# main.py: Main wxGlade module: defines wxGladeFrame which contains the buttons
# to add widgets and initializes all the stuff (tree, property_frame, etc.)
# $Id: main.py,v 1.84 2007/08/07 12:21:56 agriggio Exp $
#
# Copyright (c) 2002-2007 Alberto Griggio <agriggio@users.sourceforge.net>
# License: MIT (see license.txt)
# THIS PROGRAM COMES WITH NO WARRANTY
import wxversion
wxversion.ensureMinimal("2.6")
#from wxPython.wx import *
import wx
from widget_properties import *
from tree import Tree, WidgetTree
import edit_sizers
import common, os, os.path, misc, config
import clipboard
import xml_parse
import template
class wxGladePropertyPanel(wx.Panel):
"""\
Panel used to display the Properties of the various widgets
"""
def SetTitle(self, title):
try: self.GetParent().SetTitle(title)
except AttributeError: pass
def Layout(self):
if self.is_visible():
wx.Panel.Layout(self)
self.GetParent().Layout()
def is_visible(self):
return self.GetParent().IsShown()
# end of class wxGladePropertyPanel
TOGGLE_BOX_EVENT = wx.NewEventType()
def EVT_TOGGLE_BOX(win, id, func):
win.Connect(id, -1, TOGGLE_BOX_EVENT, func)
class ToggleBoxEvent(wx.PyCommandEvent):
def __init__(self, id, value, strval):
wx.PyCommandEvent.__init__(self)
self.SetId(id)
self.SetEventType(TOGGLE_BOX_EVENT)
self.value = value
self.strval = strval
def GetValue(self):
return self.value
def GetStringValue(self):
return self.strval
# end of class ToggleBoxEvent
class ToggleButtonBox(wx.Panel):
def __init__(self, parent, id, choices=[], value=0):
wx.Panel.__init__(self, parent, id)
self.buttons = [wx.ToggleButton(self, -1, c) for c in choices]
self.selected = None
self.SetValue(value)
for b in self.buttons:
def handler(event, b=b):
self.on_toggle(b, event)
wx.EVT_TOGGLEBUTTON(self, b.GetId(), handler)
sizer = wx.BoxSizer(wx.VERTICAL)
for b in self.buttons:
sizer.Add(b, 0, wx.ALL|wx.EXPAND, 1)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
sizer.SetSizeHints(self)
def on_toggle(self, button, event):
if self.selected is button:
self.selected.SetValue(True)
return
if self.selected is not None:
self.selected.SetValue(False)
self.selected = button
wx.PostEvent(self, ToggleBoxEvent(self.GetId(), self.GetValue(),
self.GetStringValue()))
def GetValue(self):
if self.selected is not None:
return self.buttons.index(self.selected)
return -1
def GetStringValue(self):
if self.selected is None: return None
return self.selected.GetLabel()
def SetValue(self, index):
if self.selected is not None:
self.selected.SetValue(False)
if -1 < index < len(self.buttons):
self.selected = self.buttons[index]
self.selected.SetValue(True)
def SetStringValue(self, strval):
index = -1
for i in range(len(self.buttons)):
if self.buttons[i].GetLabel() == strval:
index = i
break
self.SetValue(index)
# end of class ToggleButtonBox
class wxGladeArtProvider(wx.ArtProvider):
def CreateBitmap(self, artid, client, size):
if wx.Platform == '__WXGTK__' and artid == wx.ART_FOLDER:
return wx.Bitmap(os.path.join(common.wxglade_path, 'icons',
'closed_folder.xpm'),
wx.BITMAP_TYPE_XPM)
return wx.NullBitmap
# end of class wxGladeArtProvider
class wxGladeFrame(wx.Frame):
"""\
Main frame of wxGlade (palette)
"""
def __init__(self, parent=None):
style = wx.SYSTEM_MENU|wx.CAPTION|wx.MINIMIZE_BOX|wx.RESIZE_BORDER
if misc.check_wx_version(2, 5):
style |= wx.CLOSE_BOX
wx.Frame.__init__(self, parent, -1, "wxGlade v%s" % common.version,
style=style)
self.CreateStatusBar(1)
if parent is None: parent = self
common.palette = self # to provide a reference accessible
# by the various widget classes
icon = wx.EmptyIcon()
bmp = wx.Bitmap(os.path.join(common.wxglade_path, "icons/icon.xpm"),
wx.BITMAP_TYPE_XPM)
icon.CopyFromBitmap(bmp)
self.SetIcon(icon)
self.SetBackgroundColour(wx.SystemSettings_GetColour(
wx.SYS_COLOUR_BTNFACE))
menu_bar = wx.MenuBar()
file_menu = wx.Menu(style=wx.MENU_TEAROFF)
view_menu = wx.Menu(style=wx.MENU_TEAROFF)
help_menu = wx.Menu(style=wx.MENU_TEAROFF)
wx.ToolTip_SetDelay(1000)
# load the available code generators
common.load_code_writers()
# load the available widgets and sizers
core_btns, custom_btns = common.load_widgets()
sizer_btns = common.load_sizers()
append_item = misc.append_item
self.TREE_ID = TREE_ID = wx.NewId()
append_item(view_menu, TREE_ID, _("Show &Tree\tF2"))
self.PROPS_ID = PROPS_ID = wx.NewId()
self.RAISE_ID = RAISE_ID = wx.NewId()
append_item(view_menu, PROPS_ID, _("Show &Properties\tF3"))
append_item(view_menu, RAISE_ID, _("&Raise All\tF4"))
NEW_ID = wx.NewId()
append_item(file_menu, NEW_ID, _("&New\tCtrl+N"), wx.ART_NEW)
NEW_FROM_TEMPLATE_ID = wx.NewId()
append_item(file_menu, NEW_FROM_TEMPLATE_ID,
_("New from &Template...\tShift+Ctrl+N"))
OPEN_ID = wx.NewId()
append_item(file_menu, OPEN_ID, _("&Open...\tCtrl+O"), wx.ART_FILE_OPEN)
SAVE_ID = wx.NewId()
append_item(file_menu, SAVE_ID, _("&Save\tCtrl+S"), wx.ART_FILE_SAVE)
SAVE_AS_ID = wx.NewId()
append_item(file_menu, SAVE_AS_ID, _("Save As...\tShift+Ctrl+S"),
wx.ART_FILE_SAVE_AS)
SAVE_TEMPLATE_ID = wx.NewId()
append_item(file_menu, SAVE_TEMPLATE_ID, _("Save As Template..."))
file_menu.AppendSeparator()
RELOAD_ID = wx.ID_REFRESH #wx.NewId()
append_item(file_menu, RELOAD_ID, _("&Refresh\tf5")) #, wx.ART_REDO)
GENERATE_CODE_ID = wx.NewId()
append_item(file_menu, GENERATE_CODE_ID, _("&Generate Code\tCtrl+G"),
wx.ART_EXECUTABLE_FILE)
file_menu.AppendSeparator()
IMPORT_ID = wx.NewId()
append_item(file_menu, IMPORT_ID, _("&Import from XRC...\tCtrl+I"))
EXIT_ID = wx.NewId()
file_menu.AppendSeparator()
append_item(file_menu, EXIT_ID, _('E&xit\tCtrl+Q'), wx.ART_QUIT)
PREFS_ID = wx.ID_PREFERENCES #NewId()
view_menu.AppendSeparator()
MANAGE_TEMPLATES_ID = wx.NewId()
append_item(view_menu, MANAGE_TEMPLATES_ID, _('Templates Manager...'))
view_menu.AppendSeparator()
append_item(view_menu, PREFS_ID, _('Preferences...'))
#wx.ART_HELP_SETTINGS)
menu_bar.Append(file_menu, _("&File"))
menu_bar.Append(view_menu, _("&View"))
TUT_ID = wx.NewId()
append_item(help_menu, TUT_ID, _('Contents\tF1'), wx.ART_HELP)
ABOUT_ID = wx.ID_ABOUT #wx.NewId()
append_item(help_menu, ABOUT_ID, _('About...'))#, wx.ART_QUESTION)
menu_bar.Append(help_menu, _('&Help'))
parent.SetMenuBar(menu_bar)
# Mac tweaks...
if wx.Platform == "__WXMAC__":
wx.App_SetMacAboutMenuItemId(ABOUT_ID)
wx.App_SetMacPreferencesMenuItemId(PREFS_ID)
wx.App_SetMacExitMenuItemId(EXIT_ID)
wx.App_SetMacHelpMenuTitleName(_('&Help'))
# file history support
if misc.check_wx_version(2, 3, 3):
self.file_history = wx.FileHistory(
config.preferences.number_history)
self.file_history.UseMenu(file_menu)
files = config.load_history()
files.reverse()
for path in files:
self.file_history.AddFileToHistory(path.strip())
def open_from_history(event):
if not self.ask_save(): return
infile = self.file_history.GetHistoryFile(
event.GetId() - wx.ID_FILE1)
# ALB 2004-10-15 try to restore possible autosave content...
if common.check_autosaved(infile) and \
wx.MessageBox(_("There seems to be auto saved data for "
"this file: do you want to restore it?"),
_("Auto save detected"),
style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES:
common.restore_from_autosaved(infile)
else:
common.remove_autosaved(infile)
self._open_app(infile)
wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, open_from_history)
wx.EVT_MENU(self, TREE_ID, self.show_tree)
wx.EVT_MENU(self, PROPS_ID, self.show_props_window)
wx.EVT_MENU(self, RAISE_ID, self.raise_all)
wx.EVT_MENU(self, NEW_ID, self.new_app)
wx.EVT_MENU(self, NEW_FROM_TEMPLATE_ID, self.new_app_from_template)
wx.EVT_MENU(self, OPEN_ID, self.open_app)
wx.EVT_MENU(self, SAVE_ID, self.save_app)
wx.EVT_MENU(self, SAVE_AS_ID, self.save_app_as)
wx.EVT_MENU(self, SAVE_TEMPLATE_ID, self.save_app_as_template)
def generate_code(event):
common.app_tree.app.generate_code()
wx.EVT_MENU(self, GENERATE_CODE_ID, generate_code)
wx.EVT_MENU(self, EXIT_ID, lambda e: self.Close())
wx.EVT_MENU(self, TUT_ID, self.show_tutorial)
wx.EVT_MENU(self, ABOUT_ID, self.show_about_box)
wx.EVT_MENU(self, PREFS_ID, self.edit_preferences)
wx.EVT_MENU(self, MANAGE_TEMPLATES_ID, self.manage_templates)
wx.EVT_MENU(self, IMPORT_ID, self.import_xrc)
wx.EVT_MENU(self, RELOAD_ID, self.reload_app)
PREVIEW_ID = wx.NewId()
def preview(event):
if common.app_tree.cur_widget is not None:
p = misc.get_toplevel_widget(common.app_tree.cur_widget)
if p is not None:
p.preview(None)
wx.EVT_MENU(self, PREVIEW_ID, preview)
self.accel_table = wx.AcceleratorTable([
(wx.ACCEL_CTRL, ord('N'), NEW_ID),
(wx.ACCEL_CTRL, ord('O'), OPEN_ID),
(wx.ACCEL_CTRL, ord('S'), SAVE_ID),
(wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('S'), SAVE_AS_ID),
(wx.ACCEL_CTRL, ord('G'), GENERATE_CODE_ID),
(wx.ACCEL_CTRL, ord('I'), IMPORT_ID),
(0, wx.WXK_F1, TUT_ID),
(wx.ACCEL_CTRL, ord('Q'), EXIT_ID),
(0, wx.WXK_F5, RELOAD_ID),
(0, wx.WXK_F2, TREE_ID),
(0, wx.WXK_F3, PROPS_ID),
(0, wx.WXK_F4, RAISE_ID),
(wx.ACCEL_CTRL, ord('P'), PREVIEW_ID),
])
# Tutorial window
## self.tut_frame = None
# layout
# if there are custom components, add the toggle box...
if custom_btns:
main_sizer = wx.BoxSizer(wx.VERTICAL)
show_core_custom = ToggleButtonBox(
self, -1, [_("Core components"), _("Custom components")], 0)
if misc.check_wx_version(2, 5):
core_sizer = wx.FlexGridSizer(
0, config.preferences.buttons_per_row)
custom_sizer = wx.FlexGridSizer(
0, config.preferences.buttons_per_row)
else:
core_sizer = wx.GridSizer(
0, config.preferences.buttons_per_row)
custom_sizer = wx.GridSizer(
0, config.preferences.buttons_per_row)
self.SetAutoLayout(True)
# core components
for b in core_btns: core_sizer.Add(b)
for sb in sizer_btns: core_sizer.Add(sb)
# custom components
for b in custom_btns:
custom_sizer.Add(b)
if misc.check_wx_version(2, 5):
custom_sizer.Show(b, False)
custom_sizer.Layout()
main_sizer.Add(show_core_custom, 0, wx.EXPAND)
main_sizer.Add(core_sizer, 0, wx.EXPAND)
main_sizer.Add(custom_sizer, 0, wx.EXPAND)
self.SetSizer(main_sizer)
if not misc.check_wx_version(2, 5):
main_sizer.Show(custom_sizer, False)
#main_sizer.Show(1, False)
main_sizer.Fit(self)
# events to display core/custom components
if misc.check_wx_version(2, 5):
def on_show_core_custom(event):
show_core = True
show_custom = False
if event.GetValue() == 1:
show_core = False
show_custom = True
for b in custom_btns:
custom_sizer.Show(b, show_custom)
for b in core_btns:
core_sizer.Show(b, show_core)
for b in sizer_btns:
core_sizer.Show(b, show_core)
core_sizer.Layout()
custom_sizer.Layout()
main_sizer.Layout()
else:
def on_show_core_custom(event):
to_show = core_sizer
to_hide = custom_sizer
if event.GetValue() == 1:
to_show, to_hide = to_hide, to_show
main_sizer.Show(to_show, True)
main_sizer.Show(to_hide, False)
main_sizer.Layout()
EVT_TOGGLE_BOX(self, show_core_custom.GetId(), on_show_core_custom)
# ... otherwise (the common case), just add the palette of core buttons
else:
sizer = wx.GridSizer(0, config.preferences.buttons_per_row)
self.SetAutoLayout(True)
# core components
for b in core_btns: sizer.Add(b)
for sb in sizer_btns: sizer.Add(sb)
self.SetSizer(sizer)
sizer.Fit(self)
# Properties window
frame_style = wx.DEFAULT_FRAME_STYLE
frame_tool_win = config.preferences.frame_tool_win
if frame_tool_win:
frame_style |= wx.FRAME_NO_TASKBAR | wx.FRAME_FLOAT_ON_PARENT
frame_style &= ~wx.MINIMIZE_BOX
if wx.Platform != '__WXGTK__': frame_style |= wx.FRAME_TOOL_WINDOW
self.frame2 = wx.Frame(self, -1, _('Properties - <app>'),
style=frame_style)
self.frame2.SetBackgroundColour(wx.SystemSettings_GetColour(
wx.SYS_COLOUR_BTNFACE))
self.frame2.SetIcon(icon)
sizer_tmp = wx.BoxSizer(wx.VERTICAL)
property_panel = wxGladePropertyPanel(self.frame2, -1)
#---- 2003-06-22 Fix for what seems to be a GTK2 bug (notebooks)
misc.hidden_property_panel = wx.Panel(self.frame2, -1)
sz = wx.BoxSizer(wx.VERTICAL)
sz.Add(property_panel, 1, wx.EXPAND)
sz.Add(misc.hidden_property_panel, 1, wx.EXPAND)
self.frame2.SetSizer(sz)
sz.Show(misc.hidden_property_panel, False)
self.property_frame = self.frame2
#--------------------------------------------------------
property_panel.SetAutoLayout(True)
self.hidden_frame = wx.Frame(self, -1, "")
self.hidden_frame.Hide()
sizer_tmp.Add(property_panel, 1, wx.EXPAND)
self.frame2.SetAutoLayout(True)
self.frame2.SetSizer(sizer_tmp)
sizer_tmp = wx.BoxSizer(wx.VERTICAL)
def hide_frame2(event):
#menu_bar.Check(PROPS_ID, False)
self.frame2.Hide()
wx.EVT_CLOSE(self.frame2, hide_frame2)
wx.EVT_CLOSE(self, self.cleanup)
common.property_panel = property_panel
# Tree of widgets
self.tree_frame = wx.Frame(self, -1, _('wxGlade: Tree'),
style=frame_style)
self.tree_frame.SetIcon(icon)
import application
app = application.Application(common.property_panel)
common.app_tree = WidgetTree(self.tree_frame, app)
self.tree_frame.SetSize((300, 300))
app.notebook.Show()
sizer_tmp.Add(app.notebook, 1, wx.EXPAND)
property_panel.SetSizer(sizer_tmp)
sizer_tmp.Fit(property_panel)
def on_tree_frame_close(event):
#menu_bar.Check(TREE_ID, False)
self.tree_frame.Hide()
wx.EVT_CLOSE(self.tree_frame, on_tree_frame_close)
# check to see if there are some remembered values
prefs = config.preferences
if prefs.remember_geometry:
#print 'initializing geometry'
try:
x, y, w, h = prefs.get_geometry('main')
misc.set_geometry(self, (x, y))
except Exception, e:
pass
misc.set_geometry(self.frame2, prefs.get_geometry('properties'))
misc.set_geometry(self.tree_frame, prefs.get_geometry('tree'))
else:
if wx.Platform == '__WXMAC__':
self.frame2.SetSize((345, 384)) # I've been told this is OK...
self.SetPosition((0, 45)) # to avoid the OS X menubar
else:
self.frame2.SetSize((max(self.GetSize()[0], 250), 350))
self.SetPosition((0, 0))
x, y = self.GetPosition()
h = self.GetSize()[1]
w = self.frame2.GetSize()[0]
if wx.Platform != '__WXMSW__':
# under X, IceWM (and Sawfish, too), GetSize seems to ignore
# window decorations
h += 60
w += 10
self.frame2.SetPosition((x, y+h))
self.tree_frame.SetPosition((x+w, y))
self.Show()
self.tree_frame.Show()
self.frame2.Show()
#self._skip_activate = False
## if frame_tool_win:
## def on_iconize(event):
## if event.Iconized():
## self.hide_all()
## else:
## self.show_and_raise()
## event.Skip()
## wx.EVT_ICONIZE(self, on_iconize)
if wx.Platform == '__WXMSW__':
import about
# I'll pay a beer to anyone who can explain to me why this prevents
# a segfault on Win32 when you exit without doing anything!!
self.about_box = about.wxGladeAboutBox(self.GetParent())
else:
self.about_box = None
# last visited directory, used on GTK for wxFileDialog
self.cur_dir = config.preferences.open_save_path
# set a drop target for us...
self._droptarget = clipboard.FileDropTarget(self)
self.SetDropTarget(self._droptarget)
#self.tree_frame.SetDropTarget(self._droptarget)
#self.frame2.SetDropTarget(self._droptarget)
# ALB 2004-10-15, autosave support...
self.autosave_timer = None
if config.preferences.autosave:
TIMER_ID = wx.NewId()
self.autosave_timer = wx.Timer(self, TIMER_ID)
wx.EVT_TIMER(self, TIMER_ID, self.on_autosave_timer)
self.autosave_timer.Start(
int(config.preferences.autosave_delay) * 1000)
# ALB 2004-10-15
CLEAR_SB_TIMER_ID = wx.NewId()
self.clear_sb_timer = wx.Timer(self, CLEAR_SB_TIMER_ID)
wx.EVT_TIMER(self, CLEAR_SB_TIMER_ID, self.on_clear_sb_timer)
self.frame2.SetAcceleratorTable(self.accel_table)
self.tree_frame.SetAcceleratorTable(self.accel_table)
self.Raise()
# ALB 2004-10-16
if common.check_autosaved(None) and \
wx.MessageBox(_("There seems to be auto saved data "
"from last wxGlade session: "
"do you want to restore it?"),
_("Auto save detected"),
style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES:
if self._open_app(common.get_name_for_autosave(),
add_to_history=False):
common.app_tree.app.saved = False
common.app_tree.app.filename = None
self.user_message(_("Recovery from auto save complete"))
common.remove_autosaved()
else:
common.remove_autosaved()
def on_autosave_timer(self, event):
if common.autosave_current():
self.user_message(_("Auto saving... done"))
def edit_preferences(self, event):
config.edit_preferences()
def show_tree(self, event):
self.tree_frame.Show()
self.tree_frame.Raise()
common.app_tree.SetFocus()
def show_props_window(self, event):
self.frame2.Show()
self.frame2.Raise()
try:
c = self.frame2.GetSizer().GetChildren()
if c: c[0].GetWindow().SetFocus()
except (AttributeError, TypeError):
self.frame2.SetFocus()
def raise_all(self, event):
children = self.GetChildren()
for child in children:
child = misc.get_toplevel_parent(child)
if child.IsShown() and child.GetTitle(): child.Raise()
self.Raise()
def user_message(self, msg):
sb = self.GetStatusBar()
if sb:
sb.SetStatusText(msg)
self.clear_sb_timer.Start(5000, True)
def on_clear_sb_timer(self, event):
sb = self.GetStatusBar()
if sb:
sb.SetStatusText("")
def ask_save(self):
"""\
checks whether the current app has changed and needs to be saved:
if so, prompts the user;
returns False if the operation has been cancelled
"""
if not common.app_tree.app.saved:
ok = wx.MessageBox(_("Save changes to the current app?"),
_("Confirm"),
wx.YES_NO|wx.CANCEL|wx.CENTRE|wx.ICON_QUESTION)
if ok == wx.YES:
self.save_app(None)
return ok != wx.CANCEL
return True
def new_app(self, event):
"""\
creates a new wxGlade project
"""
if self.ask_save():
common.app_tree.clear()
common.app_tree.app.filename = None
common.app_tree.app.saved = True
self.user_message("")
# ALB 2004-10-15
common.remove_autosaved()
if config.preferences.autosave and self.autosave_timer is not None:
self.autosave_timer.Start()
def new_app_from_template(self, event):
"""\
creates a new wxGlade project from an existing template file
"""
if not self.ask_save(): return
infile = template.select_template()
if infile:
self._open_app(infile, add_to_history=False)
common.app_tree.app.template_data = None
def reload_app(self, event):
self.ask_save()
if not common.app_tree.app.filename:
wx.MessageBox(_("Impossible to reload an unsaved application"),
_("Alert"), style=wx.OK|wx.ICON_INFORMATION)
return
path = common.app_tree.get_selected_path()
#print 'path:', path
self._open_app(common.app_tree.app.filename, add_to_history=False)
common.app_tree.select_path(path)
def open_app(self, event_unused):
"""\
loads a wxGlade project from an xml file
NOTE: this is very slow and needs optimisation efforts
NOTE2: the note above should not be True anymore :)
"""
if not self.ask_save(): return
from xml_parse import XmlWidgetBuilder, ProgressXmlWidgetBuilder
infile = misc.FileSelector(_("Open file"),
wildcard="wxGlade files (*.wxg)|*.wxg|"
"wxGlade Template files (*.wgt)|*.wgt|"
"XML files (*.xml)|*.xml|All files|*",
flags=wx.OPEN|wx.FILE_MUST_EXIST,
default_path=self.cur_dir)
if infile:
# ALB 2004-10-15 try to restore possible autosave content...
if common.check_autosaved(infile) and \
wx.MessageBox(_("There seems to be auto saved data for "
"this file: do you want to restore it?"),
_("Auto save detected"),
style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES:
common.restore_from_autosaved(infile)
else:
common.remove_autosaved(infile)
self._open_app(infile)
self.cur_dir = os.path.dirname(infile)
def _open_app(self, infilename, use_progress_dialog=True,
is_filelike=False, add_to_history=True):
import time
from xml_parse import XmlWidgetBuilder, ProgressXmlWidgetBuilder, \
XmlParsingError
from xml.sax import SAXParseException
start = time.clock()
common.app_tree.clear()
if not is_filelike:
common.app_tree.app.filename = infilename
else:
common.app_tree.filename = getattr(infilename, 'name', None)
common.property_panel.Reparent(self.hidden_frame)
# prevent the auto-expansion of nodes
common.app_tree.auto_expand = False
old_dir = os.getcwd()
try:
if not is_filelike:
os.chdir(os.path.dirname(infilename))
infile = open(infilename)
else:
infile = infilename
infilename = getattr(infile, 'name', None)
if use_progress_dialog and config.preferences.show_progress:
p = ProgressXmlWidgetBuilder(input_file=infile)
else:
p = XmlWidgetBuilder()
p.parse(infile)
except (IOError, OSError, SAXParseException, XmlParsingError), msg:
if locals().has_key('infile') and not is_filelike: infile.close()
common.app_tree.clear()
common.property_panel.Reparent(self.frame2)
common.app_tree.app.saved = True
wx.MessageBox(_("Error loading file %s: %s") % \
(misc.wxstr(infilename), misc.wxstr(msg)),
_("Error"), wx.OK|wx.CENTRE|wx.ICON_ERROR)
# reset the auto-expansion of nodes
common.app_tree.auto_expand = True
os.chdir(old_dir)
return False
except Exception, msg:
import traceback; traceback.print_exc()
if locals().has_key('infile') and not is_filelike: infile.close()
common.app_tree.clear()
common.property_panel.Reparent(self.frame2)
common.app_tree.app.saved = True
wx.MessageBox(_("An exception occurred while loading file \"%s\".\n"
"This is the error message associated with it:\n"
" %s\n"
"For more details, look at the full traceback "
"on the console.\n"
"If you think this is a wxGlade bug,"
" please report it.") % \
(misc.wxstr(infilename), misc.wxstr(msg)),
_("Error"),
wx.OK|wx.CENTRE|wx.ICON_ERROR)
# reset the auto-expansion of nodes
common.app_tree.auto_expand = True
os.chdir(old_dir)
return False
if not is_filelike:
infile.close()
common.app_tree.select_item(common.app_tree.root)
common.app_tree.root.widget.show_properties()
common.property_panel.Reparent(self.frame2)
# reset the auto-expansion of nodes
common.app_tree.auto_expand = True
common.app_tree.expand()
if common.app_tree.app.is_template:
print _("Loaded template")
common.app_tree.app.template_data = template.Template(infilename)
common.app_tree.app.filename = None
end = time.clock()
print _('Loading time: %.5f') % (end-start)
common.app_tree.app.saved = True
if hasattr(self, 'file_history') and infilename is not None and \
add_to_history and (not common.app_tree.app.is_template):
self.file_history.AddFileToHistory(misc.wxstr(infilename))
# ALB 2004-10-15
if config.preferences.autosave and self.autosave_timer is not None:
self.autosave_timer.Start()
self.user_message(_("Loaded %s (%.2f seconds)") % \
(misc.wxstr(common.app_tree.app.filename), end-start))
return True
def save_app(self, event):
"""\
saves a wxGlade project onto an xml file
"""
if not common.app_tree.app.filename or common.app_tree.app.is_template:
self.save_app_as(event)
else:
# check whether we are saving a template
if os.path.splitext(common.app_tree.app.filename)[1] == ".wgt":
common.app_tree.app.is_template = True
self._save_app(common.app_tree.app.filename)
def _save_app(self, filename):
try:
from cStringIO import StringIO
buffer = StringIO()
common.app_tree.write(buffer)
common.save_file(filename,
buffer.getvalue(), 'wxg')
except (IOError, OSError), msg:
common.app_tree.app.saved = False
fn = filename
wx.MessageBox(_("Error saving app:\n%s") % msg, _("Error"),
wx.OK|wx.CENTRE|wx.ICON_ERROR)
except Exception, msg:
import traceback; traceback.print_exc()
common.app_tree.app.saved = False
fn = filename
wx.MessageBox(_("An exception occurred while saving file "
"\"%s\".\n"
"This is the error message associated with it:"
"\n %s\n"
"For more details, look at the full traceback "
"on the console.\nIf you think this is a "
"wxGlade bug,"
" please report it.") % (fn, msg), _("Error"),
wx.OK|wx.CENTRE|wx.ICON_ERROR)
else:
common.app_tree.app.saved = True
common.remove_autosaved() # ALB 2004-10-15
# ALB 2004-10-15
if config.preferences.autosave and \
self.autosave_timer is not None:
self.autosave_timer.Start()
self.user_message(_("Saved %s") % filename)
def save_app_as(self, event):
"""\
saves a wxGlade project onto an xml file chosen by the user
"""
fn = misc.FileSelector(_("Save project as..."),
wildcard="wxGlade files (*.wxg)|*.wxg|"
"wxGlade Template files (*.wgt) |*.wgt|"
"XML files (*.xml)|*.xml|All files|*",
flags=wx.SAVE|wx.OVERWRITE_PROMPT,
default_path=self.cur_dir)
if fn:
common.app_tree.app.filename = fn
#remove the template flag so we can save the file.
common.app_tree.app.is_template = False
self.save_app(event)
self.cur_dir = os.path.dirname(fn)
if misc.check_wx_version(2, 3, 3):
self.file_history.AddFileToHistory(fn)
def save_app_as_template(self, event):
data = getattr(common.app_tree.app, 'template_data', None)
outfile, data = template.save_template(data)
if outfile:
common.app_tree.app.is_template = True
common.app_tree.app.template_data = data
self._save_app(outfile)
def cleanup(self, event):
if self.ask_save():
# first, let's see if we have to save the geometry...
prefs = config.preferences
if prefs.remember_geometry:
prefs.set_geometry('main', misc.get_geometry(self))
prefs.set_geometry('tree',
misc.get_geometry(self.tree_frame))
prefs.set_geometry('properties',
misc.get_geometry(self.frame2))
prefs.changed = True
common.app_tree.clear()
if self.about_box: self.about_box.Destroy()
try: config.save_preferences()
except Exception, e:
wx.MessageBox(_('Error saving preferences:\n%s') % e,
_('Error'),
wx.OK|wx.CENTRE|wx.ICON_ERROR)
#self._skip_activate = True
self.frame2.Destroy()
self.tree_frame.Destroy()
self.Destroy()
common.remove_autosaved() # ALB 2004-10-15
misc.wxCallAfter(wx.GetApp().ExitMainLoop)
def show_about_box(self, event):
if self.about_box is None:
import about
self.about_box = about.wxGladeAboutBox(None)
self.about_box.ShowModal()
def show_tutorial(self, event):
docs_path = os.path.join(common.wxglade_path, 'docs', 'index.html')
if wx.Platform == "__WXMAC__":
os.system('open -a Help\ Viewer.app %s' % docs_path)
else:
import webbrowser, threading
# ALB 2004-08-15: why did this block the program?????
# (at least on linux - GTK)
def go():
webbrowser.open_new(docs_path)
t = threading.Thread(target=go)
t.setDaemon(True)
t.start()
def show_and_raise(self):
self.frame2.Show()#self.GetMenuBar().IsChecked(self.PROPS_ID))
self.tree_frame.Show()#self.GetMenuBar().IsChecked(self.TREE_ID))
self.frame2.Raise()
self.tree_frame.Raise()
self.Raise()
def hide_all(self):
self.tree_frame.Hide()
self.frame2.Hide()
def import_xrc(self, event):
import xrc2wxg, cStringIO
if not self.ask_save():
return
infile = misc.FileSelector(_("Import file"),
wildcard="XRC files (*.xrc)"
"|*.xrc|All files|*",
flags=wx.OPEN|wx.FILE_MUST_EXIST,
default_path=self.cur_dir)
if infile:
buf = cStringIO.StringIO()
try:
xrc2wxg.convert(infile, buf)
buf.seek(0)
self._open_app(buf, is_filelike=True)
common.app_tree.app.saved = False
except Exception, msg:
import traceback; traceback.print_exc()
wx.MessageBox(_("An exception occurred while importing file "
"\"%s\".\nThis is the error message associated "
"with it:\n %s\n"
"For more details, look at the full traceback "
"on the console.\nIf you think this is a "
"wxGlade bug, please report it.") % \
(infile, msg), _("Error"),
wx.OK|wx.CENTRE|wx.ICON_ERROR)
def manage_templates(self, event):
to_edit = template.manage_templates()
if to_edit is not None and self.ask_save():
# edit the template
# TODO, you still need to save it manually...
self._open_app(to_edit, add_to_history=False)
wx.MessageBox(_("To save the changes to the template, edit the "
"GUI as usual,\nand then click "
"File->Save as Template..."), _("Information"),
style=wx.OK|wx.ICON_INFORMATION)
# end of class wxGladeFrame
class wxGlade(wx.App):
def OnInit(self):
import sys
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
# needed for wx >= 2.3.4 to disable wxPyAssertionError exceptions
if misc.check_wx_version(2, 3, 4):
self.SetAssertMode(0)
wx.InitAllImageHandlers()
config.init_preferences()
# ALB 2004-10-27
if wx.Platform == '__WXGTK__' and config.preferences.use_kde_dialogs:
import kdefiledialog
if kdefiledialog.test_kde():
misc.FileSelector = kdefiledialog.kde_file_selector
misc.DirSelector = kdefiledialog.kde_dir_selector
wx.ArtProvider.PushProvider(wxGladeArtProvider())
frame = wxGladeFrame()
## if wx.Platform == '__WXMSW__':
## def on_activate(event):
## if event.GetActive() and not frame.IsIconized():
## frame.show_and_raise()
## event.Skip()
## wx.EVT_ACTIVATE_APP(self, on_activate)
self.SetTopWindow(frame)
self.SetExitOnFrameDelete(True)
wx.EVT_IDLE(self, self.on_idle)
return True
def on_idle(self, event):
common.message.flush()
event.Skip()
# end of class wxGlade
def main(filename=None):
"""\
if filename is not None, loads it
"""
# first thing to do, patch wxSizerPtr's Insert if needed...
## from wxPython import wx
## if wx.__version__ == '2.4.0.2':
## wxSizerPtr.Insert = misc.sizer_fixed_Insert
# now, silence a deprecation warining for py2.3
import warnings
warnings.filterwarnings("ignore", "integer", DeprecationWarning,
"wxPython.gdi")
app = wxGlade()
if filename is not None:
app.GetTopWindow()._open_app(filename, False)
app.MainLoop()
syntax highlighted by Code2HTML, v. 0.9.1