]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/wxProject/wxProject.py
Revert last change, it causes problems with not being able to use
[wxWidgets.git] / wxPython / samples / wxProject / wxProject.py
CommitLineData
7153b2cb
RD
1#!/usr/bin/env python
2
3"""
4This sample comes from an IBM developerWorks article at
5http://www-106.ibm.com/developerworks/library/l-wxpy/index.html
6
7This small program was adapted to demonstrate the current guide lines
8on http://wiki.wxpython.org/index.cgi/wxPython_20Style_20Guide.
9Changes are noted in readme.txt.
10"""
11
c12bc4de 12import sys, os
7153b2cb
RD
13import wx
14
c12bc4de
RD
15
16# Process the command line. Not much to do;
17# just get the name of the project file if it's given. Simple.
18projfile = 'Unnamed'
19if len(sys.argv) > 1:
7153b2cb 20 projfile = sys.argv[1]
c12bc4de
RD
21
22
7153b2cb
RD
23def MsgDlg(window, string, caption='wxProject', style=wx.YES_NO|wx.CANCEL):
24 """Common MessageDialog."""
25 dlg = wx.MessageDialog(window, string, caption, style)
26 result = dlg.ShowModal()
c12bc4de 27 dlg.Destroy()
7153b2cb
RD
28 return result
29
c12bc4de 30
7153b2cb
RD
31class main_window(wx.Frame):
32 """wxProject MainFrame."""
33 def __init__(self, parent, title):
34 """Create the wxProject MainFrame."""
35 wx.Frame.__init__(self, parent, title=title, size=(500, 500),
36 style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
c12bc4de
RD
37
38
c12bc4de 39 # Set up menu bar for the program.
7153b2cb 40 self.mainmenu = wx.MenuBar() # Create menu bar.
c12bc4de 41
7153b2cb
RD
42 # Make the 'Project' menu.
43 menu = wx.Menu()
c12bc4de 44
7153b2cb
RD
45 item = menu.Append(wx.ID_OPEN, '&Open', 'Open project') # Append a new menu
46 self.Bind(wx.EVT_MENU, self.OnProjectOpen, item) # Create and assign a menu event.
c12bc4de 47
7153b2cb
RD
48 item = menu.Append(wx.ID_NEW, '&New', 'New project')
49 self.Bind(wx.EVT_MENU, self.OnProjectNew, item)
c12bc4de 50
7153b2cb
RD
51 item = menu.Append(wx.ID_EXIT, 'E&xit', 'Exit program')
52 self.Bind(wx.EVT_MENU, self.OnProjectExit, item)
c12bc4de 53
7153b2cb 54 self.mainmenu.Append(menu, '&Project') # Add the project menu to the menu bar.
c12bc4de 55
7153b2cb
RD
56 # Make the 'File' menu.
57 menu = wx.Menu()
c12bc4de 58
7153b2cb
RD
59 item = menu.Append(wx.ID_ANY, '&Add', 'Add file to project')
60 self.Bind(wx.EVT_MENU, self.OnFileAdd, item)
c12bc4de 61
7153b2cb
RD
62 item = menu.Append(wx.ID_ANY, '&Remove', 'Remove file from project')
63 self.Bind(wx.EVT_MENU, self.OnFileRemove, item)
c12bc4de 64
7153b2cb
RD
65 item = menu.Append(wx.ID_ANY, '&Open', 'Open file for editing')
66 self.Bind(wx.EVT_MENU, self.OnFileOpen, item)
67
68 item = menu.Append(wx.ID_ANY, '&Save', 'Save file')
69 self.Bind(wx.EVT_MENU, self.OnFileSave, item)
70
71 self.mainmenu.Append(menu, '&File') # Add the file menu to the menu bar.
72
73 # Attach the menu bar to the window.
74 self.SetMenuBar(self.mainmenu)
c12bc4de 75
c12bc4de 76 # Create the splitter window.
7153b2cb
RD
77 splitter = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
78 splitter.SetMinimumPaneSize(1)
c12bc4de 79
c12bc4de 80 # Create the tree on the left.
7153b2cb
RD
81 self.tree = wx.TreeCtrl(splitter, style=wx.TR_DEFAULT_STYLE)
82 self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeLabelEdit)
83 self.tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeLabelEditEnd)
84 self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTreeItemActivated)
85
c12bc4de 86 # Create the editor on the right.
7153b2cb
RD
87 self.editor = wx.TextCtrl(splitter, style=wx.TE_MULTILINE)
88 self.editor.Enable(0)
c12bc4de 89
c12bc4de 90 # Install the tree and the editor.
7153b2cb
RD
91 splitter.SplitVertically(self.tree, self.editor)
92 splitter.SetSashPosition(180, True)
c12bc4de
RD
93
94 # Some global state variables.
1e4a197e 95 self.projectdirty = False
7153b2cb
RD
96 self.root = None
97 self.close = False
98
99 self.Bind(wx.EVT_CLOSE, self.OnProjectExit)
100
101 self.Show(True)
c12bc4de
RD
102
103 # ----------------------------------------------------------------------------------------
104 # Some nice little handlers.
105 # ----------------------------------------------------------------------------------------
106
c12bc4de 107 def project_open(self, project_file):
7153b2cb 108 """Open and process a wxProject file."""
c12bc4de 109 try:
7153b2cb 110 input = open(project_file, 'r')
c12bc4de
RD
111 self.tree.DeleteAllItems()
112
113 self.project_file = project_file
7153b2cb
RD
114 name = input.readline().replace ('\n', '')
115 self.SetTitle(name)
116
117 # create the file elements in the tree control.
c12bc4de
RD
118 self.root = self.tree.AddRoot(name)
119 self.activeitem = self.root
120 for line in input.readlines():
7153b2cb
RD
121 self.tree.AppendItem(self.root, line.replace ('\n', ''))
122 input.close()
123 self.tree.Expand(self.root)
c12bc4de
RD
124
125 self.editor.Clear()
7153b2cb 126 self.editor.Enable(False)
c12bc4de 127
1e4a197e 128 self.projectdirty = False
c12bc4de
RD
129 except IOError:
130 pass
131
132 def project_save(self):
7153b2cb 133 """Save a wxProject file."""
c12bc4de 134 try:
7153b2cb
RD
135 output = open(self.project_file, 'w+')
136 output.write(self.tree.GetItemText(self.root) + '\n')
137 count = self.tree.GetChildrenCount(self.root) # collect all file (tree) items.
c12bc4de
RD
138 iter = 0
139 child = ''
140 for i in range(count):
141 if i == 0:
7153b2cb 142 child, cookie = self.tree.GetFirstChild(self.root)
c12bc4de 143 else:
7153b2cb
RD
144 child, cookie = self.tree.GetNextChild(self.root, cookie)
145 output.write(self.tree.GetItemText(child) + '\n')
c12bc4de 146 output.close()
1e4a197e 147 self.projectdirty = False
c12bc4de 148 except IOError:
7153b2cb
RD
149 MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
150
151 def CheckProjectDirty(self):
152 """Were the current project changed? If so, save it before."""
153 open_it = True
154 if self.projectdirty:
155 # save the current project file first.
156 result = MsgDlg(self, 'The project has been changed. Save?')
157 if result == wx.ID_YES:
158 self.project_save()
159 if result == wx.ID_CANCEL:
160 open_it = False
161 return open_it
162
163 def CheckTreeRootItem(self):
164 """Is there any root item?"""
165 if not self.root:
166 MsgDlg(self, 'Please create or open a project before.', 'Error!', wx.OK)
167 return False
168 return True
c12bc4de
RD
169
170 # ----------------------------------------------------------------------------------------
171 # Event handlers from here on out.
172 # ----------------------------------------------------------------------------------------
173
174 def OnProjectOpen(self, event):
7153b2cb
RD
175 """Open a wxProject file."""
176 open_it = self.CheckProjectDirty()
c12bc4de 177 if open_it:
7153b2cb
RD
178 dlg = wx.FileDialog(self, 'Choose a project to open', '.', '', '*.wxp', wx.OPEN)
179 if dlg.ShowModal() == wx.ID_OK:
180 self.project_open(dlg.GetPath())
181 dlg.Destroy()
c12bc4de
RD
182
183 def OnProjectNew(self, event):
7153b2cb
RD
184 """Create a new wxProject."""
185 open_it = self.CheckProjectDirty()
c12bc4de 186 if open_it:
7153b2cb
RD
187 dlg = wx.TextEntryDialog(self, 'Name for new project:', 'New Project',
188 'New project', wx.OK|wx.CANCEL)
189 if dlg.ShowModal() == wx.ID_OK:
190 newproj = dlg.GetValue()
191 dlg.Destroy()
192 dlg = wx.FileDialog(self, 'Place to store new project.', '.', '', '*.wxp', wx.SAVE)
193 if dlg.ShowModal() == wx.ID_OK:
194 try:
195 # save the project file.
196 proj = open(dlg.GetPath(), 'w')
197 proj.write(newproj + '\n')
198 proj.close()
199 self.project_open(dlg.GetPath())
200 except IOError:
201 MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
202 dlg.Destroy()
203
204 def SaveCurrentFile(self):
205 """Check and save current file."""
206 go_ahead = True
207 if self.root:
208 if self.activeitem != self.root:
209 if self.editor.IsModified(): # Save modified file before
210 result = MsgDlg(self, 'The edited file has changed. Save it?')
211 if result == wx.ID_YES:
212 self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
213 if result == wx.ID_CANCEL:
214 go_ahead = False
215 if go_ahead:
216 self.tree.SetItemBold(self.activeitem, 0)
217 return go_ahead
c12bc4de
RD
218
219 def OnProjectExit(self, event):
7153b2cb
RD
220 """Quit the program."""
221 if not self.close:
222 self.close = True
223 if not self.SaveCurrentFile():
224 self.close = False
225 if self.projectdirty and self.close:
226 result = MsgDlg(self, 'The project has been changed. Save?')
227 if result == wx.ID_YES:
228 self.project_save()
229 if result == wx.ID_CANCEL:
230 self.close = False
231 if self.close:
232 self.Close()
233 else:
234 event.Skip()
c12bc4de
RD
235
236 def OnFileAdd(self, event):
7153b2cb
RD
237 """Adds a file to the current project."""
238 if not self.CheckTreeRootItem():
239 return
240
241 dlg = wx.FileDialog(self, 'Choose a file to add.', '.', '', '*.*', wx.OPEN)
242 if dlg.ShowModal() == wx.ID_OK:
243 path = os.path.split(dlg.GetPath())
244 self.tree.AppendItem(self.root, path[1])
245 self.tree.Expand(self.root)
246 self.project_save()
c12bc4de
RD
247
248 def OnFileRemove(self, event):
7153b2cb
RD
249 """Removes a file to the current project."""
250 if not self.CheckTreeRootItem():
251 return
c12bc4de
RD
252 item = self.tree.GetSelection()
253 if item != self.root:
7153b2cb
RD
254 self.tree.Delete(item)
255 self.project_save()
c12bc4de
RD
256
257 def OnFileOpen(self, event):
7153b2cb
RD
258 """Opens current selected file."""
259 if self.root:
260 item = self.tree.GetSelection()
261 if item != self.root:
262 self.OnTreeItemActivated(None, item)
263 return
264 MsgDlg(self, 'There is no file to load.', 'Error!', wx.OK)
c12bc4de
RD
265
266 def OnFileSave(self, event):
7153b2cb
RD
267 """Saves current selected file."""
268 if self.root:
269 if self.activeitem != self.root:
270 self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
271 return
272 MsgDlg(self, 'There is no file to save.', 'Error!', wx.OK)
c12bc4de
RD
273
274
275 def OnTreeLabelEdit(self, event):
7153b2cb
RD
276 """Edit tree label (only root label can be edited)."""
277 item = event.GetItem()
c12bc4de 278 if item != self.root:
7153b2cb 279 event.Veto()
c12bc4de
RD
280
281 def OnTreeLabelEditEnd(self, event):
7153b2cb 282 """End editing the tree label."""
1e4a197e 283 self.projectdirty = True
c12bc4de 284
7153b2cb
RD
285
286 def OnTreeItemActivated(self, event, item=None):
287 """Tree item was activated: try to open this file."""
288 go_ahead = self.SaveCurrentFile()
c12bc4de
RD
289
290 if go_ahead:
7153b2cb
RD
291 if event:
292 item = event.GetItem()
293 self.activeitem = item
294 if item != self.root:
295 # load the current selected file
296 self.tree.SetItemBold(item, 1)
297 self.editor.Enable(1)
298 self.editor.LoadFile(self.tree.GetItemText(item))
299 self.editor.SetInsertionPoint(0)
300 self.editor.SetFocus()
301 else:
302 self.editor.Clear()
303 self.editor.Enable(0)
304
305
306class App(wx.App):
307 """wxProject Application."""
c12bc4de 308 def OnInit(self):
7153b2cb
RD
309 """Create the wxProject Application."""
310 frame = main_window(None, 'wxProject - ' + projfile)
311 if projfile != 'Unnamed':
312 frame.project_open(projfile)
1e4a197e 313 return True
c12bc4de 314
c12bc4de 315
7153b2cb
RD
316if __name__ == '__main__':
317 app = App(0)
318 app.MainLoop()