2002-08-12 13:56:45 -04:00
|
|
|
#!/usr/bin/env python
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
# simple text editor
|
|
|
|
#
|
|
|
|
# Copyright 2001 Adam Feuer and Steve Howell
|
|
|
|
#
|
|
|
|
# License: Python
|
|
|
|
|
2004-01-12 22:28:11 -05:00
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import string
|
|
|
|
import sys
|
|
|
|
|
|
|
|
import wx
|
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
from StatusBar import *
|
|
|
|
from FrogEditor import FrogEditor
|
|
|
|
|
|
|
|
|
|
|
|
ABOUT_TEXT = """FrogEdit : Copyright 2001 Adam Feuer and Steve Howell
|
|
|
|
wxEditor component : Copyright 1999 - 2001 Dirk Holtwic, Robin Dunn, Adam Feuer, Steve Howell
|
|
|
|
|
|
|
|
FrogEdit was built using Python, wxPython, and wxWindows."""
|
|
|
|
|
|
|
|
|
|
|
|
##---------------------------------------------------------------------
|
|
|
|
|
|
|
|
def chomp(line):
|
|
|
|
line = string.split(line,'\n')[0]
|
|
|
|
return string.split(line,'\r')[0]
|
|
|
|
|
|
|
|
##---------------------------------------------------------------------
|
|
|
|
|
2004-01-12 22:28:11 -05:00
|
|
|
class OutlinerPanel(wx.Panel):
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
def Close(self, event):
|
|
|
|
self.parent.Close()
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.Panel.Close(self)
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
##----------------------------------------------------------------------
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
|
2004-01-12 22:28:11 -05:00
|
|
|
class FrogEditFrame(wx.Frame):
|
|
|
|
def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
|
|
|
|
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
|
2001-11-30 21:25:39 -05:00
|
|
|
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.Frame.__init__(self, parent, ID, title, pos, size, style)
|
2001-11-30 21:25:39 -05:00
|
|
|
|
2004-01-12 22:28:11 -05:00
|
|
|
splitter = wx.SplitterWindow(self, -1, style=wx.NO_3D|wx.SP_3D)
|
|
|
|
win = OutlinerPanel(splitter, -1, style=wx.CLIP_CHILDREN)
|
2001-11-30 21:25:39 -05:00
|
|
|
win.parent = self
|
|
|
|
log = self.MakeLogWindow(splitter)
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
self.MakeStatusbar()
|
|
|
|
self.MakeEditorWindow(win, log)
|
|
|
|
self.SetUpSplitter(splitter, win, log)
|
|
|
|
self.MakeMenus()
|
|
|
|
self.MakeMainWindow(win)
|
|
|
|
self.RegisterEventHandlers()
|
|
|
|
self.InitVariables()
|
|
|
|
|
2001-12-03 15:41:03 -05:00
|
|
|
win.Layout()
|
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
##------------- Init Misc
|
|
|
|
|
|
|
|
def RegisterEventHandlers(self):
|
2004-01-12 22:28:11 -05:00
|
|
|
self.Bind(wx.EVT_CLOSE,self.OnCloseWindow)
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
def InitVariables(self):
|
|
|
|
self.fileName = None
|
|
|
|
self.edl.UnTouchBuffer()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def MakeMenus(self):
|
2004-01-12 22:28:11 -05:00
|
|
|
self.MainMenu = wx.MenuBar()
|
2001-11-30 21:25:39 -05:00
|
|
|
self.AddMenus(self.MainMenu)
|
|
|
|
self.SetMenuBar(self.MainMenu)
|
|
|
|
|
|
|
|
##------------- Init Subwindows
|
|
|
|
|
|
|
|
def MakeEditorWindow(self, win, log):
|
2004-01-12 22:28:11 -05:00
|
|
|
self.edl = FrogEditor(win, -1, style=wx.SUNKEN_BORDER, statusBar = self.sb)
|
2001-11-30 21:25:39 -05:00
|
|
|
self.edl.SetControlFuncs = self.SetControlFuncs
|
|
|
|
self.edl.SetAltFuncs = self.SetAltFuncs
|
|
|
|
self.edl.SetStatus(log)
|
|
|
|
|
|
|
|
def MakeStatusbar(self):
|
|
|
|
self.sb = CustomStatusBar(self)
|
|
|
|
self.SetStatusBar(self.sb)
|
|
|
|
|
|
|
|
def MakeLogWindow(self, container):
|
2004-01-12 22:28:11 -05:00
|
|
|
log = wx.TextCtrl(container, -1,
|
|
|
|
style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
|
|
|
|
wx.Log_SetActiveTarget(wx.LogTextCtrl(log))
|
|
|
|
wx.LogMessage('window handle: %s' % self.GetHandle())
|
2001-11-30 21:25:39 -05:00
|
|
|
return log
|
|
|
|
|
|
|
|
def SetUpSplitter(self, splitter, win, log):
|
|
|
|
splitter.SplitHorizontally(win, log)
|
2003-03-25 01:35:27 -05:00
|
|
|
splitter.SetSashPosition(360, True)
|
2001-11-30 21:25:39 -05:00
|
|
|
splitter.SetMinimumPaneSize(40)
|
|
|
|
|
|
|
|
def MakeToolbar(self, win):
|
2004-01-12 22:28:11 -05:00
|
|
|
toolbarBox = wx.BoxSizer(wx.HORIZONTAL)
|
2001-11-30 21:25:39 -05:00
|
|
|
self.AddButtons(win, toolbarBox)
|
|
|
|
return toolbarBox
|
|
|
|
|
|
|
|
def MakeMainWindow(self, win):
|
2004-01-12 22:28:11 -05:00
|
|
|
mainBox = wx.BoxSizer(wx.VERTICAL)
|
2001-11-30 21:25:39 -05:00
|
|
|
mainBox.Add(self.MakeToolbar(win))
|
|
|
|
borderWidth = 5
|
2004-01-12 22:28:11 -05:00
|
|
|
mainBox.Add(self.edl, 1, wx.ALL|wx.GROW, borderWidth)
|
2001-11-30 21:25:39 -05:00
|
|
|
win.SetSizer(mainBox)
|
2003-03-25 01:35:27 -05:00
|
|
|
win.SetAutoLayout(True)
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
##-------------- Init Menus
|
|
|
|
|
|
|
|
# override this to add more menus
|
|
|
|
def AddMenus(self, menu):
|
|
|
|
self.AddFileMenu(menu)
|
|
|
|
self.AddEditMenu(menu)
|
|
|
|
self.AddHelpMenu(menu)
|
|
|
|
|
|
|
|
def AddMenuItem(self, menu, itemText, itemDescription, itemHandler):
|
2004-01-12 22:28:11 -05:00
|
|
|
menuId = wx.NewId()
|
2001-11-30 21:25:39 -05:00
|
|
|
menu.Append(menuId, itemText, itemDescription)
|
2004-01-12 22:28:11 -05:00
|
|
|
self.Bind(wx.EVT_MENU, itemHandler, id=menuId)
|
2001-11-30 21:25:39 -05:00
|
|
|
return menuId
|
|
|
|
|
|
|
|
def AddFileMenu(self, menu):
|
2004-01-12 22:28:11 -05:00
|
|
|
fileMenu = wx.Menu()
|
2001-11-30 21:25:39 -05:00
|
|
|
self.AddMenuItem(fileMenu, '&New File\tCtrl-N', 'New File', self.OnNewFile)
|
|
|
|
self.AddMenuItem(fileMenu, '&Open File\tCtrl-O', 'Open File', self.OnOpenFile)
|
|
|
|
self.AddMenuItem(fileMenu, '&Save File\tCtrl-S', 'Save File', self.OnSaveFile)
|
|
|
|
self.AddMenuItem(fileMenu, 'Save File &As\tCtrl-A', 'Save File As',self.OnSaveFileAs)
|
|
|
|
self.AddMenuItem(fileMenu, 'E&xit\tAlt-X', 'Exit', self.OnFileExit)
|
|
|
|
menu.Append(fileMenu, 'File')
|
|
|
|
|
|
|
|
def AddEditMenu(self, menu):
|
2004-01-12 22:28:11 -05:00
|
|
|
editMenu = wx.Menu()
|
2001-11-30 21:25:39 -05:00
|
|
|
self.AddMenuItem(editMenu, 'Cut\tCtrl-X', 'Cut', self.edl.OnCutSelection)
|
|
|
|
self.AddMenuItem(editMenu, '&Copy\tCtrl-C', 'Copy', self.edl.OnCopySelection)
|
|
|
|
self.AddMenuItem(editMenu, 'Paste\tCtrl-V', 'Paste', self.edl.OnPaste)
|
|
|
|
self.AddMenuItem(editMenu, 'Edit preferences', 'Edit Preferences', self.OnEditPreferences)
|
|
|
|
menu.Append(editMenu, 'Edit')
|
|
|
|
|
|
|
|
def AddHelpMenu(self, menu):
|
2004-01-12 22:28:11 -05:00
|
|
|
helpMenu = wx.Menu()
|
2001-11-30 21:25:39 -05:00
|
|
|
self.AddMenuItem(helpMenu, 'About', 'About the program', self.OnHelpAbout)
|
|
|
|
menu.Append(helpMenu, 'Help')
|
|
|
|
|
|
|
|
##---------------- Init Buttons
|
|
|
|
|
|
|
|
|
|
|
|
def NewButton(self, window, container, name, pos, size, handler):
|
2004-01-12 22:28:11 -05:00
|
|
|
buttonId = wx.NewId()
|
2001-11-30 21:25:39 -05:00
|
|
|
if pos == None or size == None:
|
2004-01-12 22:28:11 -05:00
|
|
|
container.Add(wx.Button(window, buttonId, name), 0, 0)
|
2001-11-30 21:25:39 -05:00
|
|
|
else:
|
2004-01-12 22:28:11 -05:00
|
|
|
container.Add(wx.Button(window, buttonId, name, pos, size), 0, 0)
|
|
|
|
self.Bind(wx.EVT_BUTTON, handler, id=buttonId)
|
2001-11-30 21:25:39 -05:00
|
|
|
return buttonId
|
|
|
|
|
|
|
|
# override this to make more buttons
|
|
|
|
def AddButtons(self, window, container):
|
|
|
|
buttonPos = None
|
|
|
|
buttonSize = None
|
|
|
|
self.NewButton(window, container, "New", buttonPos, buttonSize, self.OnNewFile)
|
|
|
|
self.NewButton(window, container, "Open", buttonPos, buttonSize, self.OnOpenFile)
|
|
|
|
self.NewButton(window, container, "Save", buttonPos, buttonSize, self.OnSaveFile)
|
|
|
|
|
|
|
|
|
|
|
|
##-------------- Init Dialogs
|
|
|
|
|
|
|
|
def MessageDialog(self, text, title):
|
2004-01-12 22:28:11 -05:00
|
|
|
messageDialog = wx.MessageDialog(self, text, title, wx.OK | wx.ICON_INFORMATION)
|
2001-11-30 21:25:39 -05:00
|
|
|
messageDialog.ShowModal()
|
|
|
|
messageDialog.Destroy()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def OkCancelDialog(self, text, title):
|
2004-01-12 22:28:11 -05:00
|
|
|
dialog = wx.MessageDialog(self, text, title, wx.OK | wx.CANCEL | wx.ICON_INFORMATION)
|
2001-11-30 21:25:39 -05:00
|
|
|
result = dialog.ShowModal()
|
|
|
|
dialog.Destroy()
|
2004-01-12 22:28:11 -05:00
|
|
|
if result == wx.ID_OK:
|
2003-03-25 01:35:27 -05:00
|
|
|
return True
|
2001-11-30 21:25:39 -05:00
|
|
|
else:
|
2003-03-25 01:35:27 -05:00
|
|
|
return False
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
def SelectFileDialog(self, defaultDir=None, defaultFile=None, wildCard=None):
|
|
|
|
if defaultDir == None:
|
|
|
|
defaultDir = "."
|
|
|
|
if defaultFile == None:
|
|
|
|
defaultFile = ""
|
|
|
|
if wildCard == None:
|
|
|
|
wildCard = "*.*"
|
|
|
|
fileName = None
|
2004-01-12 22:28:11 -05:00
|
|
|
fileDialog = wx.FileDialog(self, "Choose a file", defaultDir, defaultFile, wildCard, wx.OPEN|wx.MULTIPLE)
|
2001-12-03 15:41:03 -05:00
|
|
|
result = fileDialog.ShowModal()
|
2004-01-12 22:28:11 -05:00
|
|
|
if result == wx.ID_OK:
|
2001-11-30 21:25:39 -05:00
|
|
|
fileName = fileDialog.GetPath()
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.LogMessage('You selected: %s\n' % fileName)
|
2001-12-03 15:41:03 -05:00
|
|
|
fileDialog.Destroy()
|
2001-11-30 21:25:39 -05:00
|
|
|
return fileName
|
|
|
|
|
|
|
|
def OpenFileError(self, fileName):
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.LogMessage('Open file error.')
|
2001-11-30 21:25:39 -05:00
|
|
|
self.MessageDialog("Error opening file '%s'!" % fileName, "Error")
|
|
|
|
|
|
|
|
|
|
|
|
def SaveFileError(self, fileName):
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.LogMessage('Save file error.')
|
2001-11-30 21:25:39 -05:00
|
|
|
self.MessageDialog("Error saving file '%s'!" % fileName, "Error")
|
|
|
|
|
|
|
|
##---------------- Utility functions
|
|
|
|
|
|
|
|
|
|
|
|
def SetControlFuncs(self, action):
|
|
|
|
"for overriding editor's keys"
|
|
|
|
FrogEditor.SetControlFuncs(self.edl, action)
|
|
|
|
action['a'] = self.OnSaveFileAs
|
|
|
|
action['o'] = self.OnOpenFile
|
|
|
|
action['n'] = self.OnNewFile
|
|
|
|
action['s'] = self.OnSaveFile
|
|
|
|
|
|
|
|
def SetAltFuncs(self, action):
|
|
|
|
FrogEditor.SetAltFuncs(self.edl, action)
|
2001-12-03 15:41:03 -05:00
|
|
|
action['x'] = self.OnFileExit
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
def GetCurrentDir(self):
|
|
|
|
if self.fileName is not None:
|
|
|
|
return os.path.split(self.fileName)[0]
|
|
|
|
return "."
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def GetFileName(self):
|
|
|
|
if self.fileName is not None:
|
|
|
|
return os.path.split(self.fileName)[1]
|
|
|
|
return ""
|
|
|
|
|
|
|
|
def NewFile(self):
|
|
|
|
self.edl.SetText([""])
|
|
|
|
self.fileName = None
|
|
|
|
self.sb.setFileName("")
|
|
|
|
|
|
|
|
def SaveFile(self, fileName):
|
|
|
|
try:
|
|
|
|
contents = string.join(self.edl.GetText(), '\n')
|
|
|
|
f = open(fileName, 'w')
|
|
|
|
f.write(contents)
|
|
|
|
f.close()
|
|
|
|
self.edl.UnTouchBuffer()
|
|
|
|
self.sb.setFileName(fileName)
|
2003-03-25 01:35:27 -05:00
|
|
|
return True
|
2001-11-30 21:25:39 -05:00
|
|
|
except:
|
2003-03-25 01:35:27 -05:00
|
|
|
return False
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
def OpenFile(self, fileName):
|
|
|
|
try:
|
|
|
|
f = open(fileName, 'r')
|
|
|
|
contents = f.readlines()
|
|
|
|
f.close()
|
|
|
|
contents = [chomp(line) for line in contents]
|
|
|
|
if len(contents) == 0:
|
|
|
|
contents = [""]
|
|
|
|
self.edl.SetText(contents)
|
|
|
|
self.fileName = fileName
|
|
|
|
self.sb.setFileName(fileName)
|
2003-03-25 01:35:27 -05:00
|
|
|
return True
|
2001-11-30 21:25:39 -05:00
|
|
|
except:
|
2003-03-25 01:35:27 -05:00
|
|
|
return False
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
|
|
|
|
##---------------- Event handlers
|
|
|
|
|
|
|
|
|
|
|
|
def OnCloseWindow(self, event):
|
|
|
|
self.edl.OnCloseWindow(event)
|
|
|
|
self.Destroy()
|
|
|
|
|
|
|
|
def OnNewFile(self, event):
|
|
|
|
if self.edl.BufferWasTouched():
|
|
|
|
if not self.OkCancelDialog("New file - abandon changes?", "New File"):
|
|
|
|
return
|
|
|
|
self.NewFile()
|
|
|
|
self.edl.SetFocus()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def OnOpenFile(self, event):
|
|
|
|
if self.edl.BufferWasTouched():
|
|
|
|
if not self.OkCancelDialog("Open file - abandon changes?", "Open File"):
|
|
|
|
return
|
|
|
|
fileName = self.SelectFileDialog(self.GetCurrentDir())
|
|
|
|
if fileName is not None:
|
2003-03-25 01:35:27 -05:00
|
|
|
if self.OpenFile(fileName) is False:
|
2001-11-30 21:25:39 -05:00
|
|
|
self.OpenFileError(fileName)
|
|
|
|
self.edl.SetFocus()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def OnSaveFile(self, event):
|
|
|
|
if self.fileName is None:
|
|
|
|
return self.OnSaveFileAs(event)
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.LogMessage("Saving %s..." % self.fileName)
|
2003-03-25 01:35:27 -05:00
|
|
|
if self.SaveFile(self.fileName) is not True:
|
2001-11-30 21:25:39 -05:00
|
|
|
self.SaveFileError(self.fileName)
|
|
|
|
self.edl.SetFocus()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def OnSaveFileAs(self, event):
|
|
|
|
fileName = self.SelectFileDialog(self.GetCurrentDir(),self.GetFileName())
|
|
|
|
if fileName is not None:
|
|
|
|
self.fileName = fileName
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.LogMessage("Saving %s..." % self.fileName)
|
2003-03-25 01:35:27 -05:00
|
|
|
if self.SaveFile(self.fileName) is not True:
|
2001-11-30 21:25:39 -05:00
|
|
|
self.SaveFileError(self.fileName)
|
|
|
|
self.edl.SetFocus()
|
2001-12-03 15:41:03 -05:00
|
|
|
|
|
|
|
def OnFileExit(self, event):
|
2001-11-30 21:25:39 -05:00
|
|
|
if self.edl.BufferWasTouched():
|
|
|
|
if not self.OkCancelDialog("Exit program - abandon changes?", "Exit"):
|
|
|
|
return
|
|
|
|
self.OnCloseWindow(event)
|
|
|
|
|
|
|
|
def OnEditPreferences(self, event):
|
|
|
|
self.MessageDialog("Edit preferences is not implemented yet.", "Not implemented.")
|
|
|
|
pass
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def OnHelpAbout(self, event):
|
|
|
|
self.MessageDialog(ABOUT_TEXT, "About FrogEdit")
|
|
|
|
pass
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def Show(self, show):
|
2004-01-12 22:28:11 -05:00
|
|
|
wx.Frame.Show(self, show)
|
2001-11-30 21:25:39 -05:00
|
|
|
self.edl.SetFocus()
|
|
|
|
|
|
|
|
##------------- Startup stuff
|
|
|
|
|
|
|
|
def LoadInitialFile(self, fileName):
|
|
|
|
if fileName is not None:
|
2003-03-25 01:35:27 -05:00
|
|
|
if self.OpenFile(fileName) is False:
|
2001-12-03 15:41:03 -05:00
|
|
|
self.OpenFileError(fileName)
|
2001-11-30 21:25:39 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##-------------- Application Launcher utility class
|
|
|
|
|
|
|
|
class FrogEditLauncher:
|
|
|
|
|
|
|
|
def MakeAppFrame(self):
|
|
|
|
return FrogEditFrame(None, -1, "FrogEdit", size=(640, 480),
|
2004-01-12 22:28:11 -05:00
|
|
|
style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
|
2001-12-03 15:41:03 -05:00
|
|
|
|
2001-11-30 21:25:39 -05:00
|
|
|
def GetArgvFilename(self):
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
return sys.argv[1]
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
def Main(self):
|
2004-01-12 22:28:11 -05:00
|
|
|
app = wx.PySimpleApp()
|
2001-12-03 15:41:03 -05:00
|
|
|
win = self.MakeAppFrame()
|
2003-03-25 01:35:27 -05:00
|
|
|
win.Show(True)
|
2001-11-30 21:25:39 -05:00
|
|
|
win.LoadInitialFile(self.GetArgvFilename())
|
|
|
|
app.MainLoop()
|
|
|
|
|
|
|
|
|
|
|
|
##-------------- Main program
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
launcher = FrogEditLauncher()
|
|
|
|
launcher.Main()
|