]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/frogedit/FrogEdit.py
Fix or add some DoGetBestSize's
[wxWidgets.git] / wxPython / samples / frogedit / FrogEdit.py
CommitLineData
4491d3ae 1#!/usr/bin/env python
1918b6f7
RD
2
3# simple text editor
4#
5# Copyright 2001 Adam Feuer and Steve Howell
6#
7# License: Python
8
2571247b
RD
9import os
10import re
11import string
12import sys
13
14import wx
15
1918b6f7
RD
16from StatusBar import *
17from FrogEditor import FrogEditor
18
1918b6f7
RD
19
20ABOUT_TEXT = """FrogEdit : Copyright 2001 Adam Feuer and Steve Howell
21wxEditor component : Copyright 1999 - 2001 Dirk Holtwic, Robin Dunn, Adam Feuer, Steve Howell
22
23FrogEdit was built using Python, wxPython, and wxWindows."""
24
25
26##---------------------------------------------------------------------
27
28def chomp(line):
29 line = string.split(line,'\n')[0]
30 return string.split(line,'\r')[0]
31
32##---------------------------------------------------------------------
33
2571247b 34class OutlinerPanel(wx.Panel):
1918b6f7
RD
35
36 def Close(self, event):
37 self.parent.Close()
2571247b 38 wx.Panel.Close(self)
1918b6f7
RD
39
40##----------------------------------------------------------------------
78e8819c 41
1918b6f7 42
2571247b
RD
43class FrogEditFrame(wx.Frame):
44 def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
45 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
1918b6f7 46
2571247b 47 wx.Frame.__init__(self, parent, ID, title, pos, size, style)
1918b6f7 48
2571247b
RD
49 splitter = wx.SplitterWindow(self, -1, style=wx.NO_3D|wx.SP_3D)
50 win = OutlinerPanel(splitter, -1, style=wx.CLIP_CHILDREN)
1918b6f7
RD
51 win.parent = self
52 log = self.MakeLogWindow(splitter)
78e8819c 53
1918b6f7
RD
54 self.MakeStatusbar()
55 self.MakeEditorWindow(win, log)
56 self.SetUpSplitter(splitter, win, log)
57 self.MakeMenus()
58 self.MakeMainWindow(win)
59 self.RegisterEventHandlers()
60 self.InitVariables()
61
78e8819c
RD
62 win.Layout()
63
1918b6f7
RD
64
65##------------- Init Misc
66
67 def RegisterEventHandlers(self):
2571247b 68 self.Bind(wx.EVT_CLOSE,self.OnCloseWindow)
1918b6f7
RD
69
70 def InitVariables(self):
71 self.fileName = None
72 self.edl.UnTouchBuffer()
78e8819c 73
1918b6f7 74 def MakeMenus(self):
2571247b 75 self.MainMenu = wx.MenuBar()
1918b6f7
RD
76 self.AddMenus(self.MainMenu)
77 self.SetMenuBar(self.MainMenu)
78
79##------------- Init Subwindows
80
81 def MakeEditorWindow(self, win, log):
2571247b 82 self.edl = FrogEditor(win, -1, style=wx.SUNKEN_BORDER, statusBar = self.sb)
1918b6f7
RD
83 self.edl.SetControlFuncs = self.SetControlFuncs
84 self.edl.SetAltFuncs = self.SetAltFuncs
85 self.edl.SetStatus(log)
86
87 def MakeStatusbar(self):
88 self.sb = CustomStatusBar(self)
89 self.SetStatusBar(self.sb)
90
91 def MakeLogWindow(self, container):
2571247b
RD
92 log = wx.TextCtrl(container, -1,
93 style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
94 wx.Log_SetActiveTarget(wx.LogTextCtrl(log))
95 wx.LogMessage('window handle: %s' % self.GetHandle())
1918b6f7
RD
96 return log
97
98 def SetUpSplitter(self, splitter, win, log):
99 splitter.SplitHorizontally(win, log)
1e4a197e 100 splitter.SetSashPosition(360, True)
1918b6f7
RD
101 splitter.SetMinimumPaneSize(40)
102
103 def MakeToolbar(self, win):
2571247b 104 toolbarBox = wx.BoxSizer(wx.HORIZONTAL)
1918b6f7
RD
105 self.AddButtons(win, toolbarBox)
106 return toolbarBox
107
108 def MakeMainWindow(self, win):
2571247b 109 mainBox = wx.BoxSizer(wx.VERTICAL)
1918b6f7
RD
110 mainBox.Add(self.MakeToolbar(win))
111 borderWidth = 5
2571247b 112 mainBox.Add(self.edl, 1, wx.ALL|wx.GROW, borderWidth)
1918b6f7 113 win.SetSizer(mainBox)
1e4a197e 114 win.SetAutoLayout(True)
1918b6f7
RD
115
116##-------------- Init Menus
117
118 # override this to add more menus
119 def AddMenus(self, menu):
120 self.AddFileMenu(menu)
121 self.AddEditMenu(menu)
122 self.AddHelpMenu(menu)
123
124 def AddMenuItem(self, menu, itemText, itemDescription, itemHandler):
2571247b 125 menuId = wx.NewId()
1918b6f7 126 menu.Append(menuId, itemText, itemDescription)
2571247b 127 self.Bind(wx.EVT_MENU, itemHandler, id=menuId)
1918b6f7
RD
128 return menuId
129
130 def AddFileMenu(self, menu):
2571247b 131 fileMenu = wx.Menu()
1918b6f7
RD
132 self.AddMenuItem(fileMenu, '&New File\tCtrl-N', 'New File', self.OnNewFile)
133 self.AddMenuItem(fileMenu, '&Open File\tCtrl-O', 'Open File', self.OnOpenFile)
134 self.AddMenuItem(fileMenu, '&Save File\tCtrl-S', 'Save File', self.OnSaveFile)
135 self.AddMenuItem(fileMenu, 'Save File &As\tCtrl-A', 'Save File As',self.OnSaveFileAs)
136 self.AddMenuItem(fileMenu, 'E&xit\tAlt-X', 'Exit', self.OnFileExit)
137 menu.Append(fileMenu, 'File')
138
139 def AddEditMenu(self, menu):
2571247b 140 editMenu = wx.Menu()
1918b6f7
RD
141 self.AddMenuItem(editMenu, 'Cut\tCtrl-X', 'Cut', self.edl.OnCutSelection)
142 self.AddMenuItem(editMenu, '&Copy\tCtrl-C', 'Copy', self.edl.OnCopySelection)
143 self.AddMenuItem(editMenu, 'Paste\tCtrl-V', 'Paste', self.edl.OnPaste)
144 self.AddMenuItem(editMenu, 'Edit preferences', 'Edit Preferences', self.OnEditPreferences)
145 menu.Append(editMenu, 'Edit')
146
147 def AddHelpMenu(self, menu):
2571247b 148 helpMenu = wx.Menu()
1918b6f7
RD
149 self.AddMenuItem(helpMenu, 'About', 'About the program', self.OnHelpAbout)
150 menu.Append(helpMenu, 'Help')
151
152##---------------- Init Buttons
153
154
155 def NewButton(self, window, container, name, pos, size, handler):
2571247b 156 buttonId = wx.NewId()
1918b6f7 157 if pos == None or size == None:
2571247b 158 container.Add(wx.Button(window, buttonId, name), 0, 0)
1918b6f7 159 else:
2571247b
RD
160 container.Add(wx.Button(window, buttonId, name, pos, size), 0, 0)
161 self.Bind(wx.EVT_BUTTON, handler, id=buttonId)
1918b6f7
RD
162 return buttonId
163
164 # override this to make more buttons
165 def AddButtons(self, window, container):
166 buttonPos = None
167 buttonSize = None
168 self.NewButton(window, container, "New", buttonPos, buttonSize, self.OnNewFile)
169 self.NewButton(window, container, "Open", buttonPos, buttonSize, self.OnOpenFile)
170 self.NewButton(window, container, "Save", buttonPos, buttonSize, self.OnSaveFile)
171
172
173##-------------- Init Dialogs
174
175 def MessageDialog(self, text, title):
2571247b 176 messageDialog = wx.MessageDialog(self, text, title, wx.OK | wx.ICON_INFORMATION)
1918b6f7
RD
177 messageDialog.ShowModal()
178 messageDialog.Destroy()
78e8819c 179
1918b6f7 180 def OkCancelDialog(self, text, title):
2571247b 181 dialog = wx.MessageDialog(self, text, title, wx.OK | wx.CANCEL | wx.ICON_INFORMATION)
1918b6f7
RD
182 result = dialog.ShowModal()
183 dialog.Destroy()
2571247b 184 if result == wx.ID_OK:
1e4a197e 185 return True
1918b6f7 186 else:
1e4a197e 187 return False
1918b6f7
RD
188
189 def SelectFileDialog(self, defaultDir=None, defaultFile=None, wildCard=None):
190 if defaultDir == None:
191 defaultDir = "."
192 if defaultFile == None:
193 defaultFile = ""
194 if wildCard == None:
195 wildCard = "*.*"
196 fileName = None
2571247b 197 fileDialog = wx.FileDialog(self, "Choose a file", defaultDir, defaultFile, wildCard, wx.OPEN|wx.MULTIPLE)
78e8819c 198 result = fileDialog.ShowModal()
2571247b 199 if result == wx.ID_OK:
1918b6f7 200 fileName = fileDialog.GetPath()
2571247b 201 wx.LogMessage('You selected: %s\n' % fileName)
78e8819c 202 fileDialog.Destroy()
1918b6f7
RD
203 return fileName
204
205 def OpenFileError(self, fileName):
2571247b 206 wx.LogMessage('Open file error.')
1918b6f7
RD
207 self.MessageDialog("Error opening file '%s'!" % fileName, "Error")
208
209
210 def SaveFileError(self, fileName):
2571247b 211 wx.LogMessage('Save file error.')
1918b6f7
RD
212 self.MessageDialog("Error saving file '%s'!" % fileName, "Error")
213
214##---------------- Utility functions
215
216
217 def SetControlFuncs(self, action):
218 "for overriding editor's keys"
219 FrogEditor.SetControlFuncs(self.edl, action)
220 action['a'] = self.OnSaveFileAs
221 action['o'] = self.OnOpenFile
222 action['n'] = self.OnNewFile
223 action['s'] = self.OnSaveFile
224
225 def SetAltFuncs(self, action):
226 FrogEditor.SetAltFuncs(self.edl, action)
78e8819c 227 action['x'] = self.OnFileExit
1918b6f7
RD
228
229 def GetCurrentDir(self):
230 if self.fileName is not None:
231 return os.path.split(self.fileName)[0]
232 return "."
78e8819c 233
1918b6f7
RD
234 def GetFileName(self):
235 if self.fileName is not None:
236 return os.path.split(self.fileName)[1]
237 return ""
238
239 def NewFile(self):
240 self.edl.SetText([""])
241 self.fileName = None
242 self.sb.setFileName("")
243
244 def SaveFile(self, fileName):
245 try:
246 contents = string.join(self.edl.GetText(), '\n')
247 f = open(fileName, 'w')
248 f.write(contents)
249 f.close()
250 self.edl.UnTouchBuffer()
251 self.sb.setFileName(fileName)
1e4a197e 252 return True
1918b6f7 253 except:
1e4a197e 254 return False
1918b6f7
RD
255
256 def OpenFile(self, fileName):
257 try:
258 f = open(fileName, 'r')
259 contents = f.readlines()
260 f.close()
261 contents = [chomp(line) for line in contents]
262 if len(contents) == 0:
263 contents = [""]
264 self.edl.SetText(contents)
265 self.fileName = fileName
266 self.sb.setFileName(fileName)
1e4a197e 267 return True
1918b6f7 268 except:
1e4a197e 269 return False
78e8819c 270
1918b6f7
RD
271
272
273##---------------- Event handlers
274
275
276 def OnCloseWindow(self, event):
277 self.edl.OnCloseWindow(event)
278 self.Destroy()
279
280 def OnNewFile(self, event):
281 if self.edl.BufferWasTouched():
282 if not self.OkCancelDialog("New file - abandon changes?", "New File"):
283 return
284 self.NewFile()
285 self.edl.SetFocus()
78e8819c 286
1918b6f7
RD
287 def OnOpenFile(self, event):
288 if self.edl.BufferWasTouched():
289 if not self.OkCancelDialog("Open file - abandon changes?", "Open File"):
290 return
291 fileName = self.SelectFileDialog(self.GetCurrentDir())
292 if fileName is not None:
1e4a197e 293 if self.OpenFile(fileName) is False:
1918b6f7
RD
294 self.OpenFileError(fileName)
295 self.edl.SetFocus()
78e8819c 296
1918b6f7
RD
297 def OnSaveFile(self, event):
298 if self.fileName is None:
299 return self.OnSaveFileAs(event)
2571247b 300 wx.LogMessage("Saving %s..." % self.fileName)
1e4a197e 301 if self.SaveFile(self.fileName) is not True:
1918b6f7
RD
302 self.SaveFileError(self.fileName)
303 self.edl.SetFocus()
78e8819c 304
1918b6f7
RD
305 def OnSaveFileAs(self, event):
306 fileName = self.SelectFileDialog(self.GetCurrentDir(),self.GetFileName())
307 if fileName is not None:
308 self.fileName = fileName
2571247b 309 wx.LogMessage("Saving %s..." % self.fileName)
1e4a197e 310 if self.SaveFile(self.fileName) is not True:
1918b6f7
RD
311 self.SaveFileError(self.fileName)
312 self.edl.SetFocus()
78e8819c
RD
313
314 def OnFileExit(self, event):
1918b6f7
RD
315 if self.edl.BufferWasTouched():
316 if not self.OkCancelDialog("Exit program - abandon changes?", "Exit"):
317 return
318 self.OnCloseWindow(event)
319
320 def OnEditPreferences(self, event):
321 self.MessageDialog("Edit preferences is not implemented yet.", "Not implemented.")
322 pass
78e8819c 323
1918b6f7
RD
324 def OnHelpAbout(self, event):
325 self.MessageDialog(ABOUT_TEXT, "About FrogEdit")
326 pass
78e8819c 327
1918b6f7 328 def Show(self, show):
2571247b 329 wx.Frame.Show(self, show)
1918b6f7
RD
330 self.edl.SetFocus()
331
332##------------- Startup stuff
333
334 def LoadInitialFile(self, fileName):
335 if fileName is not None:
1e4a197e 336 if self.OpenFile(fileName) is False:
78e8819c 337 self.OpenFileError(fileName)
1918b6f7
RD
338
339
340
341
342##-------------- Application Launcher utility class
343
344class FrogEditLauncher:
345
346 def MakeAppFrame(self):
347 return FrogEditFrame(None, -1, "FrogEdit", size=(640, 480),
2571247b 348 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
78e8819c 349
1918b6f7
RD
350 def GetArgvFilename(self):
351 if len(sys.argv) > 1:
352 return sys.argv[1]
353 else:
354 return None
355
356 def Main(self):
2571247b 357 app = wx.PySimpleApp()
78e8819c 358 win = self.MakeAppFrame()
1e4a197e 359 win.Show(True)
1918b6f7
RD
360 win.LoadInitialFile(self.GetArgvFilename())
361 app.MainLoop()
362
363
364##-------------- Main program
365
366
367if __name__ == '__main__':
368
369 launcher = FrogEditLauncher()
370 launcher.Main()