#!/usr/bin/python

#	Programmer:	Daniel Pozmanter
#	E-mail:		drpython@bluebottle.com
#	Note:		You must reply to the verification e-mail to get through.
#
#	Copyright 2003-2004 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
#
#	Requirements(Dependencies):  Install Python(Version >= 2.0), and wxPython(Corresponding version).
#
#	Tested On Windows, Linux, Mac OS X
#
#	Icons taken from "Klassic New Crisp Icons" by Asif Ali Rizwaan (therizwaan) from the KDE-LOOK site (some edited a bit).
#	A humble and excellent artist.
#	Oh, the python icon is taken from wxPython.
#	The basic design of the program is meant to roughly (ROUGHLY) mimick DrScheme.
#	The purpose is the same, to provide a simple IDE(integrated development environment) ideal for teaching.
#	The DrPython icon itself was based on the DrScheme icon, with a slightly edited wxpython icon inserted(note yellow tongue, googly eyes).
#	
#	This program could not have been written without the wonderful work of the people behind
#	python and wxPython, in particular the Styled Text Control.  Thank you.  Hopefully this tool will be of use.
#
#	Replaced all rstrip('\n') with rstrip(), thanks Christof Ecker: (drpython.py and DrPrefs.py).
#
#	Version: 2.4.6


import os.path, sys, os
PLATFORM_IS_WIN = (sys.platform == "win32")
#If homedirectory does not work correctly on your platform,
#comment it out, and set the variable to your homedirectory.
#Just in case you don't check this code, and
#homedirectory does not work, drpython will plop
#its stuff in your root directory.
homedirectory = os.path.expanduser("~")
if (not os.path.exists(homedirectory)):
	if PLATFORM_IS_WIN:
		try:
			homedirectory = os.environ["APPDATA"].replace("\\", "/") + "/drpython"
		except:
			homedirectory = "c:/drpython"		
	else:
		homedirectory = "/.drpython"
else:
	if PLATFORM_IS_WIN:
		homedirectory = homedirectory.replace("\\", "/") + "/drpython"
	else:
		homedirectory = homedirectory + "/.drpython"

#Startup File.
startupfile = homedirectory + "/startup.py"
if os.path.exists(startupfile):
	try:
		f = file(startupfile, 'r')
		startupscript = f.read()
		f.close()
		exec(compile(startupscript, startupfile, 'exec'))
	except:
		print "ERROR LOADING STARTUP FILE: ", startupfile		

import sys, shutil, stat,  locale, re, string
from wxPython.wx import *
from wxPython.stc import *
from wxPython.lib.dialogs import wxScrolledMessageDialog
sys.path.insert(0, '/usr/share/drpython')
from drBoolean import *
from drText import DrText
from drPrompt import DrPrompt
from drPrinter import DrPrinter
from drFindReplaceDialog import drFindReplaceDialog, drFinder
from drSwitcherooDialog import drSwitcherooDialog
from drBookmarksMenu import drBookmarksMenu
from drDocsBookmarksMenu import drDocsBookmarksMenu
from drScriptMenu import drScriptMenu
from drShellMenu import drShellMenu
from drThemeMenu import drThemeMenu
from drLoggerMenu import drLoggerMenu
import drPrefsFile
from drPreferences import drPreferences
import drShortcutsFile
import drShortcuts
import drToolBarFile
#Moved here by drpython
import drDetectUTF_8

#*******************************************************************************************************

def getEndOfLineCharacter(character):
	if character == '\r' or character == '\n':
		return character
	return ""

#*******************************************************************************************************


class drNotebook(wxNotebook):
	def __init__(self, parent, id, position, size, flags = 0):
		wxNotebook.__init__(self, parent, id, position, size, flags)
		
		self.parent = parent
		
		self.PromptHasFocus = 0
		
		EVT_LEFT_DOWN(self, self.OnFindFocus)
		EVT_LEFT_UP(self, self.OnSelectTab)
		EVT_RIGHT_DOWN(self, self.OnPopUp)
	
	def OnFindFocus(self, event):
		self.PromptHasFocus = self.parent.txtPrompt.GetSTCFocus()
		
		event.Skip()
	
	def OnPopUp(self, event):
	
		closeallmenu = wxMenu()				
		closeallmenu.Append(self.parent.ID_CLOSE_ALL, "Close &All Tabs"," Close All Tabs")
		closeallmenu.Append(self.parent.ID_CLOSE_ALL_OTHER_TABS, "Close All &Other Tabs"," Close All Other Tabs")
		
		tabmenu = wxMenu()
		tabmenu.Append(self.parent.ID_RELOAD, "&Reload File"," Reload the current file")
		tabmenu.Append(self.parent.ID_RESTORE_FROM_BACKUP, "&Restore From Backup"," Restore from the last backup made")
		tabmenu.AppendSeparator()
		tabmenu.Append(self.parent.ID_CLOSE, "&Close", "Close the file")
		tabmenu.AppendMenu(self.parent.ID_CLOSE_MENU, "Close Tabs", closeallmenu)
		tabmenu.AppendSeparator()
		tabmenu.Append(self.parent.ID_SAVE, "&Save"," Save the file")
		tabmenu.Append(self.parent.ID_SAVE_AS, "Save &As..."," Save a file as ... another file")
		tabmenu.Append(self.parent.ID_SAVE_PROMPT, "Save Prompt Output To File..."," Saves Prompt Text in a text file")
		tabmenu.AppendSeparator()
		tabmenu.Append(self.parent.ID_PRINT,"&Print File..."," Print File")
		tabmenu.Append(self.parent.ID_PRINTPROMPT,"Print Prompt..."," Print Prompt")
		tabmenu.Enable(self.parent.ID_RELOAD, len(self.parent.filename) > 0)
		tabmenu.Enable(self.parent.ID_RESTORE_FROM_BACKUP, len(self.parent.filename) > 0)
		tabmenu.Enable(self.parent.ID_CLOSE_MENU, self.parent.prefs.mdi)
		self.PopupMenu(tabmenu, event.GetPosition())
		tabmenu.Destroy()
	
	def SetTab(self):
		selection = self.GetSelection()
		self.parent.setDocumentTo(selection)
		self.parent.txtPromptsArray[self.parent.docPosition].SetSTCFocus(self.PromptHasFocus and self.parent.txtPrompt.IsVisible)
		self.parent.txtDocumentsArray[self.parent.docPosition].SetSTCFocus(not (self.PromptHasFocus and self.parent.txtPrompt.IsVisible))
		
	
	def OnSelectTab(self, event):		
		selection = self.GetSelection()
		if selection is not self.parent.docPosition:
			self.SetTab()
		event.Skip()
				
class drPanel(wxPanel):
	def __init__(self, parent, id):
		wxPanel.__init__(self, parent, id)
				
		self.bSizer = wxBoxSizer(wxVERTICAL)	
		
		self.SetAutoLayout(True)
		self.SetSizer(self.bSizer)
		
class drObject(wxObject):
	def __init__(self):
		#wxObject.__init__(self)
		pass
				
	def VariableExists(self, varname):
		try:
			eval("self." + varname)
		except:
			return False
		return True
		
#*******************************************************************************************************

