wxWidgets/wxPython/samples/wxProject/wxProject.py
2006-02-09 15:37:39 +00:00

319 lines
11 KiB
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
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]
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(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 = wx.MenuBar() # Create menu bar.
# Make the 'Project' menu.
menu = wx.Menu()
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.
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)
self.mainmenu.Append(menu, '&Project') # Add the project menu to the menu bar.
# Make the 'File' menu.
menu = wx.Menu()
item = menu.Append(wx.ID_ANY, '&Add', 'Add file to project')
self.Bind(wx.EVT_MENU, self.OnFileAdd, item)
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 = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
splitter.SetMinimumPaneSize(1)
# Create the tree on the left.
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 = 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)
# 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')
self.tree.DeleteAllItems()
self.project_file = project_file
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, line.replace ('\n', ''))
input.close()
self.tree.Expand(self.root)
self.editor.Clear()
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) # collect all file (tree) items.
iter = 0
child = ''
for i in range(count):
if i == 0:
child, cookie = self.tree.GetFirstChild(self.root)
else:
child, cookie = self.tree.GetNextChild(self.root, cookie)
output.write(self.tree.GetItemText(child) + '\n')
output.close()
self.projectdirty = False
except IOError:
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 a wxProject file."""
open_it = self.CheckProjectDirty()
if open_it:
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):
"""Create a new wxProject."""
open_it = self.CheckProjectDirty()
if open_it:
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):
"""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):
"""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()
def OnFileOpen(self, event):
"""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):
"""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):
"""Edit tree label (only root label can be edited)."""
item = event.GetItem()
if item != self.root:
event.Veto()
def OnTreeLabelEditEnd(self, event):
"""End editing the tree label."""
self.projectdirty = True
def OnTreeItemActivated(self, event, item=None):
"""Tree item was activated: try to open this file."""
go_ahead = self.SaveCurrentFile()
if go_ahead:
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):
"""Create the wxProject Application."""
frame = main_window(None, 'wxProject - ' + projfile)
if projfile != 'Unnamed':
frame.project_open(projfile)
return True
if __name__ == '__main__':
app = App(0)
app.MainLoop()