]> git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/frogedit/FrogEdit.py
fixed wxVsnprintf() to write as much as it can if the output buffer is too short
[wxWidgets.git] / wxPython / samples / frogedit / FrogEdit.py
1 #!/usr/bin/env python
2
3 # simple text editor
4 #
5 # Copyright 2001 Adam Feuer and Steve Howell
6 #
7 # License: Python
8
9 import os
10 import re
11 import string
12 import sys
13
14 import wx
15
16 from StatusBar import *
17 from FrogEditor import FrogEditor
18
19
20 ABOUT_TEXT = """FrogEdit : Copyright 2001 Adam Feuer and Steve Howell
21 wxEditor component : Copyright 1999 - 2001 Dirk Holtwic, Robin Dunn, Adam Feuer, Steve Howell
22
23 FrogEdit was built using Python, wxPython, and wxWindows."""
24
25
26 ##---------------------------------------------------------------------
27
28 def chomp(line):
29 line = string.split(line,'\n')[0]
30 return string.split(line,'\r')[0]
31
32 ##---------------------------------------------------------------------
33
34 class OutlinerPanel(wx.Panel):
35
36 def Close(self, event):
37 self.parent.Close()
38 wx.Panel.Close(self)
39
40 ##----------------------------------------------------------------------
41
42
43 class FrogEditFrame(wx.Frame):
44 def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
45 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
46
47 wx.Frame.__init__(self, parent, ID, title, pos, size, style)
48
49 splitter = wx.SplitterWindow(self, -1, style=wx.NO_3D|wx.SP_3D)
50 win = OutlinerPanel(splitter, -1, style=wx.CLIP_CHILDREN)
51 win.parent = self
52 log = self.MakeLogWindow(splitter)
53
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
62 win.Layout()
63
64
65 ##------------- Init Misc
66
67 def RegisterEventHandlers(self):
68 self.Bind(wx.EVT_CLOSE,self.OnCloseWindow)
69
70 def InitVariables(self):
71 self.fileName = None
72 self.edl.UnTouchBuffer()
73
74 def MakeMenus(self):
75 self.MainMenu = wx.MenuBar()
76 self.AddMenus(self.MainMenu)
77 self.SetMenuBar(self.MainMenu)
78
79 ##------------- Init Subwindows
80
81 def MakeEditorWindow(self, win, log):
82 self.edl = FrogEditor(win, -1, style=wx.SUNKEN_BORDER, statusBar = self.sb)
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):
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())
96 return log
97
98 def SetUpSplitter(self, splitter, win, log):
99 splitter.SplitHorizontally(win, log)
100 splitter.SetSashPosition(360, True)
101 splitter.SetMinimumPaneSize(40)
102
103 def MakeToolbar(self, win):
104 toolbarBox = wx.BoxSizer(wx.HORIZONTAL)
105 self.AddButtons(win, toolbarBox)
106 return toolbarBox
107
108 def MakeMainWindow(self, win):
109 mainBox = wx.BoxSizer(wx.VERTICAL)
110 mainBox.Add(self.MakeToolbar(win))
111 borderWidth = 5
112 mainBox.Add(self.edl, 1, wx.ALL|wx.GROW, borderWidth)
113 win.SetSizer(mainBox)
114 win.SetAutoLayout(True)
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):
125 menuId = wx.NewId()
126 menu.Append(menuId, itemText, itemDescription)
127 self.Bind(wx.EVT_MENU, itemHandler, id=menuId)
128 return menuId
129
130 def AddFileMenu(self, menu):
131 fileMenu = wx.Menu()
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):
140 editMenu = wx.Menu()
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):
148 helpMenu = wx.Menu()
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):
156 buttonId = wx.NewId()
157 if pos == None or size == None:
158 container.Add(wx.Button(window, buttonId, name), 0, 0)
159 else:
160 container.Add(wx.Button(window, buttonId, name, pos, size), 0, 0)
161 self.Bind(wx.EVT_BUTTON, handler, id=buttonId)
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):
176 messageDialog = wx.MessageDialog(self, text, title, wx.OK | wx.ICON_INFORMATION)
177 messageDialog.ShowModal()
178 messageDialog.Destroy()
179
180 def OkCancelDialog(self, text, title):
181 dialog = wx.MessageDialog(self, text, title, wx.OK | wx.CANCEL | wx.ICON_INFORMATION)
182 result = dialog.ShowModal()
183 dialog.Destroy()
184 if result == wx.ID_OK:
185 return True
186 else:
187 return False
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
197 fileDialog = wx.FileDialog(self, "Choose a file", defaultDir, defaultFile, wildCard, wx.OPEN|wx.MULTIPLE)
198 result = fileDialog.ShowModal()
199 if result == wx.ID_OK:
200 fileName = fileDialog.GetPath()
201 wx.LogMessage('You selected: %s\n' % fileName)
202 fileDialog.Destroy()
203 return fileName
204
205 def OpenFileError(self, fileName):
206 wx.LogMessage('Open file error.')
207 self.MessageDialog("Error opening file '%s'!" % fileName, "Error")
208
209
210 def SaveFileError(self, fileName):
211 wx.LogMessage('Save file error.')
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)
227 action['x'] = self.OnFileExit
228
229 def GetCurrentDir(self):
230 if self.fileName is not None:
231 return os.path.split(self.fileName)[0]
232 return "."
233
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)
252 return True
253 except:
254 return False
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)
267 return True
268 except:
269 return False
270
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()
286
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:
293 if self.OpenFile(fileName) is False:
294 self.OpenFileError(fileName)
295 self.edl.SetFocus()
296
297 def OnSaveFile(self, event):
298 if self.fileName is None:
299 return self.OnSaveFileAs(event)
300 wx.LogMessage("Saving %s..." % self.fileName)
301 if self.SaveFile(self.fileName) is not True:
302 self.SaveFileError(self.fileName)
303 self.edl.SetFocus()
304
305 def OnSaveFileAs(self, event):
306 fileName = self.SelectFileDialog(self.GetCurrentDir(),self.GetFileName())
307 if fileName is not None:
308 self.fileName = fileName
309 wx.LogMessage("Saving %s..." % self.fileName)
310 if self.SaveFile(self.fileName) is not True:
311 self.SaveFileError(self.fileName)
312 self.edl.SetFocus()
313
314 def OnFileExit(self, event):
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
323
324 def OnHelpAbout(self, event):
325 self.MessageDialog(ABOUT_TEXT, "About FrogEdit")
326 pass
327
328 def Show(self, show):
329 wx.Frame.Show(self, show)
330 self.edl.SetFocus()
331
332 ##------------- Startup stuff
333
334 def LoadInitialFile(self, fileName):
335 if fileName is not None:
336 if self.OpenFile(fileName) is False:
337 self.OpenFileError(fileName)
338
339
340
341
342 ##-------------- Application Launcher utility class
343
344 class FrogEditLauncher:
345
346 def MakeAppFrame(self):
347 return FrogEditFrame(None, -1, "FrogEdit", size=(640, 480),
348 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
349
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):
357 app = wx.PySimpleApp()
358 win = self.MakeAppFrame()
359 win.Show(True)
360 win.LoadInitialFile(self.GetArgvFilename())
361 app.MainLoop()
362
363
364 ##-------------- Main program
365
366
367 if __name__ == '__main__':
368
369 launcher = FrogEditLauncher()
370 launcher.Main()