-#!/bin/python
+#!/usr/bin/env python
+
+"""
+This sample comes from an IBM developerWorks article at
+http://www-106.ibm.com/developerworks/library/l-wxpy/index.html
+
+This small program was adapted to demonstrate the current guide lines
+on http://wiki.wxpython.org/index.cgi/wxPython_20Style_20Guide.
+Changes are noted in readme.txt.
+"""
+
import sys, os
-from wxPython.wx import *
-from string import *
+import wx
+
# Process the command line. Not much to do;
# just get the name of the project file if it's given. Simple.
projfile = 'Unnamed'
if len(sys.argv) > 1:
- projfile = sys.argv[1]
+ projfile = sys.argv[1]
-def MsgBox (window, string):
- dlg=wxMessageDialog(window, string, 'wxProject', wxOK)
- dlg.ShowModal()
+def MsgDlg(window, string, caption='wxProject', style=wx.YES_NO|wx.CANCEL):
+ """Common MessageDialog."""
+ dlg = wx.MessageDialog(window, string, caption, style)
+ result = dlg.ShowModal()
dlg.Destroy()
+ return result
+
-class main_window(wxFrame):
- def __init__(self, parent, id, title):
- wxFrame.__init__(self, parent, -1, title, size = (500, 500),
- style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
+class main_window(wx.Frame):
+ """wxProject MainFrame."""
+ def __init__(self, parent, title):
+ """Create the wxProject MainFrame."""
+ wx.Frame.__init__(self, parent, title=title, size=(500, 500),
+ style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
- # ------------------------------------------------------------------------------------
# Set up menu bar for the program.
- # ------------------------------------------------------------------------------------
- self.mainmenu = wxMenuBar() # Create menu bar.
- mainwindow = self
+ self.mainmenu = wx.MenuBar() # Create menu bar.
- menu=wxMenu() # Make a menu (will be the Project menu)
+ # Make the 'Project' menu.
+ menu = wx.Menu()
- exitID=wxNewId() # Make a new ID for a menu entry.
- menu.Append(exitID, '&Open', 'Open project') # Name the ID by adding it to the menu.
- EVT_MENU(self, exitID, self.OnProjectOpen) # Create and assign a menu event.
- exitID=wxNewId()
- menu.Append(exitID, '&New', 'New project')
- EVT_MENU(self, exitID, self.OnProjectNew)
- exitID=wxNewId()
- menu.Append(exitID, 'E&xit', 'Exit program')
- EVT_MENU(self, exitID, self.OnProjectExit)
+ item = menu.Append(wx.ID_OPEN, '&Open', 'Open project') # Append a new menu
+ self.Bind(wx.EVT_MENU, self.OnProjectOpen, item) # Create and assign a menu event.
- self.mainmenu.Append (menu, '&Project') # Add the project menu to the menu bar.
+ item = menu.Append(wx.ID_NEW, '&New', 'New project')
+ self.Bind(wx.EVT_MENU, self.OnProjectNew, item)
+ item = menu.Append(wx.ID_EXIT, 'E&xit', 'Exit program')
+ self.Bind(wx.EVT_MENU, self.OnProjectExit, item)
- menu=wxMenu() # Make a menu (will be the File menu)
+ self.mainmenu.Append(menu, '&Project') # Add the project menu to the menu bar.
- exitID=wxNewId()
- menu.Append(exitID, '&Add', 'Add file to project')
- EVT_MENU(self, exitID, self.OnFileAdd)
- exitID=wxNewId()
- menu.Append(exitID, '&Remove', 'Remove file from project')
- EVT_MENU(self, exitID, self.OnFileRemove)
- exitID=wxNewId()
- menu.Append(exitID, '&Open', 'Open file for editing')
- EVT_MENU(self, exitID, self.OnFileOpen)
- exitID=wxNewId()
- menu.Append(exitID, '&Save', 'Save file')
- EVT_MENU(self, exitID, self.OnFileSave)
+ # Make the 'File' menu.
+ menu = wx.Menu()
- self.mainmenu.Append (menu, '&File') # Add the file menu to the menu bar.
+ item = menu.Append(wx.ID_ANY, '&Add', 'Add file to project')
+ self.Bind(wx.EVT_MENU, self.OnFileAdd, item)
- self.SetMenuBar (self.mainmenu) # Attach the menu bar to the window.
+ item = menu.Append(wx.ID_ANY, '&Remove', 'Remove file from project')
+ self.Bind(wx.EVT_MENU, self.OnFileRemove, item)
+ item = menu.Append(wx.ID_ANY, '&Open', 'Open file for editing')
+ self.Bind(wx.EVT_MENU, self.OnFileOpen, item)
+
+ item = menu.Append(wx.ID_ANY, '&Save', 'Save file')
+ self.Bind(wx.EVT_MENU, self.OnFileSave, item)
+
+ self.mainmenu.Append(menu, '&File') # Add the file menu to the menu bar.
+
+ # Attach the menu bar to the window.
+ self.SetMenuBar(self.mainmenu)
- # ------------------------------------------------------------------------------------
# Create the splitter window.
- # ------------------------------------------------------------------------------------
- splitter = wxSplitterWindow (self, -1, style=wxNO_3D|wxSP_3D)
- splitter.SetMinimumPaneSize (1)
+ splitter = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
+ splitter.SetMinimumPaneSize(1)
- # ------------------------------------------------------------------------------------
# Create the tree on the left.
- # ------------------------------------------------------------------------------------
- tID = wxNewId()
- self.tree = wxTreeCtrl (splitter, tID, style=wxTR_HAS_BUTTONS |
- wxTR_EDIT_LABELS |
- wxTR_HAS_VARIABLE_ROW_HEIGHT)
- EVT_TREE_BEGIN_LABEL_EDIT(self.tree, tID, self.OnTreeLabelEdit)
- EVT_TREE_END_LABEL_EDIT(self.tree, tID, self.OnTreeLabelEditEnd)
- EVT_TREE_ITEM_ACTIVATED(self.tree, tID, self.OnTreeItemActivated)
-
- # ------------------------------------------------------------------------------------
+ self.tree = wx.TreeCtrl(splitter, style=wx.TR_DEFAULT_STYLE)
+ self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeLabelEdit)
+ self.tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeLabelEditEnd)
+ self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTreeItemActivated)
+
# Create the editor on the right.
- # ------------------------------------------------------------------------------------
- self.editor = wxTextCtrl(splitter, -1, style=wxTE_MULTILINE)
- self.editor.Enable (0)
+ self.editor = wx.TextCtrl(splitter, style=wx.TE_MULTILINE)
+ self.editor.Enable(0)
- # ------------------------------------------------------------------------------------
# Install the tree and the editor.
- # ------------------------------------------------------------------------------------
- splitter.SplitVertically (self.tree, self.editor)
- splitter.SetSashPosition (180, True)
-
- self.Show(True)
+ splitter.SplitVertically(self.tree, self.editor)
+ splitter.SetSashPosition(180, True)
# Some global state variables.
self.projectdirty = False
+ self.root = None
+ self.close = False
+
+ self.Bind(wx.EVT_CLOSE, self.OnProjectExit)
+
+ self.Show(True)
# ----------------------------------------------------------------------------------------
# Some nice little handlers.
# ----------------------------------------------------------------------------------------
-
def project_open(self, project_file):
+ """Open and process a wxProject file."""
try:
- input = open (project_file, 'r')
-
+ input = open(project_file, 'r')
self.tree.DeleteAllItems()
self.project_file = project_file
- name = replace (input.readline(), "\n", "")
- self.SetTitle (name)
+ name = input.readline().replace ('\n', '')
+ self.SetTitle(name)
+
+ # create the file elements in the tree control.
self.root = self.tree.AddRoot(name)
self.activeitem = self.root
for line in input.readlines():
- self.tree.AppendItem (self.root, replace(line, "\n", ""))
- input.close
- self.tree.Expand (self.root)
+ self.tree.AppendItem(self.root, line.replace ('\n', ''))
+ input.close()
+ self.tree.Expand(self.root)
self.editor.Clear()
- self.editor.Enable (False)
+ self.editor.Enable(False)
self.projectdirty = False
except IOError:
pass
def project_save(self):
+ """Save a wxProject file."""
try:
- output = open (self.project_file, 'w+')
- output.write (self.tree.GetItemText (self.root) + "\n")
-
- count = self.tree.GetChildrenCount (self.root)
+ output = open(self.project_file, 'w+')
+ output.write(self.tree.GetItemText(self.root) + '\n')
+ count = self.tree.GetChildrenCount(self.root) # collect all file (tree) items.
iter = 0
child = ''
for i in range(count):
if i == 0:
- (child,iter) = self.tree.GetFirstChild(self.root,iter)
+ child, cookie = self.tree.GetFirstChild(self.root)
else:
- (child,iter) = self.tree.GetNextChild(self.root,iter)
- output.write (self.tree.GetItemText(child) + "\n")
+ child, cookie = self.tree.GetNextChild(self.root, cookie)
+ output.write(self.tree.GetItemText(child) + '\n')
output.close()
self.projectdirty = False
except IOError:
- dlg_m = wxMessageDialog (self, 'There was an error saving the project file.',
- 'Error!', wxOK)
- dlg_m.ShowModal()
- dlg_m.Destroy()
+ MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
+
+ def CheckProjectDirty(self):
+ """Were the current project changed? If so, save it before."""
+ open_it = True
+ if self.projectdirty:
+ # save the current project file first.
+ result = MsgDlg(self, 'The project has been changed. Save?')
+ if result == wx.ID_YES:
+ self.project_save()
+ if result == wx.ID_CANCEL:
+ open_it = False
+ return open_it
+
+ def CheckTreeRootItem(self):
+ """Is there any root item?"""
+ if not self.root:
+ MsgDlg(self, 'Please create or open a project before.', 'Error!', wx.OK)
+ return False
+ return True
# ----------------------------------------------------------------------------------------
# Event handlers from here on out.
# ----------------------------------------------------------------------------------------
def OnProjectOpen(self, event):
- open_it = True
- if self.projectdirty:
- dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject',
- wxYES_NO | wxCANCEL)
- result = dlg.ShowModal()
- if result == wxID_YES:
- self.project_save()
- if result == wxID_CANCEL:
- open_it = False
- dlg.Destroy()
+ """Open a wxProject file."""
+ open_it = self.CheckProjectDirty()
if open_it:
- dlg = wxFileDialog(self, "Choose a project to open", ".", "", "*.wxp", wxOPEN)
- if dlg.ShowModal() == wxID_OK:
- self.project_open(dlg.GetPath())
- dlg.Destroy()
+ dlg = wx.FileDialog(self, 'Choose a project to open', '.', '', '*.wxp', wx.OPEN)
+ if dlg.ShowModal() == wx.ID_OK:
+ self.project_open(dlg.GetPath())
+ dlg.Destroy()
def OnProjectNew(self, event):
- open_it = True
- if self.projectdirty:
- dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject',
- wxYES_NO | wxCANCEL)
- result = dlg.ShowModal()
- if result == wxID_YES:
- self.project_save()
- if result == wxID_CANCEL:
- open_it = False
- dlg.Destroy()
-
+ """Create a new wxProject."""
+ open_it = self.CheckProjectDirty()
if open_it:
- dlg = wxTextEntryDialog (self, "Name for new project:", "New Project",
- "New project", wxOK | wxCANCEL)
- if dlg.ShowModal() == wxID_OK:
- newproj = dlg.GetValue()
- dlg.Destroy()
- dlg = wxFileDialog (self, "Place to store new project", ".", "", "*.wxp",
- wxSAVE)
- if dlg.ShowModal() == wxID_OK:
- try:
- proj = open (dlg.GetPath(), 'w')
- proj.write (newproj + "\n")
- proj.close()
- self.project_open (dlg.GetPath())
- except IOError:
- dlg_m = wxMessageDialog (self,
- 'There was an error saving the new project file.',
- 'Error!', wxOK)
- dlg_m.ShowModal()
- dlg_m.Destroy()
- dlg.Destroy()
+ dlg = wx.TextEntryDialog(self, 'Name for new project:', 'New Project',
+ 'New project', wx.OK|wx.CANCEL)
+ if dlg.ShowModal() == wx.ID_OK:
+ newproj = dlg.GetValue()
+ dlg.Destroy()
+ dlg = wx.FileDialog(self, 'Place to store new project.', '.', '', '*.wxp', wx.SAVE)
+ if dlg.ShowModal() == wx.ID_OK:
+ try:
+ # save the project file.
+ proj = open(dlg.GetPath(), 'w')
+ proj.write(newproj + '\n')
+ proj.close()
+ self.project_open(dlg.GetPath())
+ except IOError:
+ MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
+ dlg.Destroy()
+
+ def SaveCurrentFile(self):
+ """Check and save current file."""
+ go_ahead = True
+ if self.root:
+ if self.activeitem != self.root:
+ if self.editor.IsModified(): # Save modified file before
+ result = MsgDlg(self, 'The edited file has changed. Save it?')
+ if result == wx.ID_YES:
+ self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
+ if result == wx.ID_CANCEL:
+ go_ahead = False
+ if go_ahead:
+ self.tree.SetItemBold(self.activeitem, 0)
+ return go_ahead
def OnProjectExit(self, event):
- close = True
- if self.projectdirty:
- dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject',
- wxYES_NO | wxCANCEL)
- result = dlg.ShowModal()
- if result == wxID_YES:
- self.project_save()
- if result == wxID_CANCEL:
- close = False
- dlg.Destroy()
- if close:
- self.Close()
+ """Quit the program."""
+ if not self.close:
+ self.close = True
+ if not self.SaveCurrentFile():
+ self.close = False
+ if self.projectdirty and self.close:
+ result = MsgDlg(self, 'The project has been changed. Save?')
+ if result == wx.ID_YES:
+ self.project_save()
+ if result == wx.ID_CANCEL:
+ self.close = False
+ if self.close:
+ self.Close()
+ else:
+ event.Skip()
def OnFileAdd(self, event):
- dlg = wxFileDialog (self, "Choose a file to add", ".", "", "*.*", wxOPEN)
- if dlg.ShowModal() == wxID_OK:
- path = os.path.split(dlg.GetPath())
- self.tree.AppendItem (self.root, path[1])
- self.tree.Expand (self.root)
- self.project_save()
+ """Adds a file to the current project."""
+ if not self.CheckTreeRootItem():
+ return
+
+ dlg = wx.FileDialog(self, 'Choose a file to add.', '.', '', '*.*', wx.OPEN)
+ if dlg.ShowModal() == wx.ID_OK:
+ path = os.path.split(dlg.GetPath())
+ self.tree.AppendItem(self.root, path[1])
+ self.tree.Expand(self.root)
+ self.project_save()
def OnFileRemove(self, event):
+ """Removes a file to the current project."""
+ if not self.CheckTreeRootItem():
+ return
item = self.tree.GetSelection()
if item != self.root:
- self.tree.Delete (item)
- self.project_save()
+ self.tree.Delete(item)
+ self.project_save()
def OnFileOpen(self, event):
- item = self.tree.GetSelection()
+ """Opens current selected file."""
+ if self.root:
+ item = self.tree.GetSelection()
+ if item != self.root:
+ self.OnTreeItemActivated(None, item)
+ return
+ MsgDlg(self, 'There is no file to load.', 'Error!', wx.OK)
def OnFileSave(self, event):
- if self.activeitem != self.root:
- self.editor.SaveFile (self.tree.GetItemText (self.activeitem))
+ """Saves current selected file."""
+ if self.root:
+ if self.activeitem != self.root:
+ self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
+ return
+ MsgDlg(self, 'There is no file to save.', 'Error!', wx.OK)
def OnTreeLabelEdit(self, event):
- item=event.GetItem()
+ """Edit tree label (only root label can be edited)."""
+ item = event.GetItem()
if item != self.root:
- event.Veto()
+ event.Veto()
def OnTreeLabelEditEnd(self, event):
+ """End editing the tree label."""
self.projectdirty = True
- def OnTreeItemActivated(self, event):
- go_ahead = True
- if self.activeitem != self.root:
- if self.editor.IsModified():
- dlg=wxMessageDialog(self, 'The edited file has changed. Save it?',
- 'wxProject', wxYES_NO | wxCANCEL)
- result = dlg.ShowModal()
- if result == wxID_YES:
- self.editor.SaveFile (self.tree.GetItemText (self.activeitem))
- if result == wxID_CANCEL:
- go_ahead = False
- dlg.Destroy()
- if go_ahead:
- self.tree.SetItemBold (self.activeitem, 0)
+
+ def OnTreeItemActivated(self, event, item=None):
+ """Tree item was activated: try to open this file."""
+ go_ahead = self.SaveCurrentFile()
if go_ahead:
- item=event.GetItem()
- self.activeitem = item
- if item != self.root:
- self.tree.SetItemBold (item, 1)
- self.editor.Enable (1)
- self.editor.LoadFile (self.tree.GetItemText(item))
- self.editor.SetInsertionPoint (0)
- self.editor.SetFocus()
- else:
- self.editor.Clear()
- self.editor.Enable (0)
-
-class App(wxApp):
+ if event:
+ item = event.GetItem()
+ self.activeitem = item
+ if item != self.root:
+ # load the current selected file
+ self.tree.SetItemBold(item, 1)
+ self.editor.Enable(1)
+ self.editor.LoadFile(self.tree.GetItemText(item))
+ self.editor.SetInsertionPoint(0)
+ self.editor.SetFocus()
+ else:
+ self.editor.Clear()
+ self.editor.Enable(0)
+
+
+class App(wx.App):
+ """wxProject Application."""
def OnInit(self):
- frame = main_window(None, -1, "wxProject - " + projfile)
- self.SetTopWindow(frame)
- if (projfile != 'Unnamed'):
- frame.project_open (projfile)
+ """Create the wxProject Application."""
+ frame = main_window(None, 'wxProject - ' + projfile)
+ if projfile != 'Unnamed':
+ frame.project_open(projfile)
return True
-app = App(0)
-app.MainLoop()
+if __name__ == '__main__':
+ app = App(0)
+ app.MainLoop()