class DrFrame(wxFrame):
	def __init__(self, parent, id, app, title, fn = "", EditRecentFiles = 1, Prefs = None):

		wxFrame.__init__(self, parent, id, title, wxPoint(0, 0), wxSize(640, 480))

		self.InitializeConstants()

		self.filename = fn
		self.logfile = ""

		self.lastprogargs = ""

		self.DrScript = drObject()
		
		self.app = app
		self.app.windowlist.append(self)

		#Sets all image handlers.  DrPython uses png, jpg, gif.
		wxInitAllImageHandlers()

		if (not os.path.exists(self.bitmapdirectory)):
			d = wxScrolledMessageDialog(self, ("Bitmap Directory (" + self.bitmapdirectory + ") Does Not Exist.\nThis is either a bug with DrPython,\n an error with your installation,\nor the bitmap directory was simply removed."), "DrPython Fatal Error")
			d.ShowModal()
			d.Destroy()
			sys.exit(1)
		if (len(self.pdbstring) == 0):
			d = wxScrolledMessageDialog(self, ("Cannot Find Python Debugger.\nThis means that pdb.py was not found.\nThis means it was not in <Python Installation Directory>/lib\n or <Python Installation Directory>/lib/python<VersionNumber> n\nYou will not be able use the debugger.\n"), "DrPython Error")
			d.ShowModal()
			d.Destroy()

		self.Printer = DrPrinter(self)

		self.breakpoints = []
		
		self.findpos = 0
		self.findtext = ""
		self.findflags = 0
		self.replacetext = ""
				
		self.ClassBrowser = 0
		
		#Used for current directory with open/save
		self.ddirectory = ""
		
		#Preferences
		
		self.prefs = drPreferences(PLATFORM_IS_WIN)
				
		if Prefs is not None:
			self.prefs.Copy(Prefs)
		else:
			self.LoadPreferences()	
		
		if (self.prefs.windowwidth > -1) and (self.prefs.windowheight > -1):
			self.SetSize(wxSize(self.prefs.windowwidth, self.prefs.windowheight))
		
		if (len(self.prefs.defaultdirectory) > 0):
			self.ddirectory = self.prefs.defaultdirectory

		icon = wxEmptyIcon()
		icon.CopyFromBitmap(wxBitmapFromImage(wxImage((self.bitmapdirectory + "/drpython.png"), wxBITMAP_TYPE_PNG)))
		self.SetIcon(icon)
		
		if self.prefs.mdi:
			self.mdinotebook = drNotebook(self, -1, wxDefaultPosition, wxSize(self.prefs.windowwidth, self.prefs.windowheight), wxCLIP_CHILDREN)
				
			self.mdinotebook.AddPage(drPanel(self.mdinotebook, self.ID_APP), "Untitled")
		
			page0 = self.mdinotebook.GetPage(0)
		
			self.txtDocument = DrText(page0, self.ID_APP, self)
			self.txtPrompt = DrPrompt(page0, self.ID_APP, self)
		else:
			self.txtDocument = DrText(self, self.ID_APP, self)
			self.txtPrompt = DrPrompt(self, self.ID_APP, self)
				
		#Pop Up Menu
		
		self.popupmenulist = []
		
		self.LoadPopUpFile()
							
		self.Finder = drFinder(self)
					
		#Position in the Arrays Below:
		self.docPosition = 0
				
		#Arrays for MDI Support (Only Hold One Item if SDI):
		self.txtDocumentsArray = [self.txtDocument]
		self.txtPromptsArray = [self.txtPrompt]	
		self.filenameArray = [self.filename]
		self.FinderArray = [self.Finder]
		self.findposArray = [self.findpos]
		self.findtextArray = [self.findtext]
		self.findflagsArray = [self.findflags]
		self.replacetextArray = [self.replacetext]
		self.filenameArray = [self.filename]
		self.logfileArray = [self.logfile]
		self.lastprogargsArray = [self.lastprogargs]
		
		#file encoding array limodou 2004/04/16
		self.txtDocument.locale = self.prefs.encoding	#default encoding
		self.txtPrompt.locale = self.prefs.encoding
		#end limodou
		
		#Shortcuts
		
		self.Shortcuts = []
		self.KeycodeArray = []
		self.ShortcutsIgnoreString = ""
		
		self.ShortcutsActionArray = []
		self.ShortcutsArgumentsArray = []
		
		#DrScript Shortcuts
		
		self.DrScriptShortcuts = []
		self.DrScriptKeycodeArray = []
		
		#Shell Shortcuts
		
		self.DrShellShortcuts = []
		self.DrShellKeycodeArray = []
		
		#Load Shortcuts
		self.LoadShortcuts()
		
		#Shortcuts
		drShortcuts.SetSTCBaseShortcuts(self.txtPrompt)
		drShortcuts.SetSTCBaseShortcuts(self.txtDocument)
		self.KeycodeArray, self.ShortcutsActionArray, self.ShortcutsArgumentsArray = drShortcuts.SetShortcuts(self, self.Shortcuts)
			
		#Sizer
		self.bSizer = wxBoxSizer(wxVERTICAL)	
						
		#ToolBar
		self.hasToolBar = False
		try:
			self.ToolBarList = drToolBarFile.getToolBarList(self.homedirectory)
		except:		
			d = wxScrolledMessageDialog(self, ("Error Loading ToolBar List"), "DrPython Error")
			d.ShowModal()
			d.Destroy()
			
		if (self.prefs.iconsize > 0):		
			self.hasToolBar = True
			self.toolbar = wxToolBar(self, -1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL)
			
			self.ToolBarIdList = self.SetupToolBar()
			
			self.bSizer.Add(self.toolbar, 0, wxEXPAND)					
		
		self.sizertarget = self
		if self.prefs.mdi:
			self.bSizer.Add(self.mdinotebook, 1, wxEXPAND)
			self.sizertarget = page0
		else:
			self.windowArray = []
				
		if (self.prefs.promptsize == 100):
			self.sizertarget.bSizer.Add(self.txtDocumentsArray[self.docPosition], 1, wxEXPAND)
		else:
			self.sizertarget.bSizer.Add(self.txtDocumentsArray[self.docPosition], (100 - self.prefs.promptsize), wxEXPAND)
		if (self.prefs.promptsize == 100):
			self.sizertarget.bSizer.Add(self.txtPromptsArray[self.docPosition], 1, wxEXPAND)
		else:
			self.sizertarget.bSizer.Add(self.txtPromptsArray[self.docPosition], self.prefs.promptsize, wxEXPAND)

		if (not self.prefs.promptisvisible):
			self.sizertarget.bSizer.Show(self.txtPromptsArray[self.docPosition], False)
			self.sizertarget.bSizer.Layout()
		elif (self.prefs.promptsize == 100):
			self.sizertarget.bSizer.Show(self.txtDocumentsArray[self.docPosition], False)
			self.sizertarget.bSizer.Layout()
				
		self.SetAutoLayout(True)
		self.SetSizer(self.bSizer)			
				
		self.ID_RECENT_FILES = []
		self.recentfiles = []
		
		self.ID_RECENT_SESSIONS = []		
		self.recentsessions = []

		self.LoadRecentFiles()
		self.LoadRecentSessions()

		#edited by drpython
		if self.prefs.defaultdirectory == '':
			#add limodou 2004/04/17
			#if defaultdirectory is empty, then use the last recently file's dir
			if self.ddirectory == '' and len(self.recentfiles)>0:	
				self.ddirectory = os.path.dirname(self.recentfiles[0])
			#end limodou
	
		closeallmenu = wxMenu()				
		closeallmenu.Append(self.ID_CLOSE_ALL, "Close &All Tabs"," Close All Tabs")
		closeallmenu.Append(self.ID_CLOSE_ALL_OTHER_TABS, "Close All &Other Tabs"," Close All Other Tabs")
						
		self.recentsessionmenu = wxMenu()
		self.CreateRecentSessionMenu()
		
		self.sessionmenu = wxMenu()
		self.sessionmenu.Append(self.ID_LOAD_SESSION, "&Load Session", " Load Session")
		self.sessionmenu.Append(self.ID_SAVE_SESSION, "&Save Session", " Save Session Settings")
		self.sessionmenu.AppendMenu(self.ID_LOAD_RECENT, "Load &Recent Session", self.recentsessionmenu)	
		
		self.filemenu = wxMenu()
		self.filemenu.Append(self.ID_NEW, "&New"," Open a new window")
		self.filemenu.Append(self.ID_OPEN, "&Open..."," Open a File")
		self.recentmenu = wxMenu()
		self.CreateRecentFileMenu()
		self.filemenu.AppendMenu(self.ID_OPEN_RECENT, "Open &Recent", self.recentmenu)		
		self.filemenu.AppendMenu(self.ID_SESSION, "Session", self.sessionmenu)
		self.filemenu.Append(self.ID_RELOAD, "&Reload File"," Reload the current file")
		self.filemenu.Append(self.ID_RESTORE_FROM_BACKUP, "&Restore From Backup"," Restore from the last backup made")
		self.filemenu.AppendSeparator()
		self.filemenu.Append(self.ID_CLOSE, "&Close", "Close the file")
		self.filemenu.AppendMenu(self.ID_CLOSE_MENU, "Close Tabs", closeallmenu)
		self.filemenu.AppendSeparator()
		self.filemenu.Append(self.ID_CLEAR_RECENT, "Clear Recent File List", "Clear Recent File List")
		self.filemenu.AppendSeparator()
		self.filemenu.Append(self.ID_SAVE, "&Save"," Save the file")
		self.filemenu.Append(self.ID_SAVE_AS, "Save &As..."," Save a file as ... another file")
		self.filemenu.Append(self.ID_SAVE_PROMPT, "Save Prompt Output To File..."," Saves Prompt Text in a text file")
		self.filemenu.AppendSeparator()
		self.filemenu.Append(self.ID_PRINT_SETUP,"Print Setup..."," Print Setup")
		self.filemenu.Append(self.ID_PRINT,"&Print File..."," Print File")
		self.filemenu.Append(self.ID_PRINTPROMPT,"Print Prompt..."," Print Prompt")
		self.filemenu.AppendSeparator()
		self.filemenu.Append(self.ID_EXIT,"E&xit"," Exit DrPython")
		self.filemenu.Enable(self.ID_RELOAD, False)
		self.filemenu.Enable(self.ID_RESTORE_FROM_BACKUP, False)
		self.filemenu.Enable(self.ID_CLOSE_MENU, self.prefs.mdi)

		commentmenu = wxMenu()
		commentmenu.Append(self.ID_COMMENT_REGION, "&Comment", " Comments out the selected region.")
		commentmenu.Append(self.ID_UNCOMMENT_REGION, "U&nComment", " UnComments out the selected region.")

		cleaninmenu = wxMenu()
		cleaninmenu.Append(self.ID_CLEAN_UP_TABS, "Replace Spaces With Tabs...", "Replace All ' ' with '\t'")
		cleaninmenu.Append(self.ID_CLEAN_UP_SPACES, "Replace Tabs With Spaces...", "Replace All '\t' with ' '")

		whitespacemenu = wxMenu()		
		whitespacemenu.Append(self.ID_INDENT_REGION, "&Indent", " Indents the selected region.")
		whitespacemenu.Append(self.ID_DEDENT_REGION, "&Dedent", " Dedents the selected region.")
		whitespacemenu.AppendSeparator()
		whitespacemenu.Append(self.ID_CHECK_INDENTATION, "Check Indentation", " Checks the indentation type")
		whitespacemenu.AppendMenu(self.ID_CLEAN_UP_INDENTATION, "&Clean Up Indentation", cleaninmenu)
		whitespacemenu.AppendSeparator()
		self.formatmenu = wxMenu()
		self.formatmenu.Append(self.ID_UNIXMODE, "Unix Mode (\"\\n\")"," Set Line Endings To \"\\n\"")
		self.formatmenu.Append(self.ID_WINMODE, "DOS/Windows Mode (\"\\r\\n\")"," Set Line Endings To \"\\r\\n\"")
		self.formatmenu.Append(self.ID_MACMODE, "Mac Mode (\"\\r\")"," Set Line Endings To \"\\r\"")
		whitespacemenu.AppendMenu(self.ID_FORMATMENU, "Set Line Endings To", self.formatmenu)
				
		casemenu = wxMenu()
		casemenu.Append(self.ID_UPPERCASE, "&Uppercase", " Changes the selected region to UPPERCASE.")
		casemenu.Append(self.ID_LOWERCASE, "&Lowercase", " Changes the selected region to lowercase.")

		selectmenu = wxMenu()
		selectmenu.Append(self.ID_SELECT_ALL, "&Select All", " Selects All Text")
		selectmenu.Append(self.ID_SELECT_NONE, "Select &None", " Deselects All Text")

		self.encodingmenu = wxMenu()
		self.encodingmenu.AppendRadioItem(self.ID_ENCODING_DEFAULT, "&Default", " Default Encoding")
		self.encodingmenu.AppendRadioItem(self.ID_ENCODING_ASCII, "&ASCII", " ASCII Encoding")
		self.encodingmenu.AppendRadioItem(self.ID_ENCODING_UTF_8, "&UTF-8 (Unicode)", " UTF-8 Encoding")
		self.encodingmenu.AppendRadioItem(self.ID_ENCODING_CUSTOM, "&Custom", " Custom Encoding")

		#comment limodou 2004/04/16
		self.encodingmenu.Check(self.ID_ENCODING_DEFAULT + self.txtDocument.locale, True)
		#end limodou
		
		chopmenu = wxMenu()
		chopmenu.Append(self.ID_CHOP_BEGINNING, "&Beginning", " Chop Beginning")
		chopmenu.Append(self.ID_CHOP_END, "&End", " Chop End")
		
		editmenu = wxMenu()
		editmenu.Append(self.ID_FIND, "&Find...", " Find text")
		editmenu.Append(self.ID_FIND_NEXT, "Find &Next", " Find next occurance of text")
		editmenu.Append(self.ID_FIND_PREVIOUS, "Find Previous", " Find previous occurance of text")
		editmenu.Append(self.ID_REPLACE, "&Replace...", " Find and replace text")
		editmenu.Append(self.ID_SWITCHEROO, "&Switcheroo...", " Switch all occurences of A with B, and B with A")
		editmenu.AppendSeparator()
		editmenu.Append(self.ID_FIND_IN_FILES, "Find In Files...", " Find text in files")
		editmenu.Append(self.ID_REPLACE_IN_FILES, "Replace In Files...", " Find text and replace text in files")
		editmenu.AppendSeparator()
		editmenu.Append(self.ID_INSERT_REGEX, "&Insert Regular Expression...", " Insert Regular Expression")
		editmenu.Append(self.ID_INSERT_TRACEBACK, "Insert &Traceback", " Insert Traceback Statement")		
		editmenu.AppendSeparator()
		editmenu.Append(self.ID_FIND_AND_COMPLETE, "Find And Complete", " Find And Complete")
		editmenu.AppendSeparator()
		editmenu.AppendMenu(self.ID_COMMENT, "&Comments", commentmenu)
		editmenu.AppendMenu(self.ID_WHITESPACE, "&Whitespace", whitespacemenu)
		editmenu.AppendMenu(self.ID_CASE, "Case", casemenu)
		editmenu.AppendMenu(self.ID_CHOP, "Chop", chopmenu)
		editmenu.AppendMenu(self.ID_SELECT, "Select", selectmenu)
		editmenu.AppendSeparator()
		editmenu.AppendMenu(self.ID_ENCODING, "Encoding", self.encodingmenu)
		editmenu.AppendSeparator()
		editmenu.Append(self.ID_UNDO, "&Undo", " Undo Last Command")
		editmenu.Append(self.ID_REDO, "R&edo", " Redo Last Command")

		foldmenu = wxMenu()
		foldmenu.Append(self.ID_FOLD_ALL, "Fold All", " Fold All")
		foldmenu.Append(self.ID_EXPAND_ALL, "Expand All", " Expand All")

		self.highlightmenu = wxMenu()
		self.highlightmenu.AppendRadioItem(self.ID_HIGHLIGHT_PYTHON, "Python", " Set Syntax Highlighting to Python")
		self.highlightmenu.AppendRadioItem(self.ID_HIGHLIGHT_CPP, "C/C++", " Set Syntax Highlighting to C/C++")
		self.highlightmenu.AppendRadioItem(self.ID_HIGHLIGHT_HTML, "HTML", " Set Syntax Highlighting to HTML")
		self.highlightmenu.AppendRadioItem(self.ID_HIGHLIGHT_PLAIN_TEXT, "Plain Text", " Set Syntax Highlighting to Plain Text")
		self.highlightmenu.Check(self.ID_HIGHLIGHT_PYTHON, True)
		
		self.viewmenu = wxMenu()
		self.viewmenu.Append(self.ID_GOTO, "&Go To...", " Got To Line #")
		self.viewmenu.AppendSeparator()
		self.viewmenu.Append(self.ID_ZOOM_IN, "Zoom &In", " Zoom In")
		self.viewmenu.Append(self.ID_ZOOM_OUT, "Zoom &Out", " Zoom Out")		
		self.viewmenu.AppendSeparator()
		self.viewmenu.AppendMenu(self.ID_HIGHLIGHT, "&Syntax Highlighting", self.highlightmenu)
		self.viewmenu.AppendSeparator()
		self.viewmenu.AppendMenu(self.ID_FOLDING, "&Folding", foldmenu)
		self.viewmenu.AppendSeparator()
		self.viewmenu.Append(self.ID_SHOW_CLASSBROWSER, "Show &Class Browser...", " Show Class Browser")
		self.viewmenu.AppendSeparator()
		#fix bug someone refered in forum limodou 2004/04/20
		#self.viewmenu.Append(self.ID_TOGGLE_VIEWWHITESPACE, "&Toggle View Whitespace", " View Whitespace")
		self.viewmenu.Append(self.ID_TOGGLE_VIEWWHITESPACE, "Toggle View &Whitespace", " View Whitespace")
		#end limodou
		self.viewmenu.Append(self.ID_TOGGLE_PROMPT, "&Toggle Prompt", " View/Hide Prompt")
		self.viewmenu.Append(self.ID_CLEAR_PROMPT, "C&lear Prompt", " Clear the prompt of all text")	

		drloggermenu = drLoggerMenu(self)

		loggermenu = wxMenu()
		loggermenu.Append(self.ID_LOGGER_SET_LOG_FILE, "&Set Log File...", " Set Log File For Logger")
		loggermenu.AppendSeparator()
		loggermenu.Append(self.ID_LOGGER_ADD_LOGGER, "&Insert Logger", " Add Logger To Curent Line")
		loggermenu.Append(self.ID_LOGGER_ADD_STRING_LOGGER, "Insert String Logger", " Add Logger To Curent Line")
		loggermenu.Append(self.ID_LOGGER_ADD_ARBITRARYARGLOGGER, "Insert Arbitrary Arguments Logger", " Add Logger To Curent Line")
		loggermenu.AppendSeparator()
		loggermenu.Append(self.ID_LOGGER_REMOVE_ALL_LOGGERS, "&Remove All Loggers", " Remove All Loggers")
		loggermenu.AppendSeparator()
		loggermenu.AppendMenu(self.ID_DRLOGGER, "DrLogger", drloggermenu)
		
		self.programmenu = wxMenu()
		self.programmenu.Append(self.ID_RUN, "&Run", " Run the program")
		self.programmenu.Append(self.ID_SET_ARGS, "Set &Arguments...", " Set program arguments.")
		self.programmenu.Append(self.ID_PYTHON, "Open a Python &Interpreter", " Run the python interpreter")
		self.programmenu.Append(self.ID_PYTHON_DEBUGGER, "Run using Python Debugger (pdb)", " Run the program using Python's debugger")
		self.programmenu.Append(self.ID_END, "&End", " End Current Program")		
		self.programmenu.AppendSeparator()
		self.programmenu.AppendMenu(self.ID_LOGGER, "&Logger", loggermenu)
		self.programmenu.AppendSeparator()
		self.programmenu.Append(self.ID_ADD_BREAKPOINT, "&Add Breakpoint...", " Add a breakpoint to the current program")
		self.programmenu.Append(self.ID_REMOVE_BREAKPOINT, "Remove &Breakpoint...", " Remove a breakpoint from the current program")
		self.programmenu.Append(self.ID_REMOVE_ALL_BREAKPOINTS, "Remove &All Breakpoints...", " Remove all breakpoints from the current program")
		self.programmenu.Enable(self.ID_RUN, False)
		self.programmenu.Enable(self.ID_SET_ARGS, False)
		self.programmenu.Enable(self.ID_END, False)	
		self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, False)
		
		bookmarksmenu = drBookmarksMenu(self)
		docsbookmarksmenu = drDocsBookmarksMenu(self)
		self.drscriptmenu = drScriptMenu(self)
		self.drshellmenu = drShellMenu(self)
		
		#DrScript Shortcuts
		self.DrScriptShortcutsAction = self.drscriptmenu.OnScript
		
		#Shell Shortcuts
		self.DrShellShortcutsAction = self.drshellmenu.OnShell
		
		themesmenu = drThemeMenu(self)
		
		startupmenu = wxMenu()
		startupmenu.Append(self.ID_EDIT_STARTUP_SCRIPT, "&Edit Startup Script", " Create/Edit a Startup Script")
		startupmenu.Append(self.ID_ADD_PSYCO_TO_STARTUP_SCRIPT, "&Add Psyco to Startup Script", " Add Psyco to Startup Script")
		startupmenu.Append(self.ID_REMOVE_STARTUP_SCRIPT, "&Remove Startup Script...", " Create/Edit a Startup Script")
		
		optionsmenu = wxMenu()
		optionsmenu.Append(self.ID_PREFS, "&Preferences...", " Customize DrPython")
		optionsmenu.AppendMenu(self.ID_THEMES, "&Themes", themesmenu)
		optionsmenu.Append(self.ID_SHORTCUTS, "&Customize Shortcuts...", " Customize Keyboard Shortcuts")
		optionsmenu.Append(self.ID_POPUP, "&Customize Pop Up Menu...", " Customize Right-Click Menu")
		optionsmenu.Append(self.ID_CUSTOMIZE_TOOLBAR, "&Customize ToolBar...", " Select ToolBar Items")
		optionsmenu.AppendSeparator()
		optionsmenu.AppendMenu(self.ID_STARTUP_SCRIPT, "&Startup Script", startupmenu)
		
		infomenu = wxMenu()
		infomenu.Append(self.ID_ABOUT, "&About...", " About DrPython")
		infomenu.Append(self.ID_HELP, "&Help...", " Documentation")
		infomenu.AppendSeparator()
		infomenu.Append(self.ID_PYTHON_DOCS, "&Python Docs", " View Python Docs")
		infomenu.Append(self.ID_WXWIDGETS_DOCS, "&WxWidgets Docs", " View WxWidgets Docs")
		infomenu.Append(self.ID_REHOWTO_DOCS, "&Regular Expression Howto", " View Regular Expression Howto")
		infomenu.AppendSeparator()
		infomenu.AppendMenu(self.ID_DOCS_BOOKMARKS, "&Documentation Bookmarks", docsbookmarksmenu)
		
		self.windowmenu = wxMenu()
		self.CreateWindowMenu()
		menuBar = wxMenuBar()
		menuBar.Append(self.filemenu,"&File")
		menuBar.Append(editmenu,"&Edit")
		menuBar.Append(self.viewmenu,"&View")
		menuBar.Append(self.programmenu,"&Program")
		menuBar.Append(bookmarksmenu,"&Bookmarks")
		menuBar.Append(self.drscriptmenu,"&DrScript")
		menuBar.Append(self.drshellmenu, "&Shell")
		menuBar.Append(optionsmenu,"&Options")
		menuBar.Append(infomenu,"&Information")
		menuBar.Append(self.windowmenu, "&Window")
		self.SetMenuBar(menuBar)

		EVT_MENU(self, self.ID_NEW, self.OnNew)
		EVT_MENU(self, self.ID_OPEN, self.OnOpen)		
		
		EVT_MENU(self, self.ID_LOAD_SESSION, self.OnLoadSession)
		EVT_MENU(self, self.ID_SAVE_SESSION, self.OnSaveSession)
		
		EVT_MENU(self, self.ID_CLOSE, self.OnClose)
		EVT_MENU(self, self.ID_CLOSE_ALL, self.OnCloseAllTabs)
		EVT_MENU(self, self.ID_CLOSE_ALL_OTHER_TABS, self.OnCloseAllOtherTabs)
		
		EVT_MENU(self, self.ID_RELOAD, self.OnReload)
		EVT_MENU(self, self.ID_RESTORE_FROM_BACKUP, self.OnRestoreFromBackup)
		EVT_MENU(self, self.ID_CLEAR_RECENT, self.OnClearRecent)
		EVT_MENU(self, self.ID_SAVE, self.OnSave)
		EVT_MENU(self, self.ID_SAVE_AS, self.OnSaveAs)
		EVT_MENU(self, self.ID_SAVE_PROMPT, self.OnSavePrompt)
		EVT_MENU(self, self.ID_PRINT_SETUP, self.OnPrintSetup)
		EVT_MENU(self, self.ID_PRINT, self.OnPrint)
		EVT_MENU(self, self.ID_PRINTPROMPT, self.OnPrintPrompt)
		EVT_MENU(self, self.ID_EXIT, self.OnExit)
		
		EVT_MENU(self, self.ID_FIND, self.OnMenuFind)
		EVT_MENU(self, self.ID_FIND_NEXT, self.OnMenuFindNext)
		EVT_MENU(self, self.ID_FIND_PREVIOUS, self.OnMenuFindPrevious)
		EVT_MENU(self, self.ID_REPLACE, self.OnMenuReplace)
		EVT_MENU(self, self.ID_SWITCHEROO, self.OnMenuSwitcheroo)
		
		EVT_MENU(self, self.ID_FIND_IN_FILES, self.OnMenuFindInFiles)
		EVT_MENU(self, self.ID_REPLACE_IN_FILES, self.OnMenuReplaceInFiles)
								
		EVT_MENU(self, self.ID_INSERT_REGEX, self.OnInsertRegEx)
		EVT_MENU(self, self.ID_INSERT_TRACEBACK, self.OnInsertTraceback)
		
		EVT_MENU(self, self.ID_SELECT_ALL, self.OnSelectAll)
		EVT_MENU(self, self.ID_SELECT_NONE, self.OnSelectNone)
		
		EVT_MENU(self, self.ID_COMMENT_REGION, self.OnCommentRegion)
		EVT_MENU(self, self.ID_UNCOMMENT_REGION, self.OnUnCommentRegion)
		
		EVT_MENU(self, self.ID_INDENT_REGION, self.OnIndentRegion)
		EVT_MENU(self, self.ID_DEDENT_REGION, self.OnDedentRegion)
		EVT_MENU(self, self.ID_CHECK_INDENTATION, self.OnCheckIndentation)
		EVT_MENU(self, self.ID_CLEAN_UP_TABS, self.OnCleanUpTabs)
		EVT_MENU(self, self.ID_CLEAN_UP_SPACES, self.OnCleanUpSpaces)
		
		EVT_MENU(self, self.ID_UNIXMODE, self.OnFormatUnixMode)
		EVT_MENU(self, self.ID_WINMODE, self.OnFormatWinMode)
		EVT_MENU(self, self.ID_MACMODE, self.OnFormatMacMode)
		
		
		EVT_MENU(self, self.ID_ENCODING_DEFAULT, self.OnEncodingDefault)
		EVT_MENU(self, self.ID_ENCODING_ASCII, self.OnEncodingASCII)
		EVT_MENU(self, self.ID_ENCODING_UTF_8, self.OnEncodingUTF8)
		EVT_MENU(self, self.ID_ENCODING_CUSTOM, self.OnEncodingCustom)
		
		EVT_MENU(self, self.ID_CHOP_BEGINNING, self.OnChopBeginning)
		EVT_MENU(self, self.ID_CHOP_END, self.OnChopEnd)
		
		EVT_MENU(self, self.ID_FIND_AND_COMPLETE, self.OnFindAndComplete)		
		
		EVT_MENU(self, self.ID_UPPERCASE, self.OnUppercase)
		EVT_MENU(self, self.ID_LOWERCASE, self.OnLowercase)
		EVT_MENU(self, self.ID_UNDO, self.OnUndo)
		EVT_MENU(self, self.ID_REDO, self.OnRedo)		
		
		EVT_MENU(self, self.ID_GOTO, self.OnGoTo)
		EVT_MENU(self, self.ID_ZOOM_IN, self.OnZoomIn)
		EVT_MENU(self, self.ID_ZOOM_OUT, self.OnZoomOut)
		
		EVT_MENU(self, self.ID_HIGHLIGHT_PYTHON, self.OnSyntaxHighlightingPython)
		EVT_MENU(self, self.ID_HIGHLIGHT_CPP, self.OnSyntaxHighlightingCPP)
		EVT_MENU(self, self.ID_HIGHLIGHT_HTML, self.OnSyntaxHighlightingHTML)
		EVT_MENU(self, self.ID_HIGHLIGHT_PLAIN_TEXT, self.OnSyntaxHighlightingText)
		
		EVT_MENU(self, self.ID_FOLD_ALL, self.OnFoldAll)
		EVT_MENU(self, self.ID_EXPAND_ALL, self.OnExpandAll)
		
		EVT_MENU(self, self.ID_SHOW_CLASSBROWSER, self.OnShowClassBrowser)
		EVT_MENU(self, self.ID_TOGGLE_VIEWWHITESPACE, self.OnToggleViewWhiteSpace)		
		EVT_MENU(self, self.ID_TOGGLE_PROMPT, self.OnTogglePrompt)
		EVT_MENU(self, self.ID_CLEAR_PROMPT, self.OnClearPrompt)
		
		EVT_MENU(self, self.ID_RUN, self.OnRun)
		EVT_MENU(self, self.ID_SET_ARGS, self.OnSetArgs)
		EVT_MENU(self, self.ID_PYTHON, self.OnPython)
		EVT_MENU(self, self.ID_PYTHON_DEBUGGER, self.OnRunWithDebugger)
		EVT_MENU(self, self.ID_END, self.OnEnd)
		
		EVT_MENU(self, self.ID_LOGGER_SET_LOG_FILE, self.OnSetLogFile)
		EVT_MENU(self, self.ID_LOGGER_ADD_LOGGER, self.OnAddLogger)
		EVT_MENU(self, self.ID_LOGGER_ADD_STRING_LOGGER, self.OnAddStringLogger)
		EVT_MENU(self, self.ID_LOGGER_ADD_ARBITRARYARGLOGGER, self.OnAddArbitraryArgLogger)
		EVT_MENU(self, self.ID_LOGGER_REMOVE_ALL_LOGGERS, self.OnRemoveAllLoggers)

		EVT_MENU(self, self.ID_ADD_BREAKPOINT, self.OnAddBreakpoint)
		EVT_MENU(self, self.ID_REMOVE_BREAKPOINT, self.OnRemoveBreakpoint)
		EVT_MENU(self, self.ID_REMOVE_ALL_BREAKPOINTS, self.OnRemoveAllBreakpoints)

		EVT_MENU(self, self.ID_PREFS, self.OnPrefs)
		EVT_MENU(self, self.ID_SHORTCUTS, self.OnCustomizeShortcuts)
		EVT_MENU(self, self.ID_POPUP, self.OnCustomizePopUpMenu)
		EVT_MENU(self, self.ID_CUSTOMIZE_TOOLBAR, self.OnCustomizeToolBar)
		EVT_MENU(self, self.ID_EDIT_STARTUP_SCRIPT, self.OnEditStartupScript)
		EVT_MENU(self, self.ID_ADD_PSYCO_TO_STARTUP_SCRIPT, self.OnAddPsycoToStartupScript)
		EVT_MENU(self, self.ID_REMOVE_STARTUP_SCRIPT, self.OnRemoveStartupScript)
		
		EVT_MENU(self, self.ID_ABOUT, self.OnViewAbout)
		EVT_MENU(self, self.ID_HELP, self.OnViewHelp)
		EVT_MENU(self, self.ID_PYTHON_DOCS, self.OnViewPythonDocs)
		EVT_MENU(self, self.ID_WXWIDGETS_DOCS, self.OnViewWxWidgetsDocs)
		EVT_MENU(self, self.ID_REHOWTO_DOCS, self.OnViewREHowtoDocs)		
		
		EVT_MENU(self, self.ID_COPY, self.DoBuiltIn)		
		EVT_MENU(self, self.ID_PASTE, self.DoBuiltIn)
		EVT_MENU(self, self.ID_CUT, self.DoBuiltIn)
		EVT_MENU(self, self.ID_DELETE, self.DoBuiltIn)
		
		EVT_MENU(self, self.ID_NEXT_TAB, self.OnSelectTabMenu)
		EVT_MENU(self, self.ID_PREVIOUS_TAB, self.OnSelectTabMenu)
		EVT_MENU(self, self.ID_FIRST_TAB, self.OnSelectTabMenu)
		EVT_MENU(self, self.ID_LAST_TAB, self.OnSelectTabMenu)

		self.CreateStatusBar()

		self.GetStatusBar().SetFieldsCount(3)
		self.GetStatusBar().SetStatusWidths([-6, -3, -4])

		self.SetStatusText("Welcome to DrPython")
		if self.prefs.eolmode == 1:
			eolmodestr = "WIN"
		elif self.prefs.eolmode == 2:
			eolmodestr = "MAC"
		else:
			eolmodestr = "UNIX"
		self.SetStatusText("Line: 1, Col: 0 " + eolmodestr, 1)

		self.txtDocument.SetupPrefsDocument()

		self.txtDocument.SetFocus()
		self.txtPrompt.SetReadOnly(1)
		
		self.txtPrompt.SetupPrefsPrompt()
				
		#The following chunk of code is an ugly way to work around a bug in wxSTC.
		#As things stand, defaulting to word wrap causes some ungliness in the margin
		#on file load.  This fixes the problem, by forcing drpython to reset the wxSTC instances.
		#Fixed in 2.0.0, only do this if word wrap is in effect.
		#Fixed in 2.1.1, only do this for windows.
		if (self.prefs.docwordwrap) and PLATFORM_IS_WIN:
			self.sizertarget.bSizer.Remove(self.txtDocument)
			self.sizertarget.bSizer.Remove(self.txtPrompt)
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Add(self.txtDocument, 1, wxEXPAND)
			else:
				self.sizertarget.bSizer.Add(self.txtDocument, (100 - self.prefs.promptsize), wxEXPAND)
				self.sizertarget.bSizer.Show(self.txtDocument, True)
			if (self.prefs.promptsize == 100):
				sizertarget.bSizer.Add(self.txtPrompt, 1, wxEXPAND)
			else:
				self.sizertarget.bSizer.Add(self.txtPrompt, self.prefs.promptsize, wxEXPAND)		
			if (not self.prefs.promptisvisible):
				self.sizertarget.bSizer.Show(self.txtPrompt, False)
			elif (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Show(self.txtDocument, False)
			self.sizertarget.Layout()
		#End of the chunk.
		
		#Arguments To Program
		if (len(sys.argv) > 1) and (len(self.filename) == 0):
			self.filename = sys.argv[1]
		#Arguments to Program or DrFrame.
		if (len(self.filename) > 0):
			#Make sure the path is absolute
			self.filename = os.path.abspath(self.filename)
			#Convert Filename to correct format. (Only needed when called from the command line)
			#When called from function, already converted.
			if PLATFORM_IS_WIN:
				self.filename = self.filename.replace("\\", "/")
			self.DestroyRecentFileMenu()
			self.OpenFile(False, EditRecentFiles)
			self.CreateRecentFileMenu()
			
		EVT_END_PROCESS(self, -1, self.OnProcessEnded)	
			
		EVT_CHAR(self, self.OnChar)		
		EVT_CLOSE(self, self.OnCloseW)	
	
	def checkiffileisCPP(self, filename):
		cpp = re.compile("(\.c$)|(\.cc$)|(\.cpp$)|(\.cxx$)|(\.h$)|(\.hh$)|(\.hpp$)|(\.hxx$)", re.IGNORECASE)
		return cpp.search(filename) is not None
				
	def checkiffileisHTML(self, filename):
		cpp = re.compile("(\.htm$)|(\.html$)|(\.shtm$)|(\.shtml$)|(\.xml$)", re.IGNORECASE)
		return cpp.search(filename) is not None
		
	def checkiffileisPlainText(self, filename):
		cpp = re.compile("(\.txt$)|(\.dat$)|(\.log$)", re.IGNORECASE)
		return cpp.search(filename) is not None
	
	def checkiffileisPython(self, filename):
		cpp = re.compile("(\.py$)|(\.pyw$)", re.IGNORECASE)
		return cpp.search(filename) is not None
			
	def CheckIndentation(self):
		text = self.txtDocument.GetText()
		lines = text.split("\n")
		mixed = 0
		x = 0
		spacestarget = "\t".expandtabs(self.prefs.tabwidth)
		l = len(lines)
		tabs = 0
		spaces = 0
		while x < l:
			line = lines[x][0:self.txtDocument.GetLineIndentPosition(x)]
			foundtab = (line.find('\t') > -1)
			foundspaces = (line.find(spacestarget) > -1)
			if foundspaces and foundtab:
				mixed = 1
				x = l
			elif foundtab:
				tabs = 1
			elif foundspaces:
				spaces = 1
			x = x + 1
				
		if mixed or (tabs and spaces):
			return 0
		elif tabs:
			return 1
		elif spaces:
			return -1
		return 2
	
	def CreateLogger(self, pos, linenumber):
		LoggerText = "\
#DrPythonLoggerDefined\n\
#Please Try Not To Remove These Comments Manually\n\
def DrPythonLogger(*args):\n\
\tf = file(\"" + self.logfile + "\", 'a')\n\
\tmap(f.write, args)\n\
\tf.close()\n\
DrPythonLogger(\"DrPython Log:\", \"" + self.filename + "\\n\")\n\
#Please Try Not To Remove These Comments Manually\n\
#EndDrPythonLoggerDefined\n"
		topos = 0
		text = self.txtDocument.GetText()
		if (text.find("#!/") == 0):
			topos = text.find('\n') + 1
		self.txtDocument.InsertText(topos, LoggerText)
		pos = pos + len(LoggerText)
		linenumber = self.txtDocument.LineFromPosition(pos)
		
		return pos, linenumber
		
	def CreateRecentFileMenu(self):
		x = 0
		numfiles = len(self.recentfiles)
		while (x < numfiles):
			self.recentmenu.Append(self.ID_RECENT_FILES[x], self.recentfiles[x], ("Open " + self.recentfiles[x]))
			EVT_MENU(self, self.ID_RECENT_FILES[x], self.OnOpenRecentFile)
			x = x + 1
	
	def CreateRecentSessionMenu(self):
		x = 0
		numfiles = len(self.recentsessions)
		while (x < numfiles):
			self.recentsessionmenu.Append(self.ID_RECENT_SESSIONS[x], self.recentsessions[x], ("Open " + self.recentsessions[x]))
			EVT_MENU(self, self.ID_RECENT_SESSIONS[x], self.OnLoadRecentSession)
			x = x + 1
	
	def CreateWindowMenu(self):
		x = 0
		l = len(self.app.windowlist)
		while x < l:
			self.windowmenu.Append(self.ID_WINDOWBASE+x, self.app.windowlist[x].GetTitle(), " Select Window")
			EVT_MENU(self, self.ID_WINDOWBASE+x, self.OnSelectWindow)
			x = x + 1
	
	def DestroyDocument(self):	
		self.txtDocumentsArray.pop(self.docPosition)
		self.txtPromptsArray.pop(self.docPosition)
		self.filenameArray.pop(self.docPosition)			
		self.logfileArray.pop(self.docPosition)
		self.FinderArray.pop(self.docPosition)
		self.findposArray.pop(self.docPosition)
		self.findtextArray.pop(self.docPosition)
		self.findflagsArray.pop(self.docPosition)
		self.replacetextArray.pop(self.docPosition)
		self.lastprogargsArray.pop(self.docPosition)	
	
		#utf-8 limodou 2004/04/16
		#self.fileencodingArray.pop(self.docPosition)
		#end limodou
	
	def DestroyRecentFileMenu(self):
		#You need to call this function BEFORE you update the list of recent files.
		x = 0
		mnuitems = self.recentmenu.GetMenuItems()
		num = len(mnuitems)
		while (x < num):
			self.recentmenu.Remove(self.ID_RECENT_FILES[x])
			mnuitems[x].Destroy()
			x = x + 1
			
	def DestroyRecentSessionMenu(self):
		#You need to call this function BEFORE you update the list of recent sessions.
		x = 0
		mnuitems = self.recentsessionmenu.GetMenuItems()
		num = len(mnuitems)
		while (x < num):
			self.recentsessionmenu.Remove(self.ID_RECENT_SESSIONS[x])
			mnuitems[x].Destroy()
			x = x + 1
			
	def DestroyToolBar(self):
		x = 0
		toolbarsize = len(self.ToolBarIdList)
		while (x < toolbarsize):
			if self.ToolBarIdList[x] == -300:
				self.toolbar.DeleteToolByPos(0)
			else:
				self.toolbar.DeleteTool(self.ToolBarIdList[x])
			x = x + 1
	
	def DestroyWindowMenu(self):
		#You need to call this function BEFORE you update the window menu.
		mnuitems = self.windowmenu.GetMenuItems()
		x = len(mnuitems) - 1
		while (x > -1):
			self.windowmenu.Remove(self.ID_WINDOWBASE + x)
			mnuitems[x].Destroy()
			x = x - 1		
	
	def DoBuiltIn(self, event):		
		obj = event.GetEventObject()
		objid = event.GetId()
		try:
			#Menu?
			item = obj.GetLabel(objid)	
		except:
			#ToolBar.
			item = obj.GetToolShortHelp(objid)
			
		if item == "Copy":
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_COPY)
		elif item == "Paste":
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_PASTE)
		elif item == "Cut":
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_CUT)
		elif item == "Delete":
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_CLEAR)
	
	def dynamicdrscript(self, event):
		self.drscriptmenu.OnDynamicScript(event)
	
	#GetText function limodou 2004/04/16
	#if encoding is None, then use txtctrl.locale
	#most of the time should be encodingid when save a file
	def GetEncodedText(self, txtctrl, encodingid=0):
		if encodingid == 0:
			encodingid = txtctrl.locale
		if encodingid == 3: #custom encoding
			encoding = self.prefs.customencoding
		else:
			encoding = self.encodings[encodingid]
		if encoding == "<None>":
			encoding=self.encodings[0]
		isUnicode=txtctrl.GetCodePage()!=0
		text=txtctrl.GetText()
		try:
			if isUnicode:
				sText=text.encode(encoding)
			else:
				sText=unicode(text, self.encodings[0]).encode(encoding)
		except:
			d = wxScrolledMessageDialog(self, ("Error Encoding %s\n\nTrying other encoding...") % encoding, "DrPython Error")
			d.ShowModal()
			d.Destroy()
			sText=text

		return sText
	#end limodou
			
	def GetFileName(self):
		return self.filename
	
	def InitializeConstants(self):
		#Constant messages for file format checking.
		self.FFMESSAGE = ["Unix Mode ('\\n')", "DOS/Windows Mode ('\\r\\n')", "Mac Mode ('\\r')"]
		
		#Application ID Constants
		self.ID_APP = 101
		self.ID_NEW = 102
		self.ID_OPEN = 103
		self.ID_OPEN_RECENT = 104
		self.ID_SESSION = 901
		self.ID_LOAD_SESSION = 902
		self.ID_SAVE_SESSION = 903
		self.ID_LOAD_RECENT = 904
		self.ID_RELOAD = 105
		self.ID_RESTORE_FROM_BACKUP = 1051
		self.ID_CLOSE = 106
		self.ID_CLOSE_MENU = 6060
		self.ID_CLOSE_ALL = 6061
		self.ID_CLOSE_ALL_OTHER_TABS = 6062
		self.ID_CLEAR_RECENT = 107
		self.ID_SAVE = 108
		self.ID_SAVE_AS = 109
		self.ID_SAVE_PROMPT = 1091
		self.ID_PRINT_SETUP = 1010
		self.ID_PRINT = 1011
		self.ID_PRINTPROMPT = 1012
		self.ID_EXIT = 1014
				
		self.ID_NEXT_TAB = 801
		self.ID_PREVIOUS_TAB = 802
		self.ID_FIRST_TAB = 803
		self.ID_LAST_TAB = 804
		
		self.ID_COPY = 850		
		self.ID_PASTE = 851	
		self.ID_CUT = 852	
		self.ID_DELETE = 853
				
		self.ID_FIND = 111
		self.ID_FIND_NEXT = 112
		self.ID_FIND_PREVIOUS = 1122
		self.ID_REPLACE = 113
		self.ID_SWITCHEROO = 114
		self.ID_FIND_IN_FILES = 1110
		self.ID_REPLACE_IN_FILES = 1130
		self.ID_GOTO = 115
		self.ID_SELECT = 1150
		self.ID_SELECT_ALL = 1151
		self.ID_SELECT_NONE = 1152
		
		self.ID_INSERT_REGEX = 1153
		self.ID_INSERT_TRACEBACK = 1154
		
		self.ID_COMMENT = 1116
		self.ID_COMMENT_REGION = 116
		self.ID_UNCOMMENT_REGION = 117
		
		self.ID_WHITESPACE = 1118
		self.ID_INDENT_REGION = 118
		self.ID_DEDENT_REGION = 119
		self.ID_CHECK_INDENTATION = 1650
				
		self.ID_CLEAN_UP_INDENTATION = 167
		self.ID_CLEAN_UP_TABS = 1670
		self.ID_CLEAN_UP_SPACES = 1671
		
		self.ID_FORMATMENU = 2000
		self.ID_UNIXMODE = 2001
		self.ID_WINMODE = 2002
		self.ID_MACMODE = 2003
		
		self.ID_ENCODING = 2010
		self.ID_ENCODING_DEFAULT = 2011
		self.ID_ENCODING_ASCII = 2012
		self.ID_ENCODING_UTF_8 = 2013
		#comment limodou 2004/04/13
		self.ID_ENCODING_CUSTOM = 2014
		#end limodou
				
		self.ID_CHOP = 2050
		self.ID_CHOP_BEGINNING = 2051
		self.ID_CHOP_END = 2052
		
		self.ID_FIND_AND_COMPLETE = 2071
		
		self.ID_CASE = 1191
		self.ID_UPPERCASE = 1192
		self.ID_LOWERCASE = 1193
		
		self.ID_UNDO = 1111
		self.ID_REDO = 1112
		
		self.ID_ZOOM_IN = 161
		self.ID_ZOOM_OUT = 162
		self.ID_FOLDING = 1600
		self.ID_FOLD_ALL = 1601
		self.ID_EXPAND_ALL = 1602
		self.ID_SHOW_CLASSBROWSER = 163
		self.ID_TOGGLE_VIEWWHITESPACE = 164
		self.ID_TOGGLE_PROMPT = 165
		self.ID_CLEAR_PROMPT = 166
		
		self.ID_HIGHLIGHT = 580
		
		self.ID_HIGHLIGHT_PYTHON = 585
		self.ID_HIGHLIGHT_CPP = 586
		self.ID_HIGHLIGHT_HTML = 587
		self.ID_HIGHLIGHT_PLAIN_TEXT = 589
		
		self.ID_RUN = 121
		self.ID_SET_ARGS = 122
		self.ID_PYTHON = 123
		self.ID_PYTHON_DEBUGGER = 124
		self.ID_END = 125
		self.ID_ADD_BREAKPOINT = 126
		self.ID_REMOVE_BREAKPOINT = 127
		self.ID_REMOVE_ALL_BREAKPOINTS = 128
		self.ID_LOGGER = 129
		self.ID_LOGGER_SET_LOG_FILE = 1290
		self.ID_LOGGER_ADD_LOGGER = 1291
		self.ID_LOGGER_ADD_STRING_LOGGER = 1292
		self.ID_LOGGER_ADD_ARBITRARYARGLOGGER = 1293
		self.ID_LOGGER_REMOVE_ALL_LOGGERS = 1294
		self.ID_DRLOGGER = 1295
		
		self.ID_PREFS = 131
		self.ID_THEMES = 132
		self.ID_SHORTCUTS = 133
		self.ID_STARTUP_SCRIPT = 1700
		self.ID_EDIT_STARTUP_SCRIPT = 1701
		self.ID_ADD_PSYCO_TO_STARTUP_SCRIPT = 1702
		self.ID_REMOVE_STARTUP_SCRIPT = 1703
		self.ID_POPUP = 134
		self.ID_CUSTOMIZE_TOOLBAR = 135
		
		self.ID_ABOUT = 140
		self.ID_HELP = 141
		self.ID_PYTHON_DOCS = 142
		self.ID_WXWIDGETS_DOCS = 143
		self.ID_REHOWTO_DOCS = 144
		self.ID_DOCS_BOOKMARKS = 145
		
		self.ID_RECENT_FILES_BASE = 9930
		
		self.ID_RECENT_SESSIONS_BASE = 8330
		
		self.ID_SCRIPT_BASE = 7500
		self.ID_SHELL_BASE = 7200
		
		self.ID_WINDOWBASE = 3250
				
		#System constants
		
		#self.pdbstring = sys.prefix + "/lib/python" + sys.version[:3] + "/pdb.py "
		#This does not work on all platforms, especially if you fiddled with directory names.
		#So, I will use the messier (but more accurate) method below:
		
		if PLATFORM_IS_WIN:
			self.pdbstring = sys.prefix.replace("\\", "/") + "/lib"
			self.pythexec = sys.prefix.replace("\\", "/") + "/python.exe"
			self.pythexecw = sys.prefix.replace("\\", "/") + "/pythonw.exe"
			#File Types
			self.wildcard = "Python Source (*.pyw *.py)|*.pyw;*.py|C/C++ Source (*.c *.cc *.cpp *.cxx *.h *.hh *.hpp *.hxx)|*.c;*.cc;*.cpp;*.cxx;*.h;*.hh;*.hpp;*.hxx|HTML Files (*.htm *.html *.shtm *.shtml *.xml)|*.htm;*.html;*.shtm;*.shtml;*.xml|Backup Files (*.bak)|*.bak|Plain Text (*.txt *.dat *.log)|*.txt;*.dat;*.log|All Files (*)|*"
		else:
			self.pdbstring = sys.prefix + "/lib"
			self.pythexec = sys.executable
			#File Types
			self.wildcard = "Python Source (*.py *.pyw)|*.py;*.pyw|C/C++ Source (*.c *.cc *.cpp *.cxx *.h *.hh *.hpp *.hxx)|*.c;*.cc;*.cpp;*.cxx;*.h;*.hh;*.hpp;*.hxx|HTML Files (*.htm *.html *.shtm *.shtml *.xml)|*.htm;*.html;*.shtm;*.shtml;*.xml|Backup Files (*.bak)|*.bak|Plain Text (*.txt *.dat *.log)|*.txt;*.dat;*.log|All Files (*)|*"
		
		self.sessionwildcard = "DrPython Session File (*.dsf)|*.dsf|All Files (*)|*"
		
		if (os.path.exists(self.pdbstring + "/pdb.py")):
			self.pdbstring = self.pdbstring + "/pdb.py"
		elif (os.path.exists(self.pdbstring + "/python" + sys.version[:3] + "/pdb.py")):
			self.pdbstring = self.pdbstring + "/python" + sys.version[:3] + "/pdb.py"
		else:
			self.pdbstring = ""
		
		self.homedirectory = homedirectory
		
		#Thanks to Mark Rees.
		#Thanks to Guillermo Fernandez.
		#Thanks Bjorn Breid
		self.programdirectory = os.path.dirname(os.path.abspath(sys.argv[0])).replace("\\", "/")
		self.bitmapdirectory = "/usr/share/drpython/bitmaps"
		
		defaultlocale = locale.getdefaultlocale()[1]
		if defaultlocale is None:
			defaultlocale = "ascii"
		
		self.encodings = [defaultlocale, "ascii", "utf-8"]
		
	def isvalidbreakpoint(self, text):
		if (len(text) <= 0):
			return False
		elif (text.isspace()):
			return False
		else:
			ind = text.find('#')
			if not (ind == -1):
				if (text[:ind].isspace()):
					return False
				elif (ind == 0):
					return False
		return True		
	
	def LoadPopUpFile(self):
		#check for preferences file in user homedirectory
		if os.path.exists(self.homedirectory + "/popupmenu.dat"):
			popupfile = self.homedirectory + "/popupmenu.dat"
			try:
				f = file(popupfile, 'r')
				line = f.readline()
				while len(line) > 0:
					self.popupmenulist.append(line.rstrip())
					line = f.readline()
				f.close()
			except:
				import traceback
				print str(sys.exc_info()[0]), ":\n\n", str(sys.exc_info()[1]), "\n\n", traceback.format_tb(sys.exc_info()[2])
				d = wxScrolledMessageDialog(self, ("Error with: " + popupfile + "\nDrPython will use the program defaults."), "Pop Up Menu Error")
				d.ShowModal()
				d.Destroy()		
				
	def LoadPreferences(self, UseDefault = False):
		#check for preferences file in user homedirectory
		if (os.path.exists(self.homedirectory + "/preferences.dat")) and (not UseDefault):
			f = self.homedirectory + "/preferences.dat"
			try:
				drPrefsFile.ReadPreferences(self.prefs, f)
			except:
				d = wxScrolledMessageDialog(self, ("Error with: " + f + "\nDrPython will load the program defaults."), "Preferences Error")
				d.ShowModal()
				d.Destroy()
				self.LoadPreferences(True)
		else:
			self.prefs.reset()
				
	def LoadRecentFiles(self):
		if (not os.path.exists(self.homedirectory)):
			os.mkdir(self.homedirectory)
		f = self.homedirectory + "/recent_files.log"
		if (not os.path.exists(f)):
			try:
				t = open(f, 'w')
				t.close()
			except IOError:
				d = wxScrolledMessageDialog(self, ("Error Creating: " + f), "Recent Files Error")
				d.ShowModal()
				d.Destroy()
		try:
			fin = open(f, 'r')
			s = fin.readline()
			last = self.ID_RECENT_FILES_BASE
			x = 0
			while (len(s) > 0) and (x < self.prefs.recentfileslimit):
				s = s.rstrip()
				if (len(s) > 0):
					self.ID_RECENT_FILES.append(last)
					self.recentfiles.append(s)
				last = last + 1
				x = x + 1
				s = fin.readline()
			fin.close()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Reading: " + f), "Recent Files Error")
			d.ShowModal()
			d.Destroy()
	
	def LoadRecentSessions(self):
		if (not os.path.exists(self.homedirectory)):
			os.mkdir(self.homedirectory)
		f = self.homedirectory + "/recent_sessions.log"
		if (not os.path.exists(f)):
			try:
				t = open(f, 'w')
				t.close()
			except IOError:
				d = wxScrolledMessageDialog(self, ("Error Creating: " + f), "Recent Sessions Error")
				d.ShowModal()
				d.Destroy()
		try:
			fin = open(f, 'r')
			s = fin.readline()
			last = self.ID_RECENT_SESSIONS_BASE
			x = 0
			while (len(s) > 0) and (x < self.prefs.sessionsrecentsessionslimit):
				s = s.rstrip()
				if (len(s) > 0):
					self.ID_RECENT_SESSIONS.append(last)
					self.recentsessions.append(s)
				last = last + 1
				x = x + 1
				s = fin.readline()
			fin.close()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Reading: " + f), "Recent Sessions Error")
			d.ShowModal()
			d.Destroy()
	
	def LoadSession(self, sessionfile):
		try:	
			if self.prefs.mdi:
				self.OnCloseAllTabs(None)
			else:
				self.OnClose(None)
			f = file(sessionfile, 'r')
			text = f.read()
			f.close()
			
			filenames = drPrefsFile.ExtractPreferenceFromText(text, "Files").rstrip().split('\n')
			
			#Load the Files
			l = len(filenames)
			if l > 0:
				old = self.filename
				x = 1
				self.DestroyRecentFileMenu()
				if self.prefs.mdi and (l > 1):
					self.filename = filenames[0].replace("\\", "/")
					self.OpenFile(len(old) > 0)
				while (x < l):
					self.filename = filenames[x].replace("\\", "/")
					self.OpenFile(True)
					x = x + 1
				if not (self.prefs.mdi and (l > 1)):
					self.filename = filenames[0].replace("\\", "/")
					if (len(old) > 0) or (self.txtDocument.GetModify()):
						if self.prefs.mdi:
							self.filenameArray[self.docPosition] = old
							self.OpenFile(True)
						if not self.prefs.mdi:
							self.filename = old
					else:
							self.OpenFile(False)
				self.CreateRecentFileMenu()				
			#/Load the Files
			
			#Arguments
			self.lastprogargsArray = drPrefsFile.ExtractPreferenceFromText(text, "Arguments").split('\n')
			self.lastprogargsArray.pop()
			self.lastprogargs = self.lastprogargsArray[self.docPosition]
								
			#Code Folding State
			if self.prefs.docfolding:
				try:
				
					#First, get the modification times:
					modtimes = drPrefsFile.ExtractPreferenceFromText(text, "Files.Modification.Time").rstrip().split('\n')
					a = 0
					for window in self.app.windowlist:
						y = 0
						ll = len(window.filenameArray)
						
						while y < ll:
							linearray = drPrefsFile.ExtractPreferenceFromText(text, window.filenameArray[y]).split('\n')
							x = 0
							l = window.txtDocumentsArray[y].GetLineCount()
							
							#is the modification good?
							if modtimes[a] == str(os.stat(filenames[a])[stat.ST_MTIME]):															
								while x < l:
									if len(linearray[x]) > 0:
										vis, exp = linearray[x].split(',')
										if int(vis):
											window.txtDocumentsArray[y].ShowLines(x, x)
										else:
											window.txtDocumentsArray[y].HideLines(x, x)
										window.txtDocumentsArray[y].SetFoldExpanded(x, int(exp))
									x = x + 1
							else:
									d = wxScrolledMessageDialog(self, "The File Has Been Modified Since Last Session Save.\n\nError Loading Folding Data For: " + window.filenameArray[y], "DrPython Error")
									d.ShowModal()
									d.Destroy()							
							a = a + 1
							y = y + 1
				except:
					import sys, traceback
					slist = traceback.format_tb(sys.exc_info()[2])
					l = len(slist)
					x = 0
					rstring = ""
					while x < l:
						rstring = rstring + slist[x]
						x = x + 1
					print "Traceback (most recent call last):\n" + rstring \
					+ str(sys.exc_info()[0]).lstrip("exceptions.") + ": " + str(sys.exc_info()[1])
	
					d = wxScrolledMessageDialog(self, ("Something Went Wrong Loading the Folding State."), "DrPython Error")
					d.ShowModal()
					d.Destroy()
			if (self.recentsessions.count(sessionfile) is not 0):			
				self.ID_RECENT_SESSIONS.pop()
				self.recentsessions.remove(sessionfile)
			if (len(self.recentsessions) is self.prefs.sessionsrecentsessionslimit):
				self.recentsessions.pop()
				self.ID_RECENT_SESSIONS.pop()
			ti = len(self.ID_RECENT_SESSIONS) - 1
			if (ti > -1):
				self.ID_RECENT_SESSIONS.append(self.ID_RECENT_SESSIONS[ti] + 1)
			else:
				self.ID_RECENT_SESSIONS.append(self.ID_RECENT_SESSIONS_BASE)
			self.recentsessions.insert(0, sessionfile)
			self.WriteRecentSessions()					
		except:
			d = wxScrolledMessageDialog(self, "Error Loading Session: " + sessionfile, "DrPython Error")
			d.ShowModal()
			d.Destroy()
	
	def LoadShortcuts(self, UseDefault = False):
		#check for shortcuts file in user homedirectory
		if (os.path.exists(self.homedirectory + "/shortcuts.dat")) and (not UseDefault):
			f = self.homedirectory + "/shortcuts.dat"
			try:
				self.Shortcuts, self.KeycodeArray, self.ShortcutsIgnoreString = drShortcutsFile.ReadShortcuts(f)
			except:	
				d = wxScrolledMessageDialog(self, ("Error with: " + f + "\nDrPython will load the program defaults."), "Shortcuts Error")
				d.ShowModal()
				d.Destroy()
				self.LoadShortcuts(True)
		else:
			self.Shortcuts, self.KeycodeArray, self.ShortcutsIgnoreString = drShortcutsFile.GetDefaultShortcuts()
			
		#Load DrScript Shortcuts
		if (os.path.exists(self.homedirectory + "/drscript.shortcuts.dat")) and (not UseDefault):
			f = self.homedirectory + "/drscript.shortcuts.dat"
			try:
				self.DrScriptShortcuts, self.DrScriptKeycodeArray, t = drShortcutsFile.ReadShortcuts(f, 0)
			except:
				d = wxScrolledMessageDialog(self, ("Error with: " + f + "\nDrPython will not load DrScript shortcuts."), "DrScript Shortcuts Error")
				d.ShowModal()
				d.Destroy()
				
		#Load DrShell Shortcuts
		if (os.path.exists(self.homedirectory + "/drshell.shortcuts.dat")) and (not UseDefault):
			f = self.homedirectory + "/drshell.shortcuts.dat"
			try:
				self.DrShellShortcuts, self.DrShellKeycodeArray, t = drShortcutsFile.ReadShortcuts(f, 0)
			except:	
				d = wxScrolledMessageDialog(self, ("Error with: " + f + "\nDrPython will not load DrShell shortcuts."), "DrShell Shortcuts Error")
				d.ShowModal()
				d.Destroy()
		
	def OnAddBreakpoint(self, event):
		d = wxTextEntryDialog(self, "Line Number for the breakpoint:", "Add Breakpoint", str(self.txtDocument.GetCurrentLine() + 1))
		answer = d.ShowModal()
		d.Destroy()
		if answer == wxID_OK:		
			try:
				x = int(d.GetValue()) - 1
			except:		
				d = wxScrolledMessageDialog(self, "You must enter an integer (number, eg 1,2,128)", "DrPython")
				d.ShowModal()
				d.Destroy()	
				return
			if (x > -1) and (x < self.txtDocument.GetLineCount()):
				if (self.isvalidbreakpoint(self.txtDocument.GetLine(x))):
					if len(self.breakpoints) == 0:
						self.txtDocument.SetMarginWidth(0, 10)
					self.txtDocument.MarkerAdd(x, 0)
					self.breakpoints.append(x)
				else:
					d = wxScrolledMessageDialog(self, ("Line number: " + str(x + 1) + "\nIs either a comment, or whitespace"), "DrPython")
					d.ShowModal()
					d.Destroy()					
			else:	
				d = wxScrolledMessageDialog(self, "Line number does not exist", "DrPython")
				d.ShowModal()
				d.Destroy()	
				return	
				
	def OnAddArbitraryArgLogger(self, event):
		pos = self.txtDocument.GetCurrentPos()
		linenumber = self.txtDocument.GetCurrentLine()
		if (self.txtDocument.GetText().find("#DrPythonLoggerDefined") == -1):
			pos, linenumber = self.CreateLogger(pos, linenumber)
		self.txtDocument.InsertText(pos, ("DrPythonLogger()"))
		self.txtDocument.ScrollToLine(linenumber)
		self.txtDocument.GotoPos(pos + 15)		
	
	def OnAddLogger(self, event):
		pos = self.txtDocument.GetCurrentPos()
		linenumber = self.txtDocument.GetCurrentLine()
		if (self.txtDocument.GetText().find("#DrPythonLoggerDefined") == -1):
			pos, linenumber = self.CreateLogger(pos, linenumber)
		self.txtDocument.InsertText(pos, ("DrPythonLogger(\"" + str(linenumber + 1) + "\\n\")"))
		self.txtDocument.ScrollToLine(linenumber)
			
	def OnAddPsycoToStartupScript(self, event):
		if (not self.filename == startupfile):
			d = wxMessageDialog(self, "Your startup file is not loaded.  Would you like to load it?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_NO):
				return				
			self.OnEditStartupScript(event)
		self.txtDocument.InsertText(0, "import psyco\npsyco.full()\n")		
	
	def OnAddStringLogger(self, event):
		d = wxTextEntryDialog(self, "Enter Log String:", "Add String Logger", "")
		answer = d.ShowModal()
		if answer == wxID_OK:
			pos = self.txtDocument.GetCurrentPos()
			linenumber = self.txtDocument.GetCurrentLine()
			if (self.txtDocument.GetText().find("#DrPythonLoggerDefined") == -1):
				pos, linenumber = self.CreateLogger(pos, linenumber)
			self.txtDocument.InsertText(pos, ("DrPythonLogger(\"" + str(linenumber + 1) + "\\n\", \"" + d.GetValue() + "\")"))
			self.txtDocument.ScrollToLine(linenumber)		
		d.Destroy()	
					
	def OnChar(self, event):
		self.RunShortcuts(event)

		event.Skip()	
	
	def OnCheckIndentation(self, event):
		wxBeginBusyCursor()
		result = self.CheckIndentation()
		if result == 2:
			msg = "No indentation was found in this document."
		elif result == -1:
			msg = "This document uses spaces for indentation."
		elif result == 1:
			msg = "This document uses tabs for indentation."
		elif result == 0:
			msg = "This document is mixed.  It uses tabs and spaces for indentation."
		wxEndBusyCursor()
		d = wxScrolledMessageDialog(self, msg, "Check Indentation Results")
		d.ShowModal()
		d.Destroy()
	
	def OnChopBeginning(self, event):
		curline = self.txtDocument.GetCurrentLine()
		if curline > 1:
			self.txtDocument.SetTargetStart(self.txtDocument.GetLineEndPosition(curline - 1)+len(self.txtDocument.GetEndOfLineCharacter()))
		else:
			self.txtDocument.SetTargetStart(0)
		self.txtDocument.SetTargetEnd(self.txtDocument.GetCurrentPos())
		self.txtDocument.ReplaceTarget("")
	
	def OnChopEnd(self, event):
		if self.txtPrompt.GetSTCFocus():
			self.txtDocument = self.txtPrompt
		else:
			self.txtDocument = self.txtDocument
		curline = self.txtDocument.GetCurrentLine()
		self.txtDocument.SetTargetEnd(self.txtDocument.GetLineEndPosition(curline))
		self.txtDocument.SetTargetStart(self.txtDocument.GetCurrentPos())
		self.txtDocument.ReplaceTarget("")
		
	def OnCleanUpSpaces(self, event):
		d = wxTextEntryDialog(self, "Replace a tab with how many spaces?:", "Replace Tabs With Spaces", str(self.prefs.tabwidth))
		answer = d.ShowModal()
		value = d.GetValue()
		d.Destroy()
		eol = self.txtDocument.GetEndOfLineCharacter()
		regex = re.compile(r"\S.*")
		if answer == wxID_OK:
			wxBeginBusyCursor()
			wxYield()
			try:
				x = int(value)
			except:					
				d = wxScrolledMessageDialog(self, "You must enter an integer (number, eg 1,2,128)", "DrPython")
				d.ShowModal()
				d.Destroy()
				wxEndBusyCursor()	
				return
			if (x > -1) and (x <= 128):
				text = self.txtDocument.GetText()
				lines = text.split(eol)
				new_lines = []
				for line in lines:
					result = regex.search(line)
					if result is not None:
						end = result.start()
						new_lines.append(line[0:end].expandtabs(x) + line[end:])
					else:
						new_lines.append(line)
				newtext = string.join(new_lines, eol)
				self.txtDocument.SetText(newtext)
			else:
				d = wxScrolledMessageDialog(self, "That number seems WAY too high.  Just what are you doing, replacing  a tab with more than 128 spaces?", "DrPython Foolish Error")
				d.ShowModal()
				d.Destroy()			
				wxEndBusyCursor()	
				return
			wxEndBusyCursor()

	def OnCleanUpTabs(self, event):
		d = wxTextEntryDialog(self, "Number of spaces to replace with a tab:", "Replace Spaces With Tabs", str(self.prefs.tabwidth))
		answer = d.ShowModal()
		value = d.GetValue()
		d.Destroy()
		eol = self.txtDocument.GetEndOfLineCharacter()
		regex = re.compile(r"\S.*")
		if answer == wxID_OK:
			wxBeginBusyCursor()		
			wxYield()
			try:
				x = int(value) - 1
			except:					
				d = wxScrolledMessageDialog(self, "You must enter an integer (number, eg 1,2,128)", "DrPython")
				d.ShowModal()
				d.Destroy()				
				wxEndBusyCursor()
				return
			if (x > -1) and (x <= 128):
				#Create Target String
				y = 0
				oof = " "
				while (y < x):
					oof = oof + " "
					y = y + 1
				#Continue
				text = self.txtDocument.GetText()
				lines = text.split(eol)
				new_lines = []
				for line in lines:
					result = regex.search(line)
					if result is not None:
						end = result.start()
						new_lines.append(line[0:end].replace(oof, "\t") + line[end:])
					else:
						new_lines.append(line)
				newtext = string.join(new_lines, eol)
				self.txtDocument.SetText(newtext)
			else:	
				d = wxScrolledMessageDialog(self, "That number seems WAY too high.  Just what are you doing, replacing more than 128 spaces with a tab?", "DrPython Foolish Error")
				d.ShowModal()
				d.Destroy()				
				wxEndBusyCursor()
				return				
			wxEndBusyCursor()		

	def OnClearPrompt(self, event):
		d = wxMessageDialog(self, "This will clear all text from the prompt.\nAre you sure you want to do this?", "DrPython", wxYES_NO | wxICON_QUESTION)
		answer = d.ShowModal()
		d.Destroy()
		if (answer == wxID_YES):
			iii = self.txtPrompt.GetReadOnly()
			self.txtPrompt.SetReadOnly(0)
			self.txtPrompt.editpoint = 0
			self.txtPrompt.writeposition = 0
			self.txtPrompt.ClearAll()
			self.txtPrompt.SetReadOnly(iii)							

	def OnClearRecent(self, event):
		d = wxMessageDialog(self, "This will clear all recent files\nAre you sure you want to do this?", "DrPython", wxYES_NO | wxICON_QUESTION)
		answer = d.ShowModal()
		d.Destroy()
		if (answer == wxID_YES):
			self.recentfiles = []
			self.DestroyRecentFileMenu()
			self.WriteRecentFiles()	

	def OnClose(self, event):
		if (self.txtDocument.GetModify()):
			#prompt saving filename limodou 2004/04/19
			#d = wxMessageDialog(self, "Would you like to save first?   ", "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
			d = wxMessageDialog(self, "Would you like to save %s ?" % self.filename, "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
			#end limodou
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_YES):
				self.OnSave(event)
			elif (answer == wxID_CANCEL):
				return
		self.txtDocument.SetText("")
		self.filename = ""
		self.SetTitle("DrPython - Untitled")
		self.txtDocument.EmptyUndoBuffer()
		self.txtDocument.SetSavePoint()				
		if (self.hasToolBar):
			self.toolbar.EnableTool(self.ID_RUN, False)
			self.toolbar.EnableTool(self.ID_SET_ARGS, False)
			self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, False)
			self.toolbar.EnableTool(self.ID_RELOAD, False)
		self.programmenu.Enable(self.ID_RUN, False)
		self.programmenu.Enable(self.ID_SET_ARGS, False)
		self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, False)
		self.filemenu.Enable(self.ID_RELOAD, False)
		self.filemenu.Enable(self.ID_RESTORE_FROM_BACKUP, False)
		if self.prefs.mdi and (len(self.txtDocumentsArray) > 1):
			self.mdinotebook.DeletePage(self.docPosition)
			self.DestroyDocument()
			if (self.docPosition > 0):
				self.docPosition = self.docPosition - 1
			elif (len(self.txtDocumentsArray) > 1):
				self.docPosition = self.docPosition + 1
			self.setDocumentTo(self.docPosition, 1)
		elif self.prefs.mdi:
			self.filenameArray.pop(0)
			self.filenameArray.append("")
			#The set size stuff ensures that wxwidgets repaints the tab.
			x, y = self.GetSizeTuple()
			self.SetSize(wxSize(x-1, y-1))
			self.mdinotebook.SetPageText(0, "Untitled")
			self.SetSize(wxSize(x, y))
		if not (self.prefs.mdi and (len(self.txtDocumentsArray) > 1)) or not self.prefs.mdi:
			self.txtDocument.currentlanguage = self.prefs.docdefaultsyntaxhighlighting
			if self.txtDocument.currentlanguage == 0:
				#Python
				self.highlightmenu.Check(self.ID_HIGHLIGHT_PYTHON, True)
			elif self.txtDocument.currentlanguage == 1:
				#C/C++
				self.highlightmenu.Check(self.ID_HIGHLIGHT_CPP, True)
			elif self.txtDocument.currentlanguage == 2:
				#HTML
				self.highlightmenu.Check(self.ID_HIGHLIGHT_HTML, True)
			elif self.txtDocument.currentlanguage == 3:
				#Plain Text
				self.highlightmenu.Check(self.ID_HIGHLIGHT_PLAIN_TEXT, True)
			self.txtDocument.SetupPrefsDocument()
	
	def OnCloseAllTabs(self, event):
		if self.prefs.mdi:
			x = len(self.filenameArray) - 1
			while x > -1:
				self.setDocumentTo(x, True)
				if self.txtDocument.GetModify():
					#prompt saving filename limodou 2004/04/19
					#d = wxMessageDialog(self, "Would you like to save first?   ", "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
					d = wxMessageDialog(self, "Would you like to save %s ?" % self.filename, "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
					#end limodou
					answer = d.ShowModal()
					d.Destroy()
					if (answer == wxID_YES):
						self.OnSave(event)
				self.OnClose(event)					
				x = x - 1
	
	def OnCloseAllOtherTabs(self, event):
		if self.prefs.mdi:
			if len(self.filename) < 1:
				d = wxScrolledMessageDialog(self, "Sorry, does not work when an untitled file is selected.", "DrPython Error")
				d.ShowModal()
				d.Destroy()
				return				
			try:
				i = self.filenameArray.index(self.filename)
			except:
				d = wxScrolledMessageDialog(self, "Something went wrong trying to close file: \"" + "\".", "DrPython Error")
				d.ShowModal()
				d.Destroy()
				return				
			x = len(self.filenameArray) - 1
			while x > -1:
				if x is not i:
					self.setDocumentTo(x, True)
					if self.txtDocument.GetModify():
						#prompt saveing filename limodou 2004/04/19
						#d = wxMessageDialog(self, "Would you like to save first?   ", "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
						d = wxMessageDialog(self, "Would you like to save %s ?" % self.filename, "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
						answer = d.ShowModal()
						d.Destroy()
						if (answer == wxID_YES):
							self.OnSave(event)
					self.OnClose(event)					
				x = x - 1
			
	def OnCloseW(self, event):
		if event.CanVeto():
				try:
					map(lambda document: document.GetModify(), self.txtDocumentsArray).index(True)
					d = wxMessageDialog(self, "Would you like to save first?   ", "DrPython", wxYES_NO | wxCANCEL | wxICON_QUESTION)
					answer = d.ShowModal()
					d.Destroy()
					if (answer == wxID_YES):
						if self.prefs.mdi:
							l = self.mdinotebook.GetPageCount()
							x = 0
							while x < l:
								self.setDocumentTo(x)
								if self.txtDocument.GetModify():
									self.OnSave(event)
								x = x + 1
						else:
							self.OnSave(event)
					elif (answer == wxID_CANCEL):
						return
				except:
					if self.prefs.alwayspromptonexit:
						d = wxMessageDialog(self, "Are you sure you want to exit?   ", "DrPython", wxYES_NO | wxICON_QUESTION)
						answer = d.ShowModal()
						d.Destroy()
						if (answer == wxID_NO):
							return
							
		if len(self.app.windowlist) > 0:
			try:
				i = self.app.windowlist.index(self)
			except:
				i = 0
			self.app.windowlist.pop(i)			
		event.Skip()
		
	def OnCommentRegion(self, event):
		pos = self.txtDocument.GetCurrentPos()
		selstart, selend = self.txtDocument.GetSelection()
		#From the start of the first line selected
		startline = self.txtDocument.LineFromPosition(selstart)
		self.txtDocument.GotoLine(startline)
		start = self.txtDocument.GetCurrentPos()
		#To the end of the last line selected
		#Bugfix Chris Wilson
		end = self.txtDocument.GetLineEndPosition(self.txtDocument.LineFromPosition(selend-1))
		#End Bugfix Chris Wilson
		self.txtDocument.SetSelection(start, end)
		text = "#" + self.txtDocument.GetSelectedText()
		text = text.replace('\n', "\n#")
		self.txtDocument.ReplaceSelection(text)
		self.txtDocument.GotoPos(pos)		
	
	def OnCustomizePopUpMenu(self, event):
		from drPopUpMenuDialog import drPopUpMenuDialog
		d = drPopUpMenuDialog(self)
		if PLATFORM_IS_WIN:
			d.SetSize(wxSize(550, 400))
		d.ShowModal()
		d.Destroy()
	
	def OnCustomizeToolBar(self, event):
		from drToolBarDialog import drToolBarDialog
		d = drToolBarDialog(self)
		if PLATFORM_IS_WIN:
			d.SetSize(wxSize(550, 400))
		d.ShowModal()
		d.Destroy()		
	
	def OnCustomizeShortcuts(self, event):
		from drShortcutsDialog import drShortcutsDialog
		d = drShortcutsDialog(self, PLATFORM_IS_WIN)
		d.ShowModal()
		d.Destroy()
	
	def OnDedentRegion(self, event):
		pos = self.txtDocument.GetCurrentPos()
		selstart, selend = self.txtDocument.GetSelection()
		#From the start of the first line selected
		startline = self.txtDocument.LineFromPosition(selstart)
		self.txtDocument.GotoLine(startline)
		start = self.txtDocument.GetCurrentPos()
		#To the end of the last line selected
		#Bugfix Chris Wilson
		end = self.txtDocument.GetLineEndPosition(self.txtDocument.LineFromPosition(selend-1))
		#End Bugfix Chris Wilson
		self.txtDocument.SetSelection(start, end)
		text = self.txtDocument.GetSelectedText()
		endchar = self.txtDocument.GetEndOfLineCharacter()
		if self.prefs.docusetabs:
			tabchar = '\t'
		else:
			tabchar = "\t".expandtabs(self.prefs.tabwidth)
		if (text.find(tabchar) == 0):
			text = text[len(tabchar):]
		text = text.replace(endchar+tabchar, endchar)
		self.txtDocument.ReplaceSelection(text)
		self.txtDocument.SetSelection(start, (start + len(text)))	
	
	def OnEditStartupScript(self, event):
		if (not os.path.exists(startupfile)):
			d = wxMessageDialog(self, "You don't seem to have a startup file.  Would you like one?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_NO):
				return
			else:
				f = file(startupfile, 'w')
				f.write("")
				f.close()
	
		old = self.filename
		self.filename = startupfile
		if (len(old) > 0) or (self.txtDocument.GetModify()):
			self.OpenFile(True, False)
			if not self.prefs.mdi:
				self.filename = old
		else:
			self.OpenFile(False, False)	
	
	def OnEncodingASCII(self, event):
		self.txtDocument.locale = 1
		self.txtPrompt.locale = 1
		idnum = self.ID_ENCODING_ASCII
		self.encodingmenu.Check(idnum, True)
	
	def OnEncodingCustom(self, event):
		self.txtDocument.locale = 3
		self.txtPrompt.locale = 3
		idnum = self.ID_ENCODING_CUSTOM
		self.encodingmenu.Check(idnum, True)
	
	def OnEncodingDefault(self, event):
		self.txtDocument.locale = 0
		self.txtPrompt.locale = 0
		idnum = self.ID_ENCODING_DEFAULT
		self.encodingmenu.Check(idnum, True)
		
	def OnEncodingUTF8(self, event):
		self.txtDocument.locale = 2
		self.txtPrompt.locale = 2
		idnum = self.ID_ENCODING_UTF_8
		self.encodingmenu.Check(idnum, True)
				
	def OnEnd(self, event):
		if (self.txtPrompt.pid is not -1):
			if (len(self.filename) > 0):					
				if (self.hasToolBar):
					self.toolbar.EnableTool(self.ID_RUN, True)
					self.toolbar.EnableTool(self.ID_SET_ARGS, True)
					self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, True)	
				self.programmenu.Enable(self.ID_RUN, True)
				self.programmenu.Enable(self.ID_SET_ARGS, True)	
				self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, True)					
			if (self.hasToolBar):
				self.toolbar.EnableTool(self.ID_PYTHON, True)
				self.toolbar.EnableTool(self.ID_END, False)
			self.programmenu.Enable(self.ID_PYTHON, True)
			self.programmenu.Enable(self.ID_END, False)
			wxProcess_Kill(self.txtPrompt.pid, wxSIGKILL)
			self.txtPrompt.SetReadOnly(1)

	def OnExit(self, event):
		self.Close(False)
	
	def OnExpandAll(self, event):
		if (self.prefs.docfolding):
			wxBeginBusyCursor()
			self.txtDocument.FoldAll(True)
			wxEndBusyCursor()
	
	def OnFindAndComplete(self, event):
		#Get The Current Word
		text = self.txtDocument.GetText()
		pos = self.txtDocument.GetCurrentPos()		
		regex = re.compile("\S*\Z", re.IGNORECASE | re.MULTILINE)
		regexend = re.compile("\A\S*", re.IGNORECASE | re.MULTILINE)
		eol = self.txtDocument.GetEndOfLineCharacter()

#		#Get the left bit
		i = text[0:pos].rfind(eol)
		if i == -1:
			i = 0
		else:
			i = i + len(eol)
		
#		#Get the right bit
#		e = text[pos:].find(eol)
#		if e == -1:
#			e = len(text) - 1
#		
		result = regex.search(text[i:pos])
#		resultend = regexend.search(text[pos:e])
#				
		if result == None:
			start = i
		else:
			start = i + result.start()
#			
#		if resultend == None:
#			end = e
#		else:
#			end = e + resultend.end()
				
		oword = text[start:pos]
		word = oword.replace('\\', "\\\\").replace('^', "\\^").replace('*', "\\*").replace('$', "\\$")
		word = word.replace('+', "\\+").replace('?', "\\?").replace('{', "\\{").replace('}', "\\}")
		word = word.replace('[', "\\[").replace(']', "\\]").replace('(', "\\(").replace(')', "\\)")
		word = word.replace('.', "\\.").replace('|', "\\|")
						
		#Find all matches in the document.
		findandcompleteregex = re.compile(r"\b" + word + r"\S*\b", re.MULTILINE)
		r = findandcompleteregex.findall(text)
		r.sort()
		results = ""
		tr = []
		for item in r:
			try:
				tr.index(item)
			except:
				if not item == oword:
					results = item + " " + results
					tr.append(item)
		
		results = results.strip()
							
		if len(tr) > 0:
			try:
				self.txtDocument.AutoCompShow(len(oword), results)
			except:
				#What is this mess?
				pass
			
	def OnFoldAll(self, event):
		if (self.prefs.docfolding):
			wxBeginBusyCursor()
			self.txtDocument.FoldAll(False)
			wxEndBusyCursor()
				
	def OnFormatMacMode(self, event):
		wxBeginBusyCursor()
		wxYield()
		self.txtDocument.SetEOLMode(wxSTC_EOL_CR)
		self.txtDocument.ConvertEOLs(wxSTC_EOL_CR)
		self.txtDocument.lineendingsaremixed = 0
		self.txtDocument.OnPositionChanged(event)
		wxEndBusyCursor()
	
	def OnFormatUnixMode(self, event):
		wxBeginBusyCursor()
		wxYield()
		self.txtDocument.SetEOLMode(wxSTC_EOL_LF)
		self.txtDocument.ConvertEOLs(wxSTC_EOL_LF)
		self.txtDocument.lineendingsaremixed = 0
		self.txtDocument.OnPositionChanged(event)
		wxEndBusyCursor()
		
	def OnFormatWinMode(self, event):
		wxBeginBusyCursor()
		wxYield()
		self.txtDocument.SetEOLMode(wxSTC_EOL_CRLF)
		self.txtDocument.ConvertEOLs(wxSTC_EOL_CRLF)
		self.txtDocument.lineendingsaremixed = 0
		self.txtDocument.OnPositionChanged(event)
		wxEndBusyCursor()
	
	def OnGoTo(self, event):
		d = wxTextEntryDialog(self, "Go To Line Number:", "DrPython - Go To", "")
		answer = d.ShowModal()
		v = d.GetValue()
		d.Destroy()
		if (answer == wxID_OK):
			try:
				v = int(v) - 1
				if (v >= 0) and (v < self.txtDocument.GetLineCount()):
					self.txtDocument.ScrollToLine(v)
					self.txtDocument.GotoLine(v)
				else:
					e = wxScrolledMessageDialog(self, "That line does not exist", "DrPython Error")
					e.ShowModal()
					e.Destroy()	 
			except StandardError:
				e = wxScrolledMessageDialog(self, "You must enter an integer (1, 2, 3, etc)", "DrPython Error")
				e.ShowModal()
				e.Destroy()

	def OnIndentRegion(self, event):
		pos = self.txtDocument.GetCurrentPos()
		selstart, selend = self.txtDocument.GetSelection()
		#From the start of the first line selected
		startline = self.txtDocument.LineFromPosition(selstart)
		self.txtDocument.GotoLine(startline)
		start = self.txtDocument.GetCurrentPos()
		#To the end of the last line selected
		#Bugfix Chris Wilson
		end = self.txtDocument.GetLineEndPosition(self.txtDocument.LineFromPosition(selend-1))
		#End Bugfix Chris Wilson
		self.txtDocument.SetSelection(start, end)
		if self.prefs.docusetabs:
			tabchar = '\t'
		else:
			tabchar = "\t".expandtabs(self.prefs.tabwidth)
		text = tabchar + self.txtDocument.GetSelectedText()
		text = text.replace('\n', "\n"+tabchar)
		self.txtDocument.ReplaceSelection(text)		
		self.txtDocument.SetSelection(start, (start + len(text)))
	
	def OnInsertRegEx(self, event):
		from drRegularExpressionDialog import drRegularExpressionDialog
		d = drRegularExpressionDialog(self, -1, "Insert Regular Expression", self.txtPrompt.GetSTCFocus())
		d.Show()
		
	def OnInsertTraceback(self, event):
		eol = self.txtDocument.GetEndOfLineCharacter()
		aistring = ""
		if self.prefs.docautoindent:
			linenumber = self.txtDocument.GetCurrentLine()
			numtabs = self.txtDocument.GetLineIndentation(linenumber) / self.prefs.tabwidth
			x = 0
			while (x < numtabs):
				aistring = aistring + self.txtDocument.addchar
				x = x + 1
		insertText = "import sys, traceback" + eol + aistring \
+ "slist = traceback.format_tb(sys.exc_info()[2])" + eol + aistring \
+ "l = len(slist)" + eol + aistring \
+ "x = 0" + eol + aistring \
+ "rstring = \"\"" + eol + aistring \
+ "while x < l:" + eol + aistring \
+ self.txtDocument.addchar  + "rstring = rstring + slist[x]" + eol + aistring \
+ self.txtDocument.addchar + "x = x + 1" + eol + aistring \
+ "print \"Traceback (most recent call last):\\n\" + rstring \\" + eol + aistring \
+ "+ str(sys.exc_info()[0]).lstrip(\"exceptions.\") + \": \" + str(sys.exc_info()[1])" + eol
				
		self.txtDocument.InsertText(self.txtDocument.GetCurrentPos(), insertText)
	
	def OnLoadRecentSession(self, event):
		recentmenuindex = event.GetId() - self.ID_RECENT_SESSIONS_BASE
		filename = self.recentsessions[recentmenuindex]
		self.DestroyRecentSessionMenu()
		self.LoadSession(filename)
		self.CreateRecentSessionMenu()
	
	def OnLoadSession(self, event):	
		dlg = wxFileDialog(self, "Load Session", "", "", self.sessionwildcard, wxOPEN|wxHIDE_READONLY)
		if (len(self.ddirectory) > 0):
			try:
				if self.prefs.sessionsdefaultdirectory == "<DEFAULT>":
					d = self.ddirectory
				else:
					d = self.prefs.sessionsdefaultdirectory
				dlg.SetDirectory(d)
			except:
				d = wxScrolledMessageDialog(self, ("Error Setting Default Directory To: " + d), "DrPython Error")
				d.ShowModal()
				d.Destroy()
		if (dlg.ShowModal() == wxID_OK):
			sessionfile = dlg.GetPath().replace("\\", '/')
			self.DestroyRecentSessionMenu()
			self.LoadSession(sessionfile)
			self.WriteRecentSessions()
			self.CreateRecentSessionMenu()
		dlg.Destroy()	
		
	def OnLowercase(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			self.txtPrompt.CmdKeyExecute(wxSTC_CMD_LOWERCASE)
		else:
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_LOWERCASE)

	def OnMenuFind(self, event):
		d = drFindReplaceDialog(self, -1, "Find")
		if (self.txtDocument.GetSelectionStart() < self.txtDocument.GetSelectionEnd()):
			d.SetFindString(self.txtDocument.GetTextRange(self.txtDocument.GetSelectionStart(), self.txtDocument.GetSelectionEnd()))
		else:
			d.SetFindString(self.Finder.GetFindText())
		d.Show(True)
	
	def OnMenuFindInFiles(self, event):
		from drFindReplaceInFilesDialog import drFindReplaceInFilesDialog
		d = drFindReplaceInFilesDialog(self, -1, "Find In Files")
		d.Show(True)
	
	def OnMenuFindNext(self, event):		
		self.Finder.DoFindNext()
	
	def OnMenuFindPrevious(self, event):
		self.Finder.DoFindPrevious()
		
	def OnMenuReplace(self, event):	
		d = drFindReplaceDialog(self, -1, "Replace", 1)
		if (self.txtDocument.GetSelectionStart() < self.txtDocument.GetSelectionEnd()):
			d.SetFindString(self.txtDocument.GetTextRange(self.txtDocument.GetSelectionStart(), self.txtDocument.GetSelectionEnd()))
		else:
			d.SetFindString(self.Finder.GetFindText())
		d.Show(True)
	
	def OnMenuReplaceInFiles(self, event):
		from drFindReplaceInFilesDialog import drFindReplaceInFilesDialog
		d = drFindReplaceInFilesDialog(self, -1, "Replace In Files", True)
		d.Show(True)
	
	def OnMenuSwitcheroo(self, event):
		d = drSwitcherooDialog(self, -1, "Switcheroo")
		d.Show()
			
	def OnNew(self, event):
		if (self.prefs.mdi):
			nextpage = drPanel(self.mdinotebook, self.ID_APP)
			self.sizertarget = nextpage
			self.mdinotebook.AddPage(nextpage, "Untitled")
			l = len(self.txtDocumentsArray)
			self.txtDocumentsArray.append(DrText(nextpage, self.ID_APP, self))
			self.txtPromptsArray.append(DrPrompt(nextpage, self.ID_APP, self))
			self.filenameArray.append("")
			self.logfileArray.append("")
			#copy old finder limodou 2004/04/19
			#self.FinderArray.append(drFinder(self))
			self.FinderArray.append(drFinder(self, self.Finder))
			#end limodou
			self.findposArray.append(0)
			self.findtextArray.append("")
			self.findflagsArray.append(0)
			self.replacetextArray.append("")
			self.lastprogargsArray.append("")
			#utf-8 detect limodou 2004/04/14
			#self.fileencodingArray.append(0)
			#end limodou
			self.setDocumentTo(l)
			#utf-8 auto detecting limodou 2004/04/16
			self.txtDocument.locale = self.prefs.encoding
			self.txtPrompt.local = self.prefs.encoding
			self.encodingmenu.Check(self.ID_ENCODING_DEFAULT + self.txtDocument.locale, True)
			#end limodou
			
			#Sizer
			if (self.prefs.promptsize == 100):
				nextpage.bSizer.Add(self.txtDocumentsArray[self.docPosition], 1, wxEXPAND)
			else:
				nextpage.bSizer.Add(self.txtDocumentsArray[self.docPosition], (100 - self.prefs.promptsize), wxEXPAND)
			if (self.prefs.promptsize == 100):
				nextpage.bSizer.Add(self.txtPromptsArray[self.docPosition], 1, wxEXPAND)
			else:
				nextpage.bSizer.Add(self.txtPromptsArray[self.docPosition], self.prefs.promptsize, wxEXPAND)
	
			#What is visible
			if (not self.prefs.promptisvisible):
				nextpage.bSizer.Show(self.txtPromptsArray[self.docPosition], False)
				nextpage.bSizer.Layout()
			elif (self.prefs.promptsize == 100):
				nextpage.bSizer.Show(self.txtDocumentsArray[self.docPosition], False)
				nextpage.bSizer.Layout()
		else:
			f = DrFrame(None, -1, self.app, "DrPython - Untitled")
			f.Show(True)
			self.app.UpdateWindowMenu()
		
	def OnOpen(self, event):
		dlg = wxFileDialog(self, "Open", "", "", self.wildcard, wxOPEN|wxHIDE_READONLY|wxMULTIPLE)
		if (len(self.ddirectory) > 0):
			try:
				dlg.SetDirectory(self.ddirectory)
			except:
				d = wxScrolledMessageDialog(self, ("Error Setting Default Directory To: " + self.ddirectory), "DrPython Error")
				d.ShowModal()
				d.Destroy()
		if (dlg.ShowModal() == wxID_OK):
			alreadyopen = []
			for window in self.app.windowlist:
				alreadyopen.extend(window.filenameArray)
			old = self.filename
			filenames = dlg.GetPaths()
			l = len(filenames)
			c = 0
			while c < l:
				try:
					i = alreadyopen.index(filenames[c])
					d = wxScrolledMessageDialog(self, ('"' + filenames[c] + '" is already open.'), "Already Open")
					d.ShowModal()
					d.Destroy()
					filenames.pop(c)
					c = c - 1
					l = l - 1
				except:
					pass
				c = c + 1
			if l < 1:
				return
			x = 1
			self.DestroyRecentFileMenu()
			if self.prefs.mdi and (l > 1):
				self.filename = filenames[0].replace("\\", "/")
				self.OpenFile(len(old) > 0)
			while (x < l):
				self.filename = filenames[x].replace("\\", "/")
				self.OpenFile(True)
				x = x + 1
			if not (self.prefs.mdi and (l > 1)):
				self.filename = filenames[0].replace("\\", "/")
				if (len(old) > 0) or (self.txtDocument.GetModify()):
					if self.prefs.mdi:
						self.filenameArray[self.docPosition] = old
						self.OpenFile(True)
					if not self.prefs.mdi:
						self.OpenFile(True)
						self.filename = old
				else:
						self.OpenFile(False)
			self.CreateRecentFileMenu()
			dlg.Destroy()

	def OnOpenRecentFile(self, event):
		recentmenuindex = event.GetId() - self.ID_RECENT_FILES_BASE
		alreadyopen = []
		for window in self.app.windowlist:
			alreadyopen.extend(window.filenameArray)
		try:
			i = alreadyopen.index(self.recentfiles[recentmenuindex])
			d = wxScrolledMessageDialog(self, ('"' + self.recentfiles[recentmenuindex] + '" is already open.'), "Already Open")
			d.ShowModal()
			d.Destroy()
			return
		except:
			pass
		if not os.path.exists(self.recentfiles[recentmenuindex]):
			d = wxScrolledMessageDialog(self, ('"' + self.recentfiles[recentmenuindex] + '" Does Not Exist.'), "Recent File No Longer Exists")
			d.ShowModal()
			d.Destroy()
			return
		old = self.filename
		self.filename = self.recentfiles[recentmenuindex]
		self.DestroyRecentFileMenu()
		if (len(old) > 0) or (self.txtDocument.GetModify()):
			if self.prefs.mdi:
				self.filenameArray[self.docPosition] = old
				self.OpenFile(True)
			if not self.prefs.mdi:
				self.OpenFile(True)
				self.filename = old
		else:
				self.OpenFile(False)
		self.CreateRecentFileMenu()
		
	def OnPrefs(self, event):
		from drPrefsDialog import drPrefsDialog
		d = drPrefsDialog(self, -1, "DrPython - Preferences")
		d.ShowModal()		
		d.Destroy()
	
	def OnPrint(self, event):
		self.Printer.Print(self.txtDocument.GetText(), self.filename, self.prefs.printdoclinenumbers)

	def OnPrintSetup(self, event):
		self.Printer.PrinterSetup()
				
	def OnPrintPrompt(self, event):
		self.Printer.Print(self.txtPrompt.GetText(), self.filename, self.prefs.printpromptlinenumbers)
	
	def OnProcessEnded(self, event):
		#First, check for any leftover output.
		self.txtPrompt.OnIdle(event)
		
		#Set the process info to the correct position in the array.
		i = 0
		if self.prefs.mdi:
			epid = event.GetPid()
			try:
				i = map(lambda tprompt: tprompt.pid == epid, self.txtPromptsArray).index(True)
			except:
				return				
		#If this is the process for the current window:
		if self.docPosition == i or not self.prefs.mdi:
			self.txtPrompt.process.Destroy()
			self.txtPrompt.process = None
			self.txtPrompt.pid = -1
			self.txtPrompt.SetReadOnly(1)
			self.txtPrompt.pythonintepreter = 0
			if (len(self.filename) > 0):
				if (self.hasToolBar):
					self.toolbar.EnableTool(self.ID_RUN, True)
					self.toolbar.EnableTool(self.ID_SET_ARGS, True)
					self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, True)
				self.programmenu.Enable(self.ID_RUN, True)
				self.programmenu.Enable(self.ID_SET_ARGS, True)	
				self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, True)
			self.SetStatusText("", 2)			
			if (self.hasToolBar):
				self.toolbar.EnableTool(self.ID_PYTHON, True)
				self.toolbar.EnableTool(self.ID_END, False)
			self.programmenu.Enable(self.ID_PYTHON, True)
			self.programmenu.Enable(self.ID_END, False)
		else:	
			self.txtPromptsArray[i].process.Destroy()
			self.txtPromptsArray[i].process = None
			self.txtPromptsArray[i].pid = -1
			self.txtPromptsArray[i].SetReadOnly(1)
			self.txtPromptsArray[i].pythonintepreter = 0
			
		if self.prefs.autogotofortraceback:
			#Find Last Traceback
			text = self.txtPrompt.GetText()
			f = text.find("Traceback (most recent call last):")
			e = f + 1
			targetchar = ','
			while f is not -1:
				f = text[e:].find("Traceback (most recent call last):")
				if f is not -1:
					f = e + f
					e = f + 1			
			f = e
			#Try Looking for a Syntax Error
			f = text.find("SyntaxError:")
			e = f + 1
			if f is -1:
				return
			else:
				#Syntax Errors Appear before the text "SyntaxError"
				f = 0
				targetchar = self.txtPrompt.GetEndOfLineCharacter()
			
			#Find File
			e = f
			f = text[f:].find("File") + 6
			e = e + f
			while f is not -1:
				f = text[e:].find("File")
				if f is not -1:
					f = e + f
					e = f + 6
			
			fend = e + text[e:].find('"')
			fname = text[e:fend]
			
			sdi_new = False
			
			if len(fname) < 1:
				return
			if not os.path.exists(fname):
				return
			if not fname == self.filename:
				#Quit if not current file
				if self.prefs.mdi:
					try:
						i = self.filenameArray.index(fname)
						self.setDocumentTo(i)
					except:
						self.filename = fname
						self.OpenFile(True)
				else:	
					frame = DrFrame(None, -1, self.app, "DrPython")
					frame.Show(True)
					frame.filename = fname
					frame.OpenFile(False)
					sdi_new = True					
				
			#Find Line Number
			e = fend
			f = e
			while f is not -1:
				f = text[e:].find("line")
				if f is not -1:
					f = e + f
					e = f + 1
			f = e
			#Go To Line Number
			if f is not -1:
				f = f + 3
				fend = f + text[f:].find(targetchar)
				linenumber = text[f:fend]
				try:
					ln = int(linenumber)
					if sdi_new:
						frame.txtDocument.ScrollToLine(ln-1)
						frame.txtDocument.GotoLine(ln-1)
						frame.txtDocument.EnsureCaretVisible()
					else:
						self.txtDocument.ScrollToLine(ln-1)
						self.txtDocument.GotoLine(ln-1)
						self.txtDocument.EnsureCaretVisible()
				except:
					pass	
		
	def OnPython(self, event):
		if (self.txtPrompt.pid is -1):
			self.txtPrompt.pythonintepreter = 1
			if (self.hasToolBar):
				self.toolbar.EnableTool(self.ID_RUN, False)
				self.toolbar.EnableTool(self.ID_SET_ARGS, False)
				self.toolbar.EnableTool(self.ID_PYTHON, False)
				self.toolbar.EnableTool(self.ID_END, True)
				self.toolbar.ToggleTool(self.ID_TOGGLE_PROMPT,  True)
				self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, False)	
			self.programmenu.Enable(self.ID_RUN, False)
			self.programmenu.Enable(self.ID_SET_ARGS, False)
			self.programmenu.Enable(self.ID_PYTHON, False)
			self.programmenu.Enable(self.ID_END, True)
			self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, False)
			if (not self.txtPrompt.IsVisible):
				self.txtPrompt.IsVisible = True				
				if (self.prefs.promptsize == 100):
					self.sizertarget.bSizer.Show(self.txtDocument, False)
				self.sizertarget.bSizer.Show(self.txtPrompt, True)
				self.sizertarget.bSizer.Layout()
			self.txtPrompt.SetReadOnly(0)
			self.txtPrompt.ClearAll()
			self.txtPrompt.SetScrollWidth(1)
			self.txtPrompt.editpoint = 0
			if (len(self.filename) > 0):
				try:
					cdir = self.filename[0:self.filename.rindex('/')]
					os.chdir(cdir)
				except:			
					d = wxScrolledMessageDialog(self, "Error Setting current directory for Python.", "DrPython RunError")
					d.ShowModal()
					d.Destroy()		
			self.SetStatusText("Running Python Interpreter", 2)
			self.txtPrompt.process = wxProcess(self)
			self.txtPrompt.process.Redirect()
			self.txtPrompt.pid = wxExecute((self.pythexec + " -i " + self.prefs.pythonargs), wxEXEC_ASYNC, self.txtPrompt.process)			
			self.txtPrompt.inputstream = self.txtPrompt.process.GetInputStream()		
			self.txtPrompt.errorstream = self.txtPrompt.process.GetErrorStream()
			self.txtPrompt.outputstream = self.txtPrompt.process.GetOutputStream()
			self.txtPrompt.SetFocus()

	def OnRedo(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			self.txtPrompt.Redo()
		else:
			self.txtDocument.Redo()

	def OnReload(self, event):
		d = wxMessageDialog(self, "This will reload the current file.\nAny changes will be lost.\nAre you sure you want to do this?", "DrPython", wxYES_NO | wxICON_QUESTION)
		answer = d.ShowModal()
		d.Destroy()
		if (answer == wxID_YES):
			if (len(self.filename) > 0):
				self.OpenFile(False)
		event.Skip()
				
	def OnRemoveAllBreakpoints(self, event):
		l = len(self.breakpoints)
		if (l > 0):
			d = wxMessageDialog(self, "This will remove all breakpoints\nAre you sure you want to do this?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_YES):
				l = self.txtDocument.GetLineCount()
				x = 0
				while (x < l):
					i = self.breakpoints.count(x)
					if (i > 0):
						i = self.breakpoints.index(x)
						self.breakpoints.pop(i)
					self.txtDocument.MarkerDelete(x, 0)
					x = x + 1	
				self.txtDocument.SetMarginWidth(0, 0)					
	
	def OnRemoveAllLoggers(self, event):
		d = wxMessageDialog(self, "This will remove all loggers from this file.\nAre you sure you want to do this?", "Remove All Loggers", wxYES_NO | wxICON_QUESTION)
		answer = d.ShowModal()
		d.Destroy()
		if (answer == wxID_YES):
			text = self.txtDocument.GetText()
			start = text.find("#DrPythonLoggerDefined")			
			end = text.find("#EndDrPythonLoggerDefined") + 25
			if (start == -1) or (end == -1):	
				d = wxScrolledMessageDialog(self, "No Loggers Found, or Logger Function is Corrupt.", "DrPython")
				d.ShowModal()
				d.Destroy()
				return
			self.txtDocument.SetTargetStart(start)
			self.txtDocument.SetTargetEnd(end)
			self.txtDocument.ReplaceTarget("")
			start = self.txtDocument.GetText().find("DrPythonLogger")
			x = 0
			while (start > -1):
				end = self.txtDocument.GetLineEndPosition(self.txtDocument.LineFromPosition(start))
				self.txtDocument.SetTargetStart(start)
				self.txtDocument.SetTargetEnd(end)
				self.txtDocument.ReplaceTarget("")
				start = self.txtDocument.GetText().find("DrPythonLogger")
				x = x + 1
			d = wxScrolledMessageDialog(self, "Removed " + str(x) + " Loggers", "Removed All Loggers")
			d.ShowModal()
			d.Destroy()
			
	
	def OnRemoveBreakpoint(self, event):
		l = len(self.breakpoints)
		if (l > 0):
			d = wxTextEntryDialog(self, "Line Number for the breakpoint:", "Add Breakpoint", str(self.txtDocument.GetCurrentLine() + 1))
			answer = d.ShowModal()
			d.Destroy()
			if answer == wxID_OK:
				try:
					x = int(d.GetValue()) - 1
				except:					
					d = wxScrolledMessageDialog(self, "You must enter an integer (number, eg 1,2,128)", "DrPython")
					d.ShowModal()
					d.Destroy()	
					return
				try:
					i = self.breakpoints.index(x)
				except:			
					d = wxScrolledMessageDialog(self, "Breakpoint(" + str(x + 1) + ") does not exist", "DrPython")
					d.ShowModal()
					d.Destroy()	
					return
				self.breakpoints.pop(i)
				self.txtDocument.MarkerDelete(x, 0)				
				if len(self.breakpoints) == 0:
					self.txtDocument.SetMarginWidth(0, 0)
					
	def OnRemoveStartupScript(self, event):
		if (not os.path.exists(startupfile)):
			d = wxScrolledMessageDialog(self, "You don't seem to have a startup file...\nDrPython will therefore NOT remove it.", "No Startup File to Remove")
			d.ShowModal()
			d.Destroy()
			return
		d = wxMessageDialog(self, "Are you sure you want to remove your startup file?\nOnce it is gone, IT IS GONE!", "DrPython", wxYES_NO | wxICON_QUESTION)
		answer = d.ShowModal()
		d.Destroy()		
		if (answer == wxID_NO):
			return
		try:
			os.remove(startupfile)
			try:
				if self.prefs.mdi:
					i = self.filenameArray.index(startupfile)
					self.setDocumentTo(i)
					self.OnClose(event)
				else:
					if self.filename == startupfile:
						self.OnClose(event)
			except:
				pass				
		except:
			d = wxScrolledMessageDialog(self, ("Error Removing startup file: \"" + startupfile + "\""), "DrPython Error")
			d.ShowModal()
			d.Destroy()		
	
	def OnRestoreFromBackup(self, event):
		if os.path.exists(self.filename + ".bak"):
			d = wxMessageDialog(self, "This will restore the current file from the last backup.\nAny changes will be lost.\nAre you sure you want to do this?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_YES):
				if (len(self.filename) > 0):
					old = self.filename
					self.filename = self.filename + ".bak"
					self.OpenFile(False, False, False)
					self.filename = old
		else:
			d = wxScrolledMessageDialog(self, ("No Backup File For: \"" + self.filename + "\""), "DrPython Error")
			d.ShowModal()
			d.Destroy()		
		
	def OnRun(self, event):
		if (self.txtDocument.GetModify()):
			d = wxMessageDialog(self, "The file has been modified.\nIt would be wise to save before running.\nWould you like to save the file?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_YES):
				self.OnSave(event)
		largs = ""
		if (len(self.lastprogargs) > 0):
			largs = "\" " + self.lastprogargs
		if PLATFORM_IS_WIN:
			self.runcommand((self.pythexecw + " -u " +  self.prefs.pythonargs + " \"" + self.filename.replace("\\", "/") + largs), event)
		else:
			self.runcommand((self.pythexec + " -u " +  self.prefs.pythonargs + " \"" + self.filename + largs), event)
		
	def OnRunWithDebugger(self, event):
		if (self.txtDocument.GetModify()):
			d = wxMessageDialog(self, "The file has been modified.\nIt would be wise to save before running.\nWould you like to save the file?", "DrPython", wxYES_NO | wxICON_QUESTION)
			answer = d.ShowModal()
			d.Destroy()
			if (answer == wxID_YES):
				self.OnSave(event)
		largs = ""
		if (len(self.lastprogargs) > 0):
			largs = "\" " + self.lastprogargs
		if PLATFORM_IS_WIN:
			self.runcommand((self.pythexecw + " -u " +  self.prefs.pythonargs + " \"" + self.pdbstring + "\" \"" + self.filename.replace("\\", "/") + largs), event)
		else:
			self.runcommand((self.pythexec + " -u " +  self.prefs.pythonargs + " \"" + self.pdbstring + "\" \""  + self.filename + largs), event)
		l = len(self.breakpoints)
		if (l > 0):
			x = 0
			while (x < l):
				self.txtPrompt.process.GetOutputStream().write("break " + str(self.breakpoints[x] + 1) + '\n')
				x = x + 1
				
	def OnSave(self, event):
		if (len(self.filename) <= 0):
			self.OnSaveAs(event)
		else:
			self.SaveFile(False)

	def OnSaveAs(self, event):
		dlg = wxFileDialog(self, "Save File As", "", "", self.wildcard, wxSAVE|wxOVERWRITE_PROMPT)
		if (len(self.ddirectory) > 0):
			try:
				dlg.SetDirectory(self.ddirectory)			
			except:
				d = wxScrolledMessageDialog(self, ("Error Setting Default Directory To: " + self.lastdirectory), "DrPython Error")
				d.ShowModal()
				d.Destroy()	
		if (dlg.ShowModal() == wxID_OK):
			old = self.filename
			self.filename = dlg.GetPath().replace("\\", "/")
			self.ddirectory = os.path.dirname(self.filename)
			self.DestroyRecentFileMenu()
			self.SaveFile(not (old == self.filename))	
			self.toolbar.EnableTool(self.ID_RUN, True)
			self.toolbar.EnableTool(self.ID_SET_ARGS, True)			
			self.programmenu.Enable(self.ID_RUN, True)
			self.programmenu.Enable(self.ID_SET_ARGS, True)
			
			#Highlighting
			if not self.prefs.doconlyusedefaultsyntaxhighlighting:
				if self.checkiffileisPython(self.filename):
					#Python
					self.txtDocument.currentlanguage = 0
					self.highlightmenu.Check(self.ID_HIGHLIGHT_PYTHON, True)
				elif self.checkiffileisCPP(self.filename):
					#C/C++
					self.txtDocument.currentlanguage = 1
					self.highlightmenu.Check(self.ID_HIGHLIGHT_CPP, True)
				elif self.checkiffileisHTML(self.filename):
					#HTML
					self.txtDocument.currentlanguage = 2			
					self.highlightmenu.Check(self.ID_HIGHLIGHT_HTML, True)	
				elif self.checkiffileisPlainText(self.filename):
					#Plain Text
					self.txtDocument.currentlanguage = 3
					self.highlightmenu.Check(self.ID_HIGHLIGHT_PLAIN_TEXT, True)
				else:
					#Default
					pass
				self.txtDocument.SetupPrefsDocument()	
			
			#Update Recent Files
			if (self.recentfiles.count(self.filename) is not 0):
				self.ID_RECENT_FILES.pop(self.recentfiles.index(self.filename))
				self.recentfiles.remove(self.filename)
			if (len(self.recentfiles) is self.prefs.recentfileslimit):
				self.recentfiles.pop()
				self.ID_RECENT_FILES.pop()
			ti = len(self.ID_RECENT_FILES) - 1
			if (ti > -1):
				self.ID_RECENT_FILES.append(self.ID_RECENT_FILES[ti] + 1)
			else:
				self.ID_RECENT_FILES.append(self.ID_RECENT_FILES_BASE)
			self.recentfiles.insert(0, self.filename)
			self.WriteRecentFiles()
			self.CreateRecentFileMenu()
			dlg.Destroy()

	def OnSavePrompt(self, event):
		dlg = wxFileDialog(self, "Save Prompt Text To", "", "", "Text File (*.txt)|*.txt|All files (*)|*", wxSAVE|wxOVERWRITE_PROMPT)
		if (len(self.ddirectory) > 0):
			try:
				dlg.SetDirectory(self.ddirectory)			
			except:
				d = wxScrolledMessageDialog(self, ("Error Setting Default Directory To: " + self.lastdirectory), "DrPython Error")
				d.ShowModal()
				d.Destroy()	
		if (dlg.ShowModal() == wxID_OK):	
			pfilename = dlg.GetPath().replace("\\", "/")
			self.ddirectory = os.path.dirname(pfilename)
			try:
				cfile = file(pfilename, 'wb')
				#comment limodou 2004/04/13
				#cfile.write(self.txtPrompt.GetText())
				#change 
				cfile.write(self.GetEncodedText(self.txtPrompt))
				#end limodou
				cfile.close()
			except IOError:
				d = wxScrolledMessageDialog(self, ("Error Writing: " + pfilename), "DrPython Error")
				d.ShowModal()
				d.Destroy()   		
			dlg.Destroy()

	def OnSaveSession(self, event):
		dlg = wxFileDialog(self, "Save Session As", "", "", self.sessionwildcard, wxSAVE|wxOVERWRITE_PROMPT)
		if (len(self.ddirectory) > 0):
			try:
				if self.prefs.sessionsdefaultdirectory == "<DEFAULT>":
					d = self.ddirectory
				else:
					d = self.prefs.sessionsdefaultdirectory
				dlg.SetDirectory(d)			
			except:
				d = wxScrolledMessageDialog(self, ("Error Setting Default Directory To: " + d), "DrPython Error")
				d.ShowModal()
				d.Destroy()	
		if (dlg.ShowModal() == wxID_OK):
			sessionfilename = dlg.GetPath().replace("\\", "/")
			try:
				f = file(sessionfilename, 'w')
				#Files
				f.write("<Files>")
				x = 0
				l = len(self.app.windowlist)
				for window in self.app.windowlist:
					for filename in window.filenameArray:
						f.write(filename + '\n')
				f.write("</Files>\n")
				
				#Arguments
				f.write("<Arguments>")
				for window in self.app.windowlist:
					for progarg in window.lastprogargsArray:
						f.write(progarg + '\n')
				f.write("</Arguments>\n")		
								
				#Code Folding State
				if self.prefs.docfolding:
					#First, store the modification times:
					f.write("<Files.Modification.Time>")
					x = 0
					l = len(self.app.windowlist)
					for window in self.app.windowlist:
						for filename in window.filenameArray:
							f.write(str(os.stat(filename)[stat.ST_MTIME]) + '\n')
					f.write("</Files.Modification.Time>\n")
					
					f.write("<Folding.State>")
					for window in self.app.windowlist:
						y = 0
						ll = len(window.filenameArray)
						while y < ll:
							f.write("<" + window.filenameArray[y] + ">")
							x = 0
							l = window.txtDocumentsArray[y].GetLineCount()
							while x < l:
								f.write(str(window.txtDocumentsArray[y].GetLineVisible(x)))
								f.write(",")
								f.write(str(window.txtDocumentsArray[y].GetFoldExpanded(x)))
								f.write("\n")
								x = x + 1								
							f.write("</" + window.filenameArray[y] + ">\n")
							y = y + 1
					f.write("</Folding.State>")
				
				f.close()
				self.DestroyRecentSessionMenu()
				self.WriteRecentSessions()
				self.CreateRecentSessionMenu()
			except:
				d = wxScrolledMessageDialog(self, ("Error Writing To: " + sessionfilename), "DrPython Error")
				d.ShowModal()
				d.Destroy()
			dlg.Destroy()

	def OnSelectAll(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			self.txtPrompt.SelectAll()
		else:
			self.txtDocument.SelectAll()
			
	def OnSelectNone(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			pos = self.txtPrompt.GetCurrentPos()
			self.txtPrompt.SetSelection(pos, pos)
		else:
			pos = self.txtDocument.GetCurrentPos()
			self.txtDocument.SetSelection(pos, pos)

	def OnSelectTab(self, direction):
		if self.prefs.mdi:
			if direction == -2:
				return
			elif direction == 1:
				self.mdinotebook.AdvanceSelection(True)
			elif direction == -1:
				self.mdinotebook.AdvanceSelection(False)
			elif direction == 2:
				self.mdinotebook.SetSelection(self.mdinotebook.GetPageCount()-1)
			else:
				self.mdinotebook.SetSelection(0)
			self.mdinotebook.SetTab()
		
	def OnSelectTabMenu(self, event):
		obj = event.GetEventObject()
		objid = event.GetId()
		try:
			#Menu?
			item = obj.GetLabel(objid)	
		except:
			#ToolBar.
			item = obj.GetToolShortHelp(objid)
			
		if item == "Next Tab":
			self.OnSelectTab(1)
		elif item == "Previous Tab":
			self.OnSelectTab(-1)
		elif item == "First Tab":
			self.OnSelectTab(0)
		elif item == "Last Tab":
			self.OnSelectTab(2)

	def OnSelectWindow(self, event):
		i = event.GetId() - self.ID_WINDOWBASE
		#Do Nothing if use selects current window.
		if self.app.windowlist[i] == self:
			return
		if self.app.windowlist[i].IsIconized():
			print "Hey"
			self.app.windowlist[i].Show(True)
			self.app.windowlist[i].Iconize(False)
		self.app.windowlist[i].Raise()
		self.app.windowlist[i].SetFocus()
		self.app.windowlist[i].txtDocument.SetFocus()

	def OnSetArgs(self, event):
		if (len(self.filename) > 0):
			d = wxTextEntryDialog(self, "Arguments:", "DrPython - Set Arguments", self.lastprogargs)
			if (d.ShowModal() == wxID_OK):
				self.lastprogargs = d.GetValue()
				self.lastprogargsArray[self.docPosition] = self.lastprogargs
		d.Destroy()
	
	def OnSetLogFile(self, event):
		d = wxTextEntryDialog(self, "Log File:", "Logger - Set Log File", self.logfile)
		if (d.ShowModal() == wxID_OK):
			self.logfile = d.GetValue()
		d.Destroy()	
	
	def OnShowClassBrowser(self, event):
#		if self.CheckIndentation() == 0:
#			d = wxScrolledMessageDialog(self, ("This file has mixed indentation.\nThe class browser may not display definitions and classes in the correct hierarchy."), "Class Browser Warning")
#			d.ShowModal()
#			d.Destroy()			
		from drClassBrowser import drClassBrowser
		if not (self.ClassBrowser):
			self.ClassBrowser = drClassBrowser(self, self.filename)
			self.ClassBrowser.Show()			
		else:
			self.ClassBrowser.Raise()			

	def OnSyntaxHighlightingPython(self, event):
		self.txtDocument.currentlanguage = 0
		self.txtDocument.SetupPrefsDocument()
		
	def OnSyntaxHighlightingCPP(self, event):
		self.txtDocument.currentlanguage = 1
		self.txtDocument.SetupPrefsDocument()
		
	def OnSyntaxHighlightingHTML(self, event):
		self.txtDocument.currentlanguage = 2
		self.txtDocument.SetupPrefsDocument()

	def OnSyntaxHighlightingText(self, event):
		self.txtDocument.currentlanguage = 3
		self.txtDocument.SetupPrefsDocument()					
						
	def OnTogglePrompt(self, event):
		if (self.txtPrompt.IsVisible):
			self.txtPrompt.IsVisible = False
			if self.hasToolBar:
				self.toolbar.ToggleTool(self.ID_TOGGLE_PROMPT,  False)			
			self.sizertarget.bSizer.Show(self.txtPrompt, False)
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Show(self.txtDocument, True)
			self.sizertarget.bSizer.Layout()
			self.txtDocument.SetFocus()
		else:
			self.txtPrompt.IsVisible = True
			if self.hasToolBar:
				self.toolbar.ToggleTool(self.ID_TOGGLE_PROMPT,  True)
			self.sizertarget.bSizer.Show(self.txtPrompt, True)
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Show(self.txtDocument, False)
			self.sizertarget.bSizer.Layout()
			self.txtPrompt.SetFocus()

	def OnToggleViewWhiteSpace(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			c = self.txtPrompt.GetViewWhiteSpace()
			if (c):
				self.txtPrompt.SetViewWhiteSpace(False)
			else:
				self.txtPrompt.SetViewWhiteSpace(True)
		else:
			c = self.txtDocument.GetViewWhiteSpace()
			if (c):
				self.txtDocument.SetViewWhiteSpace(False)
			else:
				self.txtDocument.SetViewWhiteSpace(True)
				
	def OnUnCommentRegion(self, event):	
		pos = self.txtDocument.GetCurrentPos()
		selstart, selend = self.txtDocument.GetSelection()
		#From the start of the first line selected
		startline = self.txtDocument.LineFromPosition(selstart)
		self.txtDocument.GotoLine(startline)
		start = self.txtDocument.GetCurrentPos()
		#To the end of the last line selected
		#Bugfix Chris Wilson
		end = self.txtDocument.GetLineEndPosition(self.txtDocument.LineFromPosition(selend-1))
		#End Bugfix Chris Wilson
		self.txtDocument.SetSelection(start, end)
		text = self.txtDocument.GetSelectedText()
		
		x = 1
		l = len(text)
		newtext = ""
		if not (text[0] == '#'):
			newtext = text[0]
		while (x < l):
			if (text[x] == '#'):
				prestyle = self.txtDocument.GetStyleAt(start + (x - 1))
				style = self.txtDocument.GetStyleAt(start + x)
				if not ((not (prestyle == wxSTC_P_COMMENTLINE) and not (prestyle == wxSTC_P_COMMENTBLOCK)) and ((style == wxSTC_P_COMMENTLINE) or (style == wxSTC_P_COMMENTBLOCK))):
					newtext = newtext + text[x]
			else:
				newtext = newtext + text[x]
			x = x + 1
		self.txtDocument.ReplaceSelection(newtext)
	
	def OnUndo(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			self.txtPrompt.Undo()
		else:
			self.txtDocument.Undo()
	
	def OnUppercase(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			self.txtPrompt.CmdKeyExecute(wxSTC_CMD_UPPERCASE)
		else:
			self.txtDocument.CmdKeyExecute(wxSTC_CMD_UPPERCASE)
		
	def OnViewHelp(self, event):
		if (self.prefs.documentationviewhelpwithbrowser):
			wxExecute((self.prefs.documentationbrowser + " " + self.programdirectory + "/documentation/help.html"), wxEXEC_ASYNC)			
			return
		from drHelpDialog import drHelpDialog
		e = drHelpDialog(self, "DrPython Help")
		e.ShowModal()
		e.Destroy()
			
	def OnViewAbout(self, event):
		from drAboutDialog import drAboutDialog
		e = drAboutDialog(self, "About DrPython")
		e.ShowModal()
		e.Destroy()
	
	def OnViewPythonDocs(self, event):
		wxExecute((self.prefs.documentationbrowser + " " + self.prefs.documentationpythonlocation), wxEXEC_ASYNC)
	
	def OnViewREHowtoDocs(self, event):
		wxExecute((self.prefs.documentationbrowser + " " + self.prefs.documentationrehowtolocation), wxEXEC_ASYNC)
	
	def OnViewWxWidgetsDocs(self, event):
		wxExecute((self.prefs.documentationbrowser + " " + self.prefs.documentationwxwidgetslocation), wxEXEC_ASYNC)
	
	def OnZoomIn(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			zoom = self.txtPrompt.GetZoom()
			if (zoom < 20):
				self.txtPrompt.SetZoom(zoom + 1)
		else:
			zoom = self.txtDocument.GetZoom()
			if (zoom < 20):
				self.txtDocument.SetZoom(zoom + 1)
	
	def OnZoomOut(self, event):
		if (self.txtPrompt.GetSTCFocus()):
			zoom = self.txtPrompt.GetZoom()
			if (zoom > -9):
				self.txtPrompt.SetZoom(zoom - 1)
		else:
			zoom = self.txtDocument.GetZoom()
			if (zoom > -9):
				self.txtDocument.SetZoom(zoom - 1)
	
	def OpenFile(self, OpenInNewWindow, editrecentfiles = True, setTitle = True):
		wxBeginBusyCursor()
		if (not os.path.exists(self.filename)):
			d = wxScrolledMessageDialog(self, ("Error Opening: " + self.filename), "DrPython Error")
			d.ShowModal()
			d.Destroy()
			wxEndBusyCursor()	
			return
		self.logfile = self.filename + ".log"
		if (editrecentfiles):
			if (self.recentfiles.count(self.filename) is not 0):			
				self.ID_RECENT_FILES.pop()
				self.recentfiles.remove(self.filename)
			if (len(self.recentfiles) is self.prefs.recentfileslimit):
				self.recentfiles.pop()
				self.ID_RECENT_FILES.pop()
			ti = len(self.ID_RECENT_FILES) - 1
			if (ti > -1):
				self.ID_RECENT_FILES.append(self.ID_RECENT_FILES[ti] + 1)
			else:
				self.ID_RECENT_FILES.append(self.ID_RECENT_FILES_BASE)
			self.recentfiles.insert(0, self.filename)
			self.WriteRecentFiles()
		if (self.txtDocument.GetModify()) or OpenInNewWindow:
			if self.prefs.mdi:
				nextpage = drPanel(self.mdinotebook, self.ID_APP)
				self.sizertarget = nextpage
				self.mdinotebook.AddPage(nextpage, "Untitled")
				l = len(self.txtDocumentsArray)		
				self.txtDocumentsArray.append(DrText(nextpage, self.ID_APP, self))
				self.txtPromptsArray.append(DrPrompt(nextpage, self.ID_APP, self))				
				self.filenameArray.append(self.filename)
				self.logfileArray.append(self.filename + ".log")
				#copy old finder limodou 2004/04/19
				#self.FinderArray.append(drFinder(self))
				self.FinderArray.append(drFinder(self, self.Finder))
				#end limodou
				self.findposArray.append(0)
				self.findtextArray.append("")
				self.findflagsArray.append(0)
				self.replacetextArray.append("")
				self.lastprogargsArray.append("")
				#utf-8 detect limodou 2004/04/16
				#self.fileencodingArray.append(0)
				#end limodou
				self.setDocumentTo(l, True)
				#utf-8 auto detecting limodou 2004/04/16
				self.txtDocument.locale = self.prefs.encoding
				self.txtPrompt.local = self.prefs.encoding
				#end limodou
				
				#Sizer
				if (self.prefs.promptsize == 100):
					nextpage.bSizer.Add(self.txtDocumentsArray[self.docPosition], 1, wxEXPAND)
				else:
					nextpage.bSizer.Add(self.txtDocumentsArray[self.docPosition], (100 - self.prefs.promptsize), wxEXPAND)
				if (self.prefs.promptsize == 100):
					nextpage.bSizer.Add(self.txtPromptsArray[self.docPosition], 1, wxEXPAND)
				else:
					nextpage.bSizer.Add(self.txtPromptsArray[self.docPosition], self.prefs.promptsize, wxEXPAND)
		
				#What is visible
				if (not self.prefs.promptisvisible):
					nextpage.bSizer.Show(self.txtPromptsArray[self.docPosition], False)
					nextpage.bSizer.Layout()
				elif (self.prefs.promptsize == 100):
					nextpage.bSizer.Show(self.txtDocumentsArray[self.docPosition], False)
					nextpage.bSizer.Layout()
			else:										
				f = DrFrame(None, -1, self.app, ("DrPython - " + self.filename), self.filename, editrecentfiles)
				f.Show(True)
				self.app.UpdateWindowMenu()
				wxEndBusyCursor()
				return
		elif self.prefs.mdi:
			self.filenameArray[self.docPosition] = self.filename
			self.logfileArray[self.docPosition] = self.filename + ".log"
		try:		
			if self.prefs.mdi and setTitle:
				self.mdinotebook.SetPageText(self.docPosition, self.filename[(self.filename.rindex('/')+1):])
			if not self.docPosition:
				self.filenameArray[0] = self.filename
				self.logfileArray[0] = self.filename + ".log"
			cfile = file(self.filename, 'rb')
			oof = cfile.read()
			if not self.prefs.doconlyusedefaultsyntaxhighlighting:
				if self.checkiffileisPython(self.filename):
					#Python
					self.txtDocument.currentlanguage = 0
					self.highlightmenu.Check(self.ID_HIGHLIGHT_PYTHON, True)
				elif self.checkiffileisCPP(self.filename):
					#C/C++
					self.txtDocument.currentlanguage = 1
					self.highlightmenu.Check(self.ID_HIGHLIGHT_CPP, True)
				elif self.checkiffileisHTML(self.filename):
					#HTML
					self.txtDocument.currentlanguage = 2			
					self.highlightmenu.Check(self.ID_HIGHLIGHT_HTML, True)	
				elif self.checkiffileisPlainText(self.filename):
					#Plain Text
					self.txtDocument.currentlanguage = 3
					self.highlightmenu.Check(self.ID_HIGHLIGHT_PLAIN_TEXT, True)
				else:
					#Default
					pass
				self.txtDocument.SetupPrefsDocument()				
			#utf-8 auto detect limodou 2004/04/16
			if self.prefs.autodetectutf8encoding and (drDetectUTF_8.utf8Detect(oof)==True):
				self.SetEncodedText(self.txtDocument, oof, 2)
				#utf-8 detect limodou 2004/04/16
				#self.fileencodingArray[self.docPosition]=2
				self.txtDocument.locale = 2
				self.txtPrompt.locale = 2
				#end
			else:
				self.SetEncodedText(self.txtDocument, oof)
			#end limodou
			self.txtDocument.EmptyUndoBuffer()
			self.txtDocument.SetSavePoint()
			cfile.close()
			self.txtDocument.SetScrollWidth(1)
			
			#Check to see if scroll length is appropriate:
			
			#Encoding add limodou 2004/04/16
			self.encodingmenu.Check(self.ID_ENCODING_DEFAULT + self.txtDocument.locale, True)
			#endif 
			
			counter = 0
			length = self.txtDocument.GetLineCount()
			ll = self.txtDocument.TextWidth(wxSTC_STYLE_DEFAULT, "OOO")
			x = 0
			spaces = "\t".expandtabs(self.prefs.tabwidth)
			current_width = self.txtDocument.GetScrollWidth()
			while (counter < length):					
				line = self.txtDocument.GetLine(counter).replace('\t', spaces)
				actual_width = self.txtDocument.TextWidth(wxSTC_STYLE_DEFAULT, line)
				if (current_width < actual_width):
					current_width = actual_width + ll
				counter = counter + 1	
			self.txtDocument.SetScrollWidth(current_width)
									
			self.txtDocument.SetXOffset(0)				
			
			if (self.txtPrompt.process is None):
				if (self.hasToolBar):
					self.toolbar.EnableTool(self.ID_RUN, True)
					self.toolbar.EnableTool(self.ID_SET_ARGS, True)
					self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, True)
					self.toolbar.EnableTool(self.ID_RELOAD, True)
				self.programmenu.Enable(self.ID_RUN, True)
				self.programmenu.Enable(self.ID_SET_ARGS, True)
				self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, True)
				self.filemenu.Enable(self.ID_RELOAD, True)
				self.filemenu.Enable(self.ID_RESTORE_FROM_BACKUP, True)
			if setTitle:
				self.SetTitle("DrPython - " + self.filename)
			
			eollist = "".join(map(getEndOfLineCharacter, oof))
			
			self.txtDocument.lineendingsaremixed = 0
			
			if eollist.count('\r\n'):
				emodenum = 1			
			elif eollist.count('\n'):
				emodenum = 0
			elif eollist.count('\r'):
				emodenum = 2
			else:
				emodenum = self.prefs.eolmode
			if len(eollist) >= 2:
				win = eollist.count('\r\n\r\n')
				unix = eollist.count('\n\n')
				mac = eollist.count('\r\r')
				
				if (win and unix) or \
				(win and mac) or \
				(mac and unix):
					self.txtDocument.lineendingsaremixed = 1				
								
			dmodenum = self.prefs.eolmode
																																	
			if (self.prefs.checkeol):
				if (not emodenum == self.prefs.eolmode):
					if self.txtDocument.lineendingsaremixed:
						d = wxMessageDialog(self, (self.filename + " is currently "\
+ self.FFMESSAGE[emodenum] + "(Mixed).\nWould you like to change it to the default?\n(Since the file is mixed, \
this is highly recommended.\nThe Default is: " + self.FFMESSAGE[dmodenum]), "Mixed Line Ending", wxYES_NO | wxICON_QUESTION)
					else:
						d = wxMessageDialog(self, (self.filename + " is currently " + self.FFMESSAGE[emodenum] + ".\nWould you like to change it to the default?  The Default is: " + self.FFMESSAGE[dmodenum]), "Line Ending", wxYES_NO | wxICON_QUESTION)					
					answer = d.ShowModal()
					d.EndModal(0)
					d.Destroy()
					if (answer == wxID_YES):
						#Bugfix, Thanks Stephen Anderson.
						if (self.prefs.eolmode == 1):
							emode = wxSTC_EOL_CRLF
						elif (self.prefs.eolmode == 2):
							emode = wxSTC_EOL_CR
						else:
							emode = wxSTC_EOL_LF
						self.txtDocument.SetEOLMode(emode)
						self.txtDocument.ConvertEOLs(emode)
						emodenum = dmodenum
			if emodenum == 1:
				emode = wxSTC_EOL_CRLF
			elif emodenum == 2:
				emode = wxSTC_EOL_CR
			else:
				emode = wxSTC_EOL_LF
			self.txtDocument.SetEOLMode(emode)
			if self.txtDocument.lineendingsaremixed:
				eolmodestr = "MIX"
			else:
				emode = self.txtDocument.GetEOLMode()
				if emode == wxSTC_EOL_CR:
					eolmodestr = "MAC"
				elif emode == wxSTC_EOL_CRLF:
					eolmodestr = "WIN"
				else:
					eolmodestr = "UNIX"		
			self.SetStatusText("Line: 1, Col: 0 " + eolmodestr, 1)		
			if (editrecentfiles):
				self.ddirectory = os.path.dirname(self.filename)
			self.app.UpdateWindowMenu()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Opening: " + self.filename), "DrPython Error")
			d.ShowModal()
			d.Destroy()
				
		#The following chunk of code is an ugly way to work around a bug in wxSTC.
		#As things stand, word wrap may not update on file load.
		#This fixes the problem, by forcing drpython to reset the wxSTC instances.
		if (self.prefs.docwordwrap):
			x, y = self.GetSizeTuple()
			self.SetSize(wxSize(0, 0))
			self.SetSize(wxSize(x, y))
		#End of the chunk.
		
		wxEndBusyCursor()
	
	def SaveFile(self, IsSaveAs = True):
		try:
			if self.prefs.backupfileonsave and not IsSaveAs:
				try:
					shutil.copyfile(self.filename, self.filename+".bak")
				except:
					d = wxScrolledMessageDialog(self, ("Error Backing up to: " + self.filename + ".bak"), "DrPython Error")
					d.ShowModal()
					d.Destroy()					
			cfile = file(self.filename, 'wb')
			#comment limodou 2004/04/16
			#cfile.write(self.GetEncodedText(self.txtDocument, self.fileencodingArray[self.docPosition]))
			cfile.write(self.GetEncodedText(self.txtDocument))
			#end limodou
			cfile.close()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Writing: " + self.filename), "DrPython Error")
			d.ShowModal()
			d.Destroy()
		self.txtDocument.SetSavePoint()
		if (len(self.filename) > 0):
			self.SetTitle("DrPython - " + self.filename)
			if self.prefs.mdi:
				self.mdinotebook.SetPageText(self.docPosition, self.filename[(self.filename.rindex('/')+1):])
				
				
	def setDocumentTo(self, number, ignoreold = 0):
		prompthasfocus = (self.prefs.promptsize == 100)
		if not ignoreold:
			self.filenameArray[self.docPosition] = self.filename
			self.logfileArray[self.docPosition] = self.logfile
			self.findtextArray[self.docPosition] = self.findtext
			self.replacetextArray[self.docPosition] = self.replacetext
			self.lastprogargsArray[self.docPosition] = self.lastprogargs
			prompthasfocus = self.txtPrompt.GetSTCFocus()
		#copy old finder limodou 2004/04/19
		oldfinder = self.FinderArray[self.docPosition]
		#end limodou
		self.docPosition = number
		self.txtDocument = self.txtDocumentsArray[self.docPosition]
		self.txtPrompt = self.txtPromptsArray[self.docPosition]		
		self.filename = self.filenameArray[self.docPosition]
		self.Finder = self.FinderArray[self.docPosition]
		#copy old finder limodou 2004/04/19
		self.Finder.Copy(oldfinder)
		#end limodou
		self.findpos = self.findposArray[self.docPosition]
		self.findtext = self.findtextArray[self.docPosition]
		self.findflags = self.findflagsArray[self.docPosition]
		self.replacetext = self.replacetextArray[self.docPosition]
		self.filename = self.filenameArray[self.docPosition]
		self.logfile = self.logfileArray[self.docPosition]
		self.lastprogargs = self.lastprogargsArray[self.docPosition]
		self.sizertarget = self.mdinotebook.GetPage(self.docPosition)
		self.updatePrefsMDI(self.prefs)
		
		#Encoding
		self.encodingmenu.Check(self.ID_ENCODING_DEFAULT + self.txtDocument.locale, True)
		
		#Syntax Highlighting
		if self.txtDocument.currentlanguage == 0:
			self.highlightmenu.Check(self.ID_HIGHLIGHT_PYTHON, True)
		if self.txtDocument.currentlanguage == 1:
			self.highlightmenu.Check(self.ID_HIGHLIGHT_CPP, True)
		if self.txtDocument.currentlanguage == 2:
			self.highlightmenu.Check(self.ID_HIGHLIGHT_HTML, True)
		if self.txtDocument.currentlanguage == 3:
			#comment limodou 2004/04/13
			self.highlightmenu.Check(self.ID_HIGHLIGHT_PLAIN_TEXT, True)
			#end limodou 
			
		if (self.txtDocument.GetModify()):
			if (len(self.filename) <= 0):
				self.SetTitle("DrPython - Untitled*")
			else:
				self.SetTitle("DrPython - " + self.filename + "*")
		else:
			if (len(self.filename) <= 0):
				self.SetTitle("DrPython - Untitled")
			else:
				self.SetTitle("DrPython - " + self.filename)
			
		if self.txtPromptsArray[self.docPosition].pid is not -1:
			if self.txtPrompt.pythonintepreter:
				self.SetStatusText("Running Python Interpreter", 2)
			else:
				self.SetStatusText(("Running " + self.filename[(self.filename.rindex('/')+1):]), 2)
		else:
			self.SetStatusText("", 2)		
			
		if self.txtDocument.lineendingsaremixed:
			eolmodestr = "MIX"
		else:
			emode = self.txtDocument.GetEOLMode()
			if emode == wxSTC_EOL_CR:
				eolmodestr = "MAC"
			elif emode == wxSTC_EOL_CRLF:
				eolmodestr = "WIN"
			else:
				eolmodestr = "UNIX"
		self.SetStatusText(("Line: %(line)s, Col: %(col)s %(mode)s" % {"line": self.txtDocument.GetCurrentLine()+1, "col": self.txtDocument.GetColumn(self.txtDocument.GetCurrentPos()), "mode": eolmodestr}), 1)
			
		if prompthasfocus:
			self.txtPrompt.SetFocus()
		else:
			self.txtDocument.SetFocus()	
			
		self.mdinotebook.SetSelection(self.docPosition)
		if len(self.app.windowlist) > 1:
			self.app.UpdateWindowMenu()

	#SetText function limodou 2004/04/16
	#Edited a tad by drpython 2004/04/13
	#if encoding is None, then use default encoding
	#only support specified encoding or default encoding
	#should support utf-8 encoding auto detect
	def SetEncodedText(self, txtctrl, text, encodingid=0):
		if encodingid == 0:
			encodingid == txtctrl.locale
		if encodingid == 3:
			encoding = self.prefs.customencoding
		else:
			encoding = self.encodings[encodingid]
		if encoding == '<None>':
			encoding = self.encodings[0]
		isUnicode=txtctrl.GetCodePage()!=0
		if isUnicode:
			try:
				sText=unicode(text, encoding)
			except:
				d = wxScrolledMessageDialog(self, ("Error Encoding %s\n\nTrying other encoding...") % encoding, "DrPython Error")
				d.ShowModal()
				d.Destroy()
				sText=text
		else:
			#Additions of two try->except statements by drpython 4/22/2004
			#Bug report John Bell
			try:
				#utf-8 auto detect limodou 2004/04/14
				#sText=text
				sText=unicode(text, encoding).encode(self.encodings[0])	#convert utf-8 encoding to default encoding
				#set utf-8 encoding in preference
			except:
				#Do Nothing
				sText = text

		txtctrl.SetText(sText)
	#end limodou
	
	def SetupToolBar(self):
		return drToolBarFile.SetupToolBar(self)
			
	def runcommand(self, command, event, override = 0):
		if ((len(self.filename) > 0) and (self.txtPrompt.pid is -1)) or \
		(override and (self.txtPrompt.pid is -1)):
			if (self.hasToolBar):
				self.toolbar.EnableTool(self.ID_RUN, False)
				self.toolbar.EnableTool(self.ID_SET_ARGS, False)
				self.toolbar.EnableTool(self.ID_PYTHON, False)
				self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, False)
				self.toolbar.EnableTool(self.ID_END, True)	
				self.toolbar.ToggleTool(self.ID_TOGGLE_PROMPT,  True)
			self.programmenu.Enable(self.ID_RUN, False)
			self.programmenu.Enable(self.ID_SET_ARGS, False)
			self.programmenu.Enable(self.ID_PYTHON, False)
			self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, False)
			self.programmenu.Enable(self.ID_END, True)		
			if (not self.txtPrompt.IsVisible):
				self.txtPrompt.IsVisible = True
				if (self.prefs.promptsize == 100):
					self.sizertarget.bSizer.Show(self.txtDocument, False)
				self.sizertarget.bSizer.Show(self.txtPrompt, True)
				self.sizertarget.bSizer.Layout()
			self.txtPrompt.SetReadOnly(0)
			self.txtPrompt.ClearAll()
			self.txtPrompt.SetScrollWidth(1)
			self.txtPrompt.editpoint = 0
			if not override:
				filen = self.filename
				if (len(self.filename) > 0):
					try:
						cdir = self.filename[0:self.filename.rindex('/')]
						filen = self.filename[(self.filename.rindex('/')+1):]
						os.chdir(cdir)
					except:			
						d = wxScrolledMessageDialog(self, "Error Setting current directory for Python.", "DrPython RunError")
						d.ShowModal()
						d.Destroy()
					self.SetStatusText(("Running " + filen), 2)
			else:
				self.SetStatusText("Running Shell Command", 2)
			self.txtPrompt.process = wxProcess(self)
			self.txtPrompt.process.Redirect()
			if PLATFORM_IS_WIN:
				self.txtPrompt.pid = wxExecute(command, wxEXEC_ASYNC | wxEXEC_NOHIDE, self.txtPrompt.process)
			else:
				self.txtPrompt.pid = wxExecute(command, wxEXEC_ASYNC, self.txtPrompt.process)					
			self.txtPrompt.inputstream = self.txtPrompt.process.GetInputStream()		
			self.txtPrompt.errorstream = self.txtPrompt.process.GetErrorStream()
			self.txtPrompt.outputstream = self.txtPrompt.process.GetOutputStream()	
			self.txtPrompt.SetFocus()
	
	def ShowPrompt(self):
		if self.txtPrompt.IsVisible:
			return
		self.txtPrompt.IsVisible = True
		if self.hasToolBar:
			self.toolbar.ToggleTool(self.ID_TOGGLE_PROMPT,  True)
		self.sizertarget.bSizer.Show(self.txtPrompt, True)
		if (self.prefs.promptsize == 100):
			self.sizertarget.bSizer.Show(self.txtDocument, False)
		self.sizertarget.bSizer.Layout()
		self.txtPrompt.SetFocus()
	
	def RunShortcuts(self, event, stc = None):
		return drShortcuts.RunShortcuts(self, event, stc)
	
	def updatePrefsMDI(self, oldprefs):	
		#Determine What is showing
		if (self.txtPrompt.IsVisible):
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Show(self.txtDocumentsArray[self.docPosition], False)
				self.sizertarget.bSizer.Show(self.txtPromptsArray[self.docPosition], True)
			else:				
				self.sizertarget.bSizer.Show(self.txtDocumentsArray[self.docPosition], True)
				self.sizertarget.bSizer.Show(self.txtPromptsArray[self.docPosition], True)
		else:
			self.sizertarget.bSizer.Show(self.txtDocument, True)
			self.sizertarget.bSizer.Show(self.txtPrompt, False)
				
		self.sizertarget.bSizer.Layout()
		
		self.Layout()
		
		#Toolbar
		thereisafile = (len(self.filename) > 0)
		if (self.hasToolBar):
			self.toolbar.EnableTool(self.ID_RELOAD, thereisafile)
			
			if (self.txtPrompt.pid is -1):
				self.toolbar.EnableTool(self.ID_PYTHON, True)
				self.toolbar.EnableTool(self.ID_END, False)
				self.toolbar.EnableTool(self.ID_RUN, thereisafile)
				self.toolbar.EnableTool(self.ID_SET_ARGS, thereisafile)
				self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, thereisafile)			
			else:
				self.toolbar.EnableTool(self.ID_PYTHON, False)
				self.toolbar.EnableTool(self.ID_END, True)
				if thereisafile:
					self.toolbar.EnableTool(self.ID_RUN, False)
					self.toolbar.EnableTool(self.ID_SET_ARGS, False)
					self.toolbar.EnableTool(self.ID_PYTHON_DEBUGGER, False)
		
		#Menus
		self.filemenu.Enable(self.ID_RELOAD, thereisafile)
		self.filemenu.Enable(self.ID_RESTORE_FROM_BACKUP, thereisafile)
		
		if (self.txtPrompt.pid is -1):
			self.programmenu.Enable(self.ID_PYTHON, True)
			self.programmenu.Enable(self.ID_END, False)
			self.programmenu.Enable(self.ID_RUN, thereisafile)
			self.programmenu.Enable(self.ID_SET_ARGS, thereisafile)	
			self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, thereisafile)			
		else:
			self.programmenu.Enable(self.ID_PYTHON, False)
			self.programmenu.Enable(self.ID_END, True)
			if thereisafile:
				self.programmenu.Enable(self.ID_RUN, False)
				self.programmenu.Enable(self.ID_SET_ARGS, False)	
				self.programmenu.Enable(self.ID_PYTHON_DEBUGGER, False)
		
		#Styling:
		self.txtDocument.StyleResetDefault()
		self.txtDocument.StyleClearAll()
		self.txtDocument.SetCaretForeground("#000000")
		
		self.txtPrompt.StyleResetDefault()
		self.txtPrompt.StyleClearAll()
		self.txtPrompt.SetCaretForeground("#000000")								
				
		self.txtDocument.SetupPrefsDocument(0)
		self.txtPrompt.SetupPrefsPrompt(0)				
	
	def updatePrefs(self, oldprefs):		
		if (self.hasToolBar):
			self.bSizer.Remove(self.toolbar)
		if oldprefs.mdi:
			self.bSizer.Remove(self.mdinotebook)
			c = self.mdinotebook.GetPageCount()
			x = 0
			while (x < c):
				self.mdinotebook.GetPage(x).bSizer.Remove(self.txtDocumentsArray[x])
				self.mdinotebook.GetPage(x).bSizer.Remove(self.txtPromptsArray[x])
				x = x + 1
		else:
			self.bSizer.Remove(self.txtDocument)
			self.bSizer.Remove(self.txtPrompt)
		
		#DrScript:
		if self.prefs.drscriptloadexamples is not oldprefs.drscriptloadexamples:
			self.drscriptmenu.reloadscripts()			
		
		#Toolbar
		if (self.prefs.iconsize > 0):
			if (self.hasToolBar):
				self.DestroyToolBar()
			else:
				self.toolbar = wxToolBar(self, -1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL)
			self.ToolBarIdList = self.SetupToolBar()
			self.hasToolBar = 1
		else:
			if (self.hasToolBar):
				self.DestroyToolBar()
				self.toolbar.Show(0)
				self.toolbar.Destroy()
				self.toolbar = None
				self.hasToolBar = 0
		
		#comment limodou 2004/04/13
		self.locale=self.prefs.encoding
		#end limodou
		
		if not (oldprefs.recentfileslimit is self.prefs.recentfileslimit):
			self.DestroyRecentFileMenu()
			self.ID_RECENT_FILES = []
			self.recentfiles = []

			self.LoadRecentFiles()
			self.CreateRecentFileMenu()
			
		if (not oldprefs.sessionsrecentsessionslimit is self.prefs.sessionsrecentsessionslimit):
			self.DestroyRecentSessionMenu()
			self.ID_RECENT_SESSIONS = []
			self.recentsessions = []

			self.LoadRecentSessions()
			self.CreateRecentSessionMenu()
				
		if self.prefs.mdi is not oldprefs.mdi:
			self.filemenu.Enable(self.ID_CLOSE_MENU, self.prefs.mdi)			
			ttext = self.txtDocument.GetText()
			ptext = self.txtPrompt.GetText()
		
			tpos = self.txtDocument.GetCurrentPos()
			ppos = self.txtPrompt.GetCurrentPos()
			
			pedit = self.txtPrompt.editpoint
			pwrite = self.txtPrompt.writeposition
					
			pproc = self.txtPrompt.process
			ppid = self.txtPrompt.pid
			ppint = self.txtPrompt.pythonintepreter
			
			if pproc is not None:
				pins = self.txtPrompt.inputstream
				pers = self.txtPrompt.errorstream
				pous = self.txtPrompt.outputstream
				
			if self.prefs.mdi:	
				if len(self.filename) > 0:
					ftitle = self.filename[(self.filename.rindex('/')+1):]					
				else:
					ftitle = "Untitled"
						
				self.mdinotebook = drNotebook(self, -1, wxDefaultPosition, wxSize(self.prefs.windowwidth, self.prefs.windowheight), wxCLIP_CHILDREN)
						
				self.mdinotebook.AddPage(drPanel(self.mdinotebook, self.ID_APP), ftitle)
				
				page0 = self.mdinotebook.GetPage(0)
				
				self.sizertarget = page0
								
				self.txtDocument.Destroy()
				self.txtDocument = None
				self.txtPrompt.Destroy()
				self.txtPrompt = None
				
				self.txtDocument = DrText(page0, self.ID_APP, self)
				self.txtPrompt = DrPrompt(page0, self.ID_APP, self)								
			else:	
				self.bSizer.Remove(self.mdinotebook)
				l = len(self.filenameArray)
				x = l - 1
				while x > 0:
					self.setDocumentTo(x, True)
					f = DrFrame(None, -1, self.app, "DrPython - " + self.filename, self.filename, 0, self.prefs)
					f.Show(True)
					self.DestroyDocument()
					x = x - 1
				self.setDocumentTo(0, True)
												
				self.mdinotebook.DeleteAllPages()
				self.mdinotebook.Destroy()
				self.mdinotebook = None
				
				self.sizertarget = self
				
				self.txtDocument = DrText(self, self.ID_APP, self)
				self.txtPrompt = DrPrompt(self, self.ID_APP, self)
			
			self.txtDocumentsArray.pop()
			self.txtPromptsArray.pop()
			self.txtDocumentsArray = [self.txtDocument]
			self.txtPromptsArray = [self.txtPrompt]
			
			self.txtDocument.SetText(ttext)
			self.txtDocument.EmptyUndoBuffer()
			self.txtDocument.SetSavePoint()
			self.txtPrompt.SetText(ptext)
			self.txtPrompt.EmptyUndoBuffer()
			self.txtPrompt.SetSavePoint()
			
			if len(self.filename) > 0:
				self.SetTitle("DrPython - " + self.filename)
			else:
				self.SetTitle("DrPython - Untitled")
			
			self.txtDocument.GotoPos(tpos)
			self.txtPrompt.GotoPos(ppos)
			
			self.txtPrompt.editpoint = pedit
			self.txtPrompt.writeposition = pwrite
					
			self.txtPrompt.process = pproc
			self.txtPrompt.pid = ppid
			self.txtPrompt.pythonintepreter = ppint
			
			if pproc is not None:
				self.txtPrompt.inputstream = pins
				self.txtPrompt.errorstream = pers
				self.txtPrompt.outputstream = pous

		#Styling:
		self.txtDocument.StyleResetDefault()
		self.txtDocument.StyleClearAll()
		
		self.txtPrompt.StyleResetDefault()
		self.txtPrompt.StyleClearAll()
		
		self.txtDocument.SetupPrefsDocument()
		self.txtPrompt.SetupPrefsPrompt()

		if (oldprefs.docfolding):
			if (not self.prefs.docfolding):
				self.txtDocument.FoldAll(True)
		
		#Set the Size of the Window
		if (self.prefs.windowwidth > -1) and (self.prefs.windowheight > -1):
			self.SetSize(wxSize(self.prefs.windowwidth, self.prefs.windowheight))
		#Work Around Bug in wxPython 2.5.1
		try:
			self.Maximize(False)
		except:
			pass
				
		#Add The Stuff to the Sizer
		if (self.prefs.iconsize > 0):
			self.bSizer.Add(self.toolbar, 0, wxEXPAND)
		if self.prefs.mdi:
			self.bSizer.Add(self.mdinotebook, 1, wxEXPAND)
			c = self.mdinotebook.GetPageCount()
			x = 0
			if (self.prefs.promptsize == 100):
				txtfileproportion = 1
				txtpromptproportion = 1
			else:
				txtfileproportion = (100 - self.prefs.promptsize)
				txtpromptproportion = self.prefs.promptsize
				
			while (x < c):			
				self.mdinotebook.GetPage(x).bSizer.Add(self.txtDocumentsArray[x], txtfileproportion, wxEXPAND)
				self.mdinotebook.GetPage(x).bSizer.Add(self.txtPromptsArray[x], txtpromptproportion, wxEXPAND)
				x = x + 1
		else:
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Add(self.txtDocumentsArray[self.docPosition], 1, wxEXPAND)
				self.sizertarget.bSizer.Add(self.txtPromptsArray[self.docPosition], 1, wxEXPAND)
			else:
				self.sizertarget.bSizer.Add(self.txtDocumentsArray[self.docPosition], (100 - self.prefs.promptsize), wxEXPAND)
				self.sizertarget.bSizer.Add(self.txtPromptsArray[self.docPosition], self.prefs.promptsize, wxEXPAND)
			
		#Determine What is showing
		if (self.txtPrompt.IsVisible):
			if (self.prefs.promptsize == 100):
				self.sizertarget.bSizer.Show(self.txtDocumentsArray[self.docPosition], False)
				self.sizertarget.bSizer.Show(self.txtPromptsArray[self.docPosition], True)
				self.txtPrompt.SetFocus()
			else:				
				self.sizertarget.bSizer.Show(self.txtDocumentsArray[self.docPosition], True)
				self.sizertarget.bSizer.Show(self.txtPromptsArray[self.docPosition], True)
				self.txtDocument.SetFocus()
		else:
			self.sizertarget.bSizer.Show(self.txtDocument, True)
			self.sizertarget.bSizer.Show(self.txtPrompt, False)
			self.txtDocument.SetFocus()
		self.sizertarget.bSizer.Layout()
		
		self.Layout()
		
	def WriteRecentFiles(self):
		try:
			fin = open((self.homedirectory + "/recent_files.log"), 'w')
			x = 0
			length = len(self.recentfiles)
			while (x < self.prefs.recentfileslimit) and (x < length):
				fin.write(self.recentfiles[x] + '\n')
				x = x + 1
			fin.close()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Writing: " + f), "Recent Files Error")
			d.ShowModal()
			d.Destroy()
			
	def WriteRecentSessions(self):
		try:
			fin = open((self.homedirectory + "/recent_sessions.log"), 'w')
			x = 0
			length = len(self.recentsessions)
			while (x < self.prefs.sessionsrecentsessionslimit) and (x < length):
				fin.write(self.recentsessions[x] + '\n')
				x = x + 1
			fin.close()
		except IOError:
			d = wxScrolledMessageDialog(self, ("Error Writing: " + f), "Recent Sessions Error")
			d.ShowModal()
			d.Destroy()
			
#*******************************************************************************************************

class DrApp(wxApp):

	def OnInit(self):

		self.windowlist = []
		frame = DrFrame(None, 101, self, "DrPython - Untitled")
		frame.Show(True)

		self.SetTopWindow(frame)

		return True
		
	def UpdateWindowMenu(self):
		x = 0
		l = len(self.windowlist)
		while x < l:
			self.windowlist[x].DestroyWindowMenu()
			self.windowlist[x].CreateWindowMenu()
			x = x + 1

app = DrApp(0)
app.MainLoop()
