2 # Purpose: XRC editor, main module
3 # Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
9 xrced -- Simple resource editor for XRC format used by wxWidgets/wxPython
14 xrced [ -h ] [ -v ] [ XRC-file ]
18 -h output short usage info and exit
20 -v output version info and exit
24 import os
, sys
, getopt
, re
, traceback
, tempfile
, shutil
, cPickle
25 from xml
.parsers
import expat
28 from tree
import * # imports xxx which imports params
31 from params
import genericStyles
32 # Cleanup recursive import sideeffects, otherwise we can't create undoMan
34 undo
.ParamPage
= ParamPage
35 undoMan
= g
.undoMan
= UndoManager()
37 # Set application path for loading resources
38 if __name__
== '__main__':
39 basePath
= os
.path
.dirname(sys
.argv
[0])
41 basePath
= os
.path
.dirname(__file__
)
43 # Remember system path
46 # 1 adds CMD command to Help menu
50 <HTML><H2>Welcome to XRC<font color="blue">ed</font></H2><H3><font color="green">DON'T PANIC :)</font></H3>
51 Read this note before clicking on anything!<P>
52 To start select tree root, then popup menu with your right mouse button,
53 select "Append Child", and then any command.<P>
54 Or just press one of the buttons on the tools palette.<P>
55 Enter XML ID, change properties, create children.<P>
56 To test your interface select Test command (View menu).<P>
57 Consult README.txt file for the details.</HTML>
60 defaultIDs
= {xxxPanel
:'PANEL', xxxDialog
:'DIALOG', xxxFrame
:'FRAME',
61 xxxMenuBar
:'MENUBAR', xxxMenu
:'MENU', xxxToolBar
:'TOOLBAR',
62 xxxWizard
:'WIZARD', xxxBitmap
:'BITMAP', xxxIcon
:'ICON'}
64 defaultName
= 'UNTITLED.xrc'
66 ################################################################################
68 # ScrolledMessageDialog - modified from wxPython lib to set fixed-width font
69 class ScrolledMessageDialog(wx
.Dialog
):
70 def __init__(self
, parent
, msg
, caption
, pos
= wx
.DefaultPosition
, size
= (500,300)):
71 from wx
.lib
.layoutf
import Layoutf
72 wx
.Dialog
.__init
__(self
, parent
, -1, caption
, pos
, size
)
73 text
= wx
.TextCtrl(self
, -1, msg
, wx
.DefaultPosition
,
74 wx
.DefaultSize
, wx
.TE_MULTILINE | wx
.TE_READONLY
)
75 text
.SetFont(g
.modernFont())
76 dc
= wx
.WindowDC(text
)
77 w
, h
= dc
.GetFullTextExtent(' ', g
.modernFont())[:2]
78 ok
= wx
.Button(self
, wx
.ID_OK
, "OK")
80 text
.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self
,ok
)))
81 text
.SetSize((w
* 80 + 30, h
* 40))
82 text
.ShowPosition(1) # scroll to the first line
83 ok
.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!35', (self
,)))
84 self
.SetAutoLayout(True)
86 self
.CenterOnScreen(wx
.BOTH
)
88 ################################################################################
90 # Event handler for using during location
91 class Locator(wx
.EvtHandler
):
92 def ProcessEvent(self
, evt
):
95 class Frame(wx
.Frame
):
96 def __init__(self
, pos
, size
):
97 wx
.Frame
.__init
__(self
, None, -1, '', pos
, size
)
99 frame
= g
.frame
= self
100 bar
= self
.CreateStatusBar(2)
101 bar
.SetStatusWidths([-1, 40])
102 self
.SetIcon(images
.getIconIcon())
107 # Load our own resources
108 self
.res
= xrc
.EmptyXmlResource()
109 # !!! Blocking of assert failure occurring in older unicode builds
111 quietlog
= wx
.LogNull()
112 self
.res
.Load(os
.path
.join(basePath
, 'xrced.xrc'))
113 except wx
._core
.PyAssertionError
:
114 print 'PyAssertionError was ignored'
117 menuBar
= wx
.MenuBar()
120 menu
.Append(wx
.ID_NEW
, '&New\tCtrl-N', 'New file')
121 menu
.AppendSeparator()
122 menu
.Append(wx
.ID_OPEN
, '&Open...\tCtrl-O', 'Open XRC file')
124 self
.recentMenu
= wx
.Menu()
125 g
.fileHistory
.UseMenu(self
.recentMenu
)
126 g
.fileHistory
.AddFilesToMenu()
127 self
.Bind(wx
.EVT_MENU
, self
.OnRecentFile
, id=wx
.ID_FILE1
, id2
=wx
.ID_FILE9
)
128 menu
.AppendMenu(-1, 'Open &Recent', self
.recentMenu
, 'Open a recent file')
130 menu
.AppendSeparator()
131 menu
.Append(wx
.ID_SAVE
, '&Save\tCtrl-S', 'Save XRC file')
132 menu
.Append(wx
.ID_SAVEAS
, 'Save &As...', 'Save XRC file under different name')
133 self
.ID_GENERATE_PYTHON
= wx
.NewId()
134 menu
.Append(self
.ID_GENERATE_PYTHON
, '&Generate Python...',
135 'Generate a Python module that uses this XRC')
136 menu
.AppendSeparator()
137 self
.ID_PREFS
= wx
.NewId()
138 menu
.Append(self
.ID_PREFS
, 'Preferences...', 'Change XRCed settings')
139 menu
.AppendSeparator()
140 menu
.Append(wx
.ID_EXIT
, '&Quit\tCtrl-Q', 'Exit application')
142 menuBar
.Append(menu
, '&File')
145 menu
.Append(wx
.ID_UNDO
, '&Undo\tCtrl-Z', 'Undo')
146 menu
.Append(wx
.ID_REDO
, '&Redo\tCtrl-Y', 'Redo')
147 menu
.AppendSeparator()
148 menu
.Append(wx
.ID_CUT
, 'Cut\tCtrl-X', 'Cut to the clipboard')
149 menu
.Append(wx
.ID_COPY
, '&Copy\tCtrl-C', 'Copy to the clipboard')
150 menu
.Append(wx
.ID_PASTE
, '&Paste\tCtrl-V', 'Paste from the clipboard')
151 self
.ID_DELETE
= wx
.NewId()
152 menu
.Append(self
.ID_DELETE
, '&Delete\tCtrl-D', 'Delete object')
153 menu
.AppendSeparator()
154 self
.ID_LOCATE
= wx
.NewId()
155 self
.ID_TOOL_LOCATE
= wx
.NewId()
156 self
.ID_TOOL_PASTE
= wx
.NewId()
157 menu
.Append(self
.ID_LOCATE
, '&Locate\tCtrl-L', 'Locate control in test window and select it')
158 menuBar
.Append(menu
, '&Edit')
161 self
.ID_EMBED_PANEL
= wx
.NewId()
162 menu
.Append(self
.ID_EMBED_PANEL
, '&Embed Panel',
163 'Toggle embedding properties panel in the main window', True)
164 menu
.Check(self
.ID_EMBED_PANEL
, conf
.embedPanel
)
165 self
.ID_SHOW_TOOLS
= wx
.NewId()
166 menu
.Append(self
.ID_SHOW_TOOLS
, 'Show &Tools', 'Toggle tools', True)
167 menu
.Check(self
.ID_SHOW_TOOLS
, conf
.showTools
)
168 menu
.AppendSeparator()
169 self
.ID_TEST
= wx
.NewId()
170 menu
.Append(self
.ID_TEST
, '&Test\tF5', 'Show test window')
171 self
.ID_REFRESH
= wx
.NewId()
172 menu
.Append(self
.ID_REFRESH
, '&Refresh\tCtrl-R', 'Refresh test window')
173 self
.ID_AUTO_REFRESH
= wx
.NewId()
174 menu
.Append(self
.ID_AUTO_REFRESH
, '&Auto-refresh\tAlt-A',
175 'Toggle auto-refresh mode', True)
176 menu
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
177 self
.ID_TEST_HIDE
= wx
.NewId()
178 menu
.Append(self
.ID_TEST_HIDE
, '&Hide\tF6', 'Close test window')
179 menuBar
.Append(menu
, '&View')
182 self
.ID_MOVEUP
= wx
.NewId()
183 menu
.Append(self
.ID_MOVEUP
, '&Up', 'Move before previous sibling')
184 self
.ID_MOVEDOWN
= wx
.NewId()
185 menu
.Append(self
.ID_MOVEDOWN
, '&Down', 'Move after next sibling')
186 self
.ID_MOVELEFT
= wx
.NewId()
187 menu
.Append(self
.ID_MOVELEFT
, '&Make sibling', 'Make sibling of parent')
188 self
.ID_MOVERIGHT
= wx
.NewId()
189 menu
.Append(self
.ID_MOVERIGHT
, '&Make child', 'Make child of previous sibling')
190 menuBar
.Append(menu
, '&Move')
193 menu
.Append(wx
.ID_ABOUT
, '&About...', 'About XCRed')
194 self
.ID_README
= wx
.NewId()
195 menu
.Append(self
.ID_README
, '&Readme...\tF1', 'View the README file')
197 self
.ID_DEBUG_CMD
= wx
.NewId()
198 menu
.Append(self
.ID_DEBUG_CMD
, 'CMD', 'Python command line')
199 wx
.EVT_MENU(self
, self
.ID_DEBUG_CMD
, self
.OnDebugCMD
)
200 menuBar
.Append(menu
, '&Help')
202 self
.menuBar
= menuBar
203 self
.SetMenuBar(menuBar
)
206 tb
= self
.CreateToolBar(wx
.TB_HORIZONTAL | wx
.NO_BORDER | wx
.TB_FLAT
)
207 tb
.SetToolBitmapSize((24,24))
208 new_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_NORMAL_FILE
, wx
.ART_TOOLBAR
)
209 open_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_OPEN
, wx
.ART_TOOLBAR
)
210 save_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_SAVE
, wx
.ART_TOOLBAR
)
211 undo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_UNDO
, wx
.ART_TOOLBAR
)
212 redo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_REDO
, wx
.ART_TOOLBAR
)
213 cut_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_CUT
, wx
.ART_TOOLBAR
)
214 copy_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_COPY
, wx
.ART_TOOLBAR
)
215 paste_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_PASTE
, wx
.ART_TOOLBAR
)
217 tb
.AddSimpleTool(wx
.ID_NEW
, new_bmp
, 'New', 'New file')
218 tb
.AddSimpleTool(wx
.ID_OPEN
, open_bmp
, 'Open', 'Open file')
219 tb
.AddSimpleTool(wx
.ID_SAVE
, save_bmp
, 'Save', 'Save file')
220 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
221 tb
.AddSimpleTool(wx
.ID_UNDO
, undo_bmp
, 'Undo', 'Undo')
222 tb
.AddSimpleTool(wx
.ID_REDO
, redo_bmp
, 'Redo', 'Redo')
223 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
224 tb
.AddSimpleTool(wx
.ID_CUT
, cut_bmp
, 'Cut', 'Cut')
225 tb
.AddSimpleTool(wx
.ID_COPY
, copy_bmp
, 'Copy', 'Copy')
226 tb
.AddSimpleTool(self
.ID_TOOL_PASTE
, paste_bmp
, 'Paste', 'Paste')
227 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
228 tb
.AddSimpleTool(self
.ID_TOOL_LOCATE
,
229 images
.getLocateBitmap(), #images.getLocateArmedBitmap(),
230 'Locate', 'Locate control in test window and select it', True)
231 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
232 tb
.AddSimpleTool(self
.ID_TEST
, images
.getTestBitmap(), 'Test', 'Test window')
233 tb
.AddSimpleTool(self
.ID_REFRESH
, images
.getRefreshBitmap(),
234 'Refresh', 'Refresh view')
235 tb
.AddSimpleTool(self
.ID_AUTO_REFRESH
, images
.getAutoRefreshBitmap(),
236 'Auto-refresh', 'Toggle auto-refresh mode', True)
237 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
238 tb
.AddSimpleTool(self
.ID_MOVEUP
, images
.getToolMoveUpBitmap(),
239 'Up', 'Move before previous sibling')
240 tb
.AddSimpleTool(self
.ID_MOVEDOWN
, images
.getToolMoveDownBitmap(),
241 'Down', 'Move after next sibling')
242 tb
.AddSimpleTool(self
.ID_MOVELEFT
, images
.getToolMoveLeftBitmap(),
243 'Make Sibling', 'Make sibling of parent')
244 tb
.AddSimpleTool(self
.ID_MOVERIGHT
, images
.getToolMoveRightBitmap(),
245 'Make Child', 'Make child of previous sibling')
246 # if wx.Platform == '__WXGTK__':
247 # tb.AddSeparator() # otherwise auto-refresh sticks in status line
248 tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
252 self
.minWidth
= tb
.GetSize()[0] # minimal width is the size of toolbar
255 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnNew
)
256 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnOpen
)
257 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnSaveOrSaveAs
)
258 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnSaveOrSaveAs
)
259 wx
.EVT_MENU(self
, self
.ID_GENERATE_PYTHON
, self
.OnGeneratePython
)
260 wx
.EVT_MENU(self
, self
.ID_PREFS
, self
.OnPrefs
)
261 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
263 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
264 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
265 wx
.EVT_MENU(self
, wx
.ID_CUT
, self
.OnCutDelete
)
266 wx
.EVT_MENU(self
, wx
.ID_COPY
, self
.OnCopy
)
267 wx
.EVT_MENU(self
, wx
.ID_PASTE
, self
.OnPaste
)
268 wx
.EVT_MENU(self
, self
.ID_TOOL_PASTE
, self
.OnPaste
)
269 wx
.EVT_MENU(self
, self
.ID_DELETE
, self
.OnCutDelete
)
270 wx
.EVT_MENU(self
, self
.ID_LOCATE
, self
.OnLocate
)
271 wx
.EVT_MENU(self
, self
.ID_TOOL_LOCATE
, self
.OnLocate
)
273 wx
.EVT_MENU(self
, self
.ID_EMBED_PANEL
, self
.OnEmbedPanel
)
274 wx
.EVT_MENU(self
, self
.ID_SHOW_TOOLS
, self
.OnShowTools
)
275 wx
.EVT_MENU(self
, self
.ID_TEST
, self
.OnTest
)
276 wx
.EVT_MENU(self
, self
.ID_REFRESH
, self
.OnRefresh
)
277 wx
.EVT_MENU(self
, self
.ID_AUTO_REFRESH
, self
.OnAutoRefresh
)
278 wx
.EVT_MENU(self
, self
.ID_TEST_HIDE
, self
.OnTestHide
)
280 wx
.EVT_MENU(self
, self
.ID_MOVEUP
, self
.OnMoveUp
)
281 wx
.EVT_MENU(self
, self
.ID_MOVEDOWN
, self
.OnMoveDown
)
282 wx
.EVT_MENU(self
, self
.ID_MOVELEFT
, self
.OnMoveLeft
)
283 wx
.EVT_MENU(self
, self
.ID_MOVERIGHT
, self
.OnMoveRight
)
285 wx
.EVT_MENU(self
, wx
.ID_ABOUT
, self
.OnAbout
)
286 wx
.EVT_MENU(self
, self
.ID_README
, self
.OnReadme
)
289 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateUI
)
290 wx
.EVT_UPDATE_UI(self
, wx
.ID_CUT
, self
.OnUpdateUI
)
291 wx
.EVT_UPDATE_UI(self
, wx
.ID_COPY
, self
.OnUpdateUI
)
292 wx
.EVT_UPDATE_UI(self
, wx
.ID_PASTE
, self
.OnUpdateUI
)
293 wx
.EVT_UPDATE_UI(self
, self
.ID_LOCATE
, self
.OnUpdateUI
)
294 wx
.EVT_UPDATE_UI(self
, self
.ID_TOOL_LOCATE
, self
.OnUpdateUI
)
295 wx
.EVT_UPDATE_UI(self
, self
.ID_TOOL_PASTE
, self
.OnUpdateUI
)
296 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUI
)
297 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateUI
)
298 wx
.EVT_UPDATE_UI(self
, self
.ID_DELETE
, self
.OnUpdateUI
)
299 wx
.EVT_UPDATE_UI(self
, self
.ID_TEST
, self
.OnUpdateUI
)
300 wx
.EVT_UPDATE_UI(self
, self
.ID_REFRESH
, self
.OnUpdateUI
)
303 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
304 #sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND)
305 # Horizontal sizer for toolbar and splitter
306 self
.toolsSizer
= sizer1
= wx
.BoxSizer()
307 splitter
= wx
.SplitterWindow(self
, -1, style
=wx
.SP_3DSASH
)
308 self
.splitter
= splitter
309 splitter
.SetMinimumPaneSize(100)
312 g
.tree
= tree
= XML_Tree(splitter
, -1)
314 # Init pull-down menu data
316 g
.pullDownMenu
= pullDownMenu
= PullDownMenu(self
)
318 # Vertical toolbar for GUI buttons
319 g
.tools
= tools
= Tools(self
)
320 tools
.Show(conf
.showTools
)
321 if conf
.showTools
: sizer1
.Add(tools
, 0, wx
.EXPAND
)
323 tree
.RegisterKeyEvents()
325 # Miniframe for split mode
326 miniFrame
= wx
.MiniFrame(self
, -1, 'Properties & Style',
327 (conf
.panelX
, conf
.panelY
),
328 (conf
.panelWidth
, conf
.panelHeight
))
329 self
.miniFrame
= miniFrame
330 sizer2
= wx
.BoxSizer()
331 miniFrame
.SetAutoLayout(True)
332 miniFrame
.SetSizer(sizer2
)
333 wx
.EVT_CLOSE(self
.miniFrame
, self
.OnCloseMiniFrame
)
334 # Create panel for parameters
337 panel
= Panel(splitter
)
338 # Set plitter windows
339 splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
341 panel
= Panel(miniFrame
)
342 sizer2
.Add(panel
, 1, wx
.EXPAND
)
344 splitter
.Initialize(tree
)
345 sizer1
.Add(splitter
, 1, wx
.EXPAND
)
346 sizer
.Add(sizer1
, 1, wx
.EXPAND
)
347 self
.SetAutoLayout(True)
351 wx
.EVT_IDLE(self
, self
.OnIdle
)
352 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
353 wx
.EVT_KEY_DOWN(self
, tools
.OnKeyDown
)
354 wx
.EVT_KEY_UP(self
, tools
.OnKeyUp
)
355 wx
.EVT_ICONIZE(self
, self
.OnIconize
)
357 def OnRecentFile(self
,evt
):
358 # open recently used file
359 if not self
.AskSave(): return
362 # get the pathname based on the menu ID
363 fileNum
= evt
.GetId() - wx
.ID_FILE1
364 path
= g
.fileHistory
.GetHistoryFile(fileNum
)
367 self
.SetStatusText('Data loaded')
368 # add it back to the history so it will be moved up the list
369 self
.SaveRecent(path
)
371 self
.SetStatusText('Failed')
375 def OnNew(self
, evt
):
376 if not self
.AskSave(): return
379 def OnOpen(self
, evt
):
380 if not self
.AskSave(): return
381 dlg
= wx
.FileDialog(self
, 'Open', os
.path
.dirname(self
.dataFile
),
382 '', '*.xrc', wx
.OPEN | wx
.CHANGE_DIR
)
383 if dlg
.ShowModal() == wx
.ID_OK
:
385 self
.SetStatusText('Loading...')
389 self
.SetStatusText('Data loaded')
390 self
.SaveRecent(path
)
392 self
.SetStatusText('Failed')
397 def OnSaveOrSaveAs(self
, evt
):
398 if evt
.GetId() == wx
.ID_SAVEAS
or not self
.dataFile
:
399 if self
.dataFile
: name
= ''
400 else: name
= defaultName
401 dirname
= os
.path
.abspath(os
.path
.dirname(self
.dataFile
))
402 dlg
= wx
.FileDialog(self
, 'Save As', dirname
, name
, '*.xrc',
403 wx
.SAVE | wx
.OVERWRITE_PROMPT | wx
.CHANGE_DIR
)
404 if dlg
.ShowModal() == wx
.ID_OK
:
406 if isinstance(path
, unicode):
407 path
= path
.encode(sys
.getfilesystemencoding())
414 # if we already have a localconf then it needs to be
415 # copied to a new config with the new name
417 nc
= self
.CreateLocalConf(path
)
418 flag
, key
, idx
= lc
.GetFirstEntry()
420 nc
.Write(key
, lc
.Read(key
))
421 flag
, key
, idx
= lc
.GetNextEntry(idx
)
424 # otherwise create a new one
425 conf
.localconf
= self
.CreateLocalConf(path
)
428 self
.SetStatusText('Saving...')
432 tmpFile
,tmpName
= tempfile
.mkstemp(prefix
='xrced-')
434 self
.Save(tmpName
) # save temporary file first
435 shutil
.move(tmpName
, path
)
437 self
.SetModified(False)
438 if conf
.localconf
.ReadBool("autogenerate", False):
439 pypath
= conf
.localconf
.Read("filename")
440 embed
= conf
.localconf
.ReadBool("embedResource", False)
441 genGettext
= conf
.localconf
.ReadBool("genGettext", False)
442 self
.GeneratePython(self
.dataFile
, pypath
, embed
, genGettext
)
444 self
.SetStatusText('Data saved')
445 self
.SaveRecent(path
)
447 self
.SetStatusText('Failed')
451 def SaveRecent(self
,path
):
452 # append to recently used files
453 g
.fileHistory
.AddFileToHistory(path
)
455 def GeneratePython(self
, dataFile
, pypath
, embed
, genGettext
):
457 import wx
.tools
.pywxrc
458 rescomp
= wx
.tools
.pywxrc
.XmlResourceCompiler()
459 rescomp
.MakePythonModule([dataFile
], pypath
, embed
, genGettext
)
462 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
463 wx
.LogError('Error generating python code : %s' % pypath
)
467 def OnGeneratePython(self
, evt
):
468 if self
.modified
or not conf
.localconf
:
469 wx
.MessageBox("Save the XRC file first!", "Error")
472 dlg
= PythonOptions(self
, conf
.localconf
, self
.dataFile
)
476 def OnPrefs(self
, evt
):
477 dlg
= PrefsDialog(self
)
478 if dlg
.ShowModal() == wx
.ID_OK
:
479 # Fetch new preferences
480 for id,cdp
in dlg
.checkControls
.items():
482 if dlg
.FindWindowById(id).IsChecked():
483 d
[p
] = str(c
.GetValue())
484 elif p
in d
: del d
[p
]
485 g
.conf
.allowExec
= ('ask', 'yes', 'no')[dlg
.radio_allow_exec
.GetSelection()]
488 def OnExit(self
, evt
):
491 def OnUndo(self
, evt
):
492 # Extra check to not mess with idle updating
493 if undoMan
.CanUndo():
495 g
.panel
.SetModified(False)
496 if not undoMan
.CanUndo():
497 self
.SetModified(False)
499 def OnRedo(self
, evt
):
500 if undoMan
.CanRedo():
502 self
.SetModified(True)
504 def OnCopy(self
, evt
):
505 selected
= tree
.selection
506 if not selected
: return # key pressed event
507 xxx
= tree
.GetPyData(selected
)
508 if wx
.TheClipboard
.Open():
510 data
= wx
.CustomDataObject('XRCED')
511 # Set encoding in header
513 s
= xxx
.node
.toxml(encoding
=expat
.native_encoding
)
515 data
= wx
.CustomDataObject('XRCED_node')
517 data
.SetData(cPickle
.dumps(s
))
518 wx
.TheClipboard
.SetData(data
)
519 wx
.TheClipboard
.Close()
520 self
.SetStatusText('Copied')
522 wx
.MessageBox("Unable to open the clipboard", "Error")
524 def OnPaste(self
, evt
):
525 selected
= tree
.selection
526 if not selected
: return # key pressed event
527 # For pasting with Ctrl pressed
529 if evt
.GetId() == pullDownMenu
.ID_PASTE_SIBLING
: appendChild
= False
530 elif evt
.GetId() == self
.ID_TOOL_PASTE
:
531 if g
.tree
.ctrl
: appendChild
= False
532 else: appendChild
= not tree
.NeedInsert(selected
)
533 else: appendChild
= not tree
.NeedInsert(selected
)
534 xxx
= tree
.GetPyData(selected
)
536 # If has next item, insert, else append to parent
537 nextItem
= tree
.GetNextSibling(selected
)
538 parentLeaf
= tree
.GetItemParent(selected
)
539 # Expanded container (must have children)
540 elif tree
.IsExpanded(selected
) and tree
.GetChildrenCount(selected
, False):
541 # Insert as first child
542 nextItem
= tree
.GetFirstChild(selected
)[0]
543 parentLeaf
= selected
545 # No children or unexpanded item - appendChild stays True
546 nextItem
= wx
.TreeItemId() # no next item
547 parentLeaf
= selected
548 parent
= tree
.GetPyData(parentLeaf
).treeObject()
550 # Create a copy of clipboard pickled element
551 success
= success_node
= False
552 if wx
.TheClipboard
.Open():
554 data
= wx
.CustomDataObject('XRCED')
555 if wx
.TheClipboard
.IsSupported(data
.GetFormat()):
557 success
= wx
.TheClipboard
.GetData(data
)
559 # there is a problem if XRCED_node is in clipboard
560 # but previous SetData was for XRCED
562 if not success
: # try other format
563 data
= wx
.CustomDataObject('XRCED_node')
564 if wx
.TheClipboard
.IsSupported(data
.GetFormat()):
565 success_node
= wx
.TheClipboard
.GetData(data
)
567 wx
.TheClipboard
.Close()
569 if not success
and not success_node
:
571 "There is no data in the clipboard in the required format",
575 xml
= cPickle
.loads(data
.GetData()) # xml representation of element
577 elem
= minidom
.parseString(xml
).childNodes
[0]
579 elem
= g
.tree
.dom
.createComment(xml
)
581 # Tempopary xxx object to test things
582 xxx
= MakeXXXFromDOM(parent
, elem
)
584 # Check compatibility
585 if not self
.ItemsAreCompatible(parent
, xxx
.treeObject()): return
587 # Check parent and child relationships.
588 # If parent is sizer or notebook, child is of wrong class or
589 # parent is normal window, child is child container then detach child.
590 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
591 parentIsBook
= parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]
592 if isChildContainer
and \
593 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
594 (parentIsBook
and not isinstance(xxx
, xxxPage
)) or \
595 not (parent
.isSizer
or parentIsBook
)):
596 elem
.removeChild(xxx
.child
.node
) # detach child
597 elem
.unlink() # delete child container
598 elem
= xxx
.child
.node
# replace
599 # This may help garbage collection
600 xxx
.child
.parent
= None
601 isChildContainer
= False
602 # Parent is sizer or notebook, child is not child container
603 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
604 # Create sizer item element
605 sizerItemElem
= MakeEmptyDOM(parent
.itemTag
)
606 sizerItemElem
.appendChild(elem
)
608 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
609 pageElem
= MakeEmptyDOM('notebookpage')
610 pageElem
.appendChild(elem
)
612 elif isinstance(parent
, xxxChoicebook
) and not isChildContainer
:
613 pageElem
= MakeEmptyDOM('choicebookpage')
614 pageElem
.appendChild(elem
)
616 elif isinstance(parent
, xxxListbook
) and not isChildContainer
:
617 pageElem
= MakeEmptyDOM('listbookpage')
618 pageElem
.appendChild(elem
)
620 # Insert new node, register undo
621 newItem
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
)
622 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
623 # Scroll to show new item (!!! redundant?)
624 tree
.EnsureVisible(newItem
)
625 tree
.SelectItem(newItem
)
626 if not tree
.IsVisible(newItem
):
627 tree
.ScrollTo(newItem
)
630 if g
.testWin
and tree
.IsHighlatable(newItem
):
632 tree
.needUpdate
= True
633 tree
.pendingHighLight
= newItem
635 tree
.pendingHighLight
= None
637 self
.SetStatusText('Pasted')
640 def ItemsAreCompatible(self
, parent
, child
):
641 # Check compatibility
643 # Comments are always compatible
644 if child
.__class
__ == xxxComment
:
647 if child
.__class
__ in [xxxDialog
, xxxFrame
, xxxWizard
]:
649 if parent
.__class
__ != xxxMainNode
: error
= True
650 elif child
.__class
__ == xxxMenuBar
:
651 # Menubar can be put in frame or dialog
652 if parent
.__class
__ not in [xxxMainNode
, xxxFrame
, xxxDialog
]: error
= True
653 elif child
.__class
__ == xxxToolBar
:
654 # Toolbar can be top-level of child of panel or frame
655 if parent
.__class
__ not in [xxxMainNode
, xxxPanel
, xxxFrame
] and \
656 not parent
.isSizer
: error
= True
657 elif child
.__class
__ == xxxPanel
and parent
.__class
__ == xxxMainNode
:
659 elif child
.__class
__ == xxxSpacer
:
660 if not parent
.isSizer
: error
= True
661 elif child
.__class
__ == xxxSeparator
:
662 if not parent
.__class
__ in [xxxMenu
, xxxToolBar
]: error
= True
663 elif child
.__class
__ == xxxTool
:
664 if parent
.__class
__ != xxxToolBar
: error
= True
665 elif child
.__class
__ == xxxMenu
:
666 if not parent
.__class
__ in [xxxMainNode
, xxxMenuBar
, xxxMenu
]: error
= True
667 elif child
.__class
__ == xxxMenuItem
:
668 if not parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
669 elif child
.isSizer
and parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]:
671 else: # normal controls can be almost anywhere
672 if parent
.__class
__ == xxxMainNode
or \
673 parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
675 if parent
.__class
__ == xxxMainNode
: parentClass
= 'root'
676 else: parentClass
= parent
.className
677 wx
.LogError('Incompatible parent/child: parent is %s, child is %s!' %
678 (parentClass
, child
.className
))
682 def OnMoveUp(self
, evt
):
683 selected
= tree
.selection
684 if not selected
: return
686 index
= tree
.ItemIndex(selected
)
687 if index
== 0: return # No previous sibling found
690 self
.lastOp
= 'MOVEUP'
691 status
= 'Moved before previous sibling'
696 parent
= tree
.GetItemParent(selected
)
697 elem
= tree
.RemoveLeaf(selected
)
698 nextItem
= tree
.GetFirstChild(parent
)[0]
699 for i
in range(index
- 1): nextItem
= tree
.GetNextSibling(nextItem
)
700 selected
= tree
.InsertNode(parent
, tree
.GetPyData(parent
).treeObject(), elem
, nextItem
)
701 newIndex
= tree
.ItemIndex(selected
)
702 tree
.SelectItem(selected
)
704 undoMan
.RegisterUndo(UndoMove(parent
, index
, parent
, newIndex
))
707 self
.SetStatusText(status
)
711 def OnMoveDown(self
, evt
):
712 selected
= tree
.selection
713 if not selected
: return
715 index
= tree
.ItemIndex(selected
)
716 next
= tree
.GetNextSibling(selected
)
720 self
.lastOp
= 'MOVEDOWN'
721 status
= 'Moved after next sibling'
726 parent
= tree
.GetItemParent(selected
)
727 elem
= tree
.RemoveLeaf(selected
)
728 nextItem
= tree
.GetFirstChild(parent
)[0]
729 for i
in range(index
+ 1): nextItem
= tree
.GetNextSibling(nextItem
)
730 selected
= tree
.InsertNode(parent
, tree
.GetPyData(parent
).treeObject(), elem
, nextItem
)
731 newIndex
= tree
.ItemIndex(selected
)
732 tree
.SelectItem(selected
)
734 undoMan
.RegisterUndo(UndoMove(parent
, index
, parent
, newIndex
))
737 self
.SetStatusText(status
)
741 def OnMoveLeft(self
, evt
):
742 selected
= tree
.selection
743 if not selected
: return
745 oldParent
= tree
.GetItemParent(selected
)
746 if not oldParent
: return
747 pparent
= tree
.GetItemParent(oldParent
)
748 if not pparent
: return
750 # Check compatibility
751 if not self
.ItemsAreCompatible(tree
.GetPyData(pparent
).treeObject(), tree
.GetPyData(selected
).treeObject()): return
754 self
.lastOp
= 'MOVELEFT'
755 status
= 'Made next sibling of parent'
757 oldIndex
= tree
.ItemIndex(selected
)
758 elem
= tree
.RemoveLeaf(selected
)
759 nextItem
= tree
.GetFirstChild(pparent
)[0]
760 parentIndex
= tree
.ItemIndex(oldParent
)
761 for i
in range(parentIndex
+ 1): nextItem
= tree
.GetNextSibling(nextItem
)
763 # Check parent and child relationships.
764 # If parent is sizer or notebook, child is of wrong class or
765 # parent is normal window, child is child container then detach child.
766 parent
= tree
.GetPyData(pparent
).treeObject()
767 xxx
= MakeXXXFromDOM(parent
, elem
)
768 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
769 if isChildContainer
and \
770 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
771 (isinstance(parent
, xxxNotebook
) and not isinstance(xxx
, xxxNotebookPage
)) or \
772 not (parent
.isSizer
or isinstance(parent
, xxxNotebook
))):
773 elem
.removeChild(xxx
.child
.node
) # detach child
774 elem
.unlink() # delete child container
775 elem
= xxx
.child
.node
# replace
776 # This may help garbage collection
777 xxx
.child
.parent
= None
778 isChildContainer
= False
779 # Parent is sizer or notebook, child is not child container
780 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
781 # Create sizer item element
782 sizerItemElem
= MakeEmptyDOM('sizeritem')
783 sizerItemElem
.appendChild(elem
)
785 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
786 pageElem
= MakeEmptyDOM('notebookpage')
787 pageElem
.appendChild(elem
)
790 selected
= tree
.InsertNode(pparent
, tree
.GetPyData(pparent
).treeObject(), elem
, nextItem
)
791 newIndex
= tree
.ItemIndex(selected
)
792 tree
.SelectItem(selected
)
794 undoMan
.RegisterUndo(UndoMove(oldParent
, oldIndex
, pparent
, newIndex
))
797 self
.SetStatusText(status
)
799 def OnMoveRight(self
, evt
):
800 selected
= tree
.selection
801 if not selected
: return
803 oldParent
= tree
.GetItemParent(selected
)
804 if not oldParent
: return
806 newParent
= tree
.GetPrevSibling(selected
)
807 if not newParent
: return
809 parent
= tree
.GetPyData(newParent
).treeObject()
811 # Check compatibility
812 if not self
.ItemsAreCompatible(parent
, tree
.GetPyData(selected
).treeObject()): return
815 self
.lastOp
= 'MOVERIGHT'
816 status
= 'Made last child of previous sibling'
818 oldIndex
= tree
.ItemIndex(selected
)
819 elem
= tree
.RemoveLeaf(selected
)
821 # Check parent and child relationships.
822 # If parent is sizer or notebook, child is of wrong class or
823 # parent is normal window, child is child container then detach child.
824 xxx
= MakeXXXFromDOM(parent
, elem
)
825 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
826 if isChildContainer
and \
827 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
828 (isinstance(parent
, xxxNotebook
) and not isinstance(xxx
, xxxNotebookPage
)) or \
829 not (parent
.isSizer
or isinstance(parent
, xxxNotebook
))):
830 elem
.removeChild(xxx
.child
.node
) # detach child
831 elem
.unlink() # delete child container
832 elem
= xxx
.child
.node
# replace
833 # This may help garbage collection
834 xxx
.child
.parent
= None
835 isChildContainer
= False
836 # Parent is sizer or notebook, child is not child container
837 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
838 # Create sizer item element
839 sizerItemElem
= MakeEmptyDOM('sizeritem')
840 sizerItemElem
.appendChild(elem
)
842 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
843 pageElem
= MakeEmptyDOM('notebookpage')
844 pageElem
.appendChild(elem
)
847 selected
= tree
.InsertNode(newParent
, tree
.GetPyData(newParent
).treeObject(), elem
, wx
.TreeItemId())
849 newIndex
= tree
.ItemIndex(selected
)
850 tree
.SelectItem(selected
)
852 undoMan
.RegisterUndo(UndoMove(oldParent
, oldIndex
, newParent
, newIndex
))
855 self
.SetStatusText(status
)
858 def OnCutDelete(self
, evt
):
859 selected
= tree
.selection
860 if not selected
: return # key pressed event
862 if evt
.GetId() == wx
.ID_CUT
:
864 status
= 'Removed to clipboard'
866 self
.lastOp
= 'DELETE'
870 # If deleting top-level item, delete testWin
871 if selected
== g
.testWin
.item
:
875 # Remove highlight, update testWin
876 if g
.testWin
.highLight
:
877 g
.testWin
.highLight
.Remove()
878 tree
.needUpdate
= True
881 index
= tree
.ItemFullIndex(selected
)
882 xxx
= tree
.GetPyData(selected
)
883 parent
= tree
.GetPyData(tree
.GetItemParent(selected
)).treeObject()
884 elem
= tree
.RemoveLeaf(selected
)
885 undoMan
.RegisterUndo(UndoCutDelete(index
, parent
, elem
))
886 if evt
.GetId() == wx
.ID_CUT
:
887 if wx
.TheClipboard
.Open():
889 data
= wx
.CustomDataObject('XRCED')
891 s
= elem
.toxml(encoding
=expat
.native_encoding
)
893 data
= wx
.CustomDataObject('XRCED_node')
895 data
.SetData(cPickle
.dumps(s
))
896 wx
.TheClipboard
.SetData(data
)
897 wx
.TheClipboard
.Close()
899 wx
.MessageBox("Unable to open the clipboard", "Error")
900 tree
.pendingHighLight
= None
902 tree
.selection
= None
907 self
.SetStatusText(status
)
909 def OnSubclass(self
, evt
):
910 selected
= tree
.selection
911 xxx
= tree
.GetPyData(selected
).treeObject()
913 subclass
= xxx
.subclass
914 dlg
= wx
.TextEntryDialog(self
, 'Subclass:', defaultValue
=subclass
)
915 if dlg
.ShowModal() == wx
.ID_OK
:
916 subclass
= dlg
.GetValue()
918 elem
.setAttribute('subclass', subclass
)
919 elif elem
.hasAttribute('subclass'):
920 elem
.removeAttribute('subclass')
922 xxx
.subclass
= elem
.getAttribute('subclass')
923 tree
.SetItemText(selected
, xxx
.treeName())
924 panel
.pages
[0].box
.SetLabel(xxx
.panelName())
927 def OnEmbedPanel(self
, evt
):
928 conf
.embedPanel
= evt
.IsChecked()
930 # Remember last dimentions
931 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
932 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
933 size
= self
.GetSize()
934 pos
= self
.GetPosition()
935 sizePanel
= panel
.GetSize()
936 panel
.Reparent(self
.splitter
)
937 self
.miniFrame
.GetSizer().Remove(panel
)
939 self
.SetDimensions(pos
.x
, pos
.y
, size
.width
+ sizePanel
.width
, size
.height
)
940 self
.splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
941 self
.miniFrame
.Show(False)
943 conf
.sashPos
= self
.splitter
.GetSashPosition()
944 pos
= self
.GetPosition()
945 size
= self
.GetSize()
946 sizePanel
= panel
.GetSize()
947 self
.splitter
.Unsplit(panel
)
948 sizer
= self
.miniFrame
.GetSizer()
949 panel
.Reparent(self
.miniFrame
)
951 sizer
.Add(panel
, 1, wx
.EXPAND
)
952 self
.miniFrame
.Show(True)
953 self
.miniFrame
.SetDimensions(conf
.panelX
, conf
.panelY
,
954 conf
.panelWidth
, conf
.panelHeight
)
955 self
.miniFrame
.Layout()
957 self
.SetDimensions(pos
.x
, pos
.y
,
958 max(size
.width
- sizePanel
.width
, self
.minWidth
), size
.height
)
960 def OnShowTools(self
, evt
):
961 conf
.showTools
= evt
.IsChecked()
962 g
.tools
.Show(conf
.showTools
)
964 self
.toolsSizer
.Prepend(g
.tools
, 0, wx
.EXPAND
)
966 self
.toolsSizer
.Remove(g
.tools
)
967 self
.toolsSizer
.Layout()
969 def OnTest(self
, evt
):
970 if not tree
.selection
: return # key pressed event
971 tree
.ShowTestWindow(tree
.selection
)
973 def OnTestHide(self
, evt
):
974 tree
.CloseTestWindow()
976 # Find object by relative position
977 def FindObject(self
, item
, obj
):
978 # We simply perform depth-first traversal, sinse it's too much
979 # hassle to deal with all sizer/window combinations
980 w
= tree
.FindNodeObject(item
)
981 if w
== obj
or isinstance(w
, wx
.GBSizerItem
) and w
.GetWindow() == obj
:
983 if tree
.ItemHasChildren(item
):
984 child
= tree
.GetFirstChild(item
)[0]
986 found
= self
.FindObject(child
, obj
)
987 if found
: return found
988 child
= tree
.GetNextSibling(child
)
991 # Click event after locate activated
992 def OnTestWinLeftDown(self
, evt
):
993 # Restore normal event processing
994 self
.SetHandler(g
.testWin
)
995 g
.testWin
.Disconnect(wx
.ID_ANY
, wx
.ID_ANY
, wx
.wxEVT_LEFT_DOWN
)
996 item
= self
.FindObject(g
.testWin
.item
, evt
.GetEventObject())
998 tree
.EnsureVisible(item
)
999 tree
.SelectItem(item
)
1000 self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, False)
1002 self
.SetStatusText('Selected %s' % tree
.GetItemText(item
))
1004 self
.SetStatusText('Locate failed!')
1006 def SetHandler(self
, w
, h
=None):
1008 w
.SetEventHandler(h
)
1009 w
.SetCursor(wx
.CROSS_CURSOR
)
1011 w
.SetEventHandler(w
)
1012 w
.SetCursor(wx
.NullCursor
)
1013 for ch
in w
.GetChildren():
1014 self
.SetHandler(ch
, h
)
1016 def OnLocate(self
, evt
):
1018 if evt
.GetId() == self
.ID_LOCATE
or \
1019 evt
.GetId() == self
.ID_TOOL_LOCATE
and evt
.IsChecked():
1020 self
.SetHandler(g
.testWin
, g
.testWin
)
1021 g
.testWin
.Connect(wx
.ID_ANY
, wx
.ID_ANY
, wx
.wxEVT_LEFT_DOWN
, self
.OnTestWinLeftDown
)
1022 if evt
.GetId() == self
.ID_LOCATE
:
1023 self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, True)
1024 elif evt
.GetId() == self
.ID_TOOL_LOCATE
and not evt
.IsChecked():
1025 self
.SetHandler(g
.testWin
, None)
1026 g
.testWin
.Disconnect(wx
.ID_ANY
, wx
.ID_ANY
, wx
.wxEVT_LEFT_DOWN
)
1027 self
.SetStatusText('Click somewhere in your test window now')
1029 def OnRefresh(self
, evt
):
1030 # If modified, apply first
1031 selection
= tree
.selection
1033 xxx
= tree
.GetPyData(selection
)
1034 if xxx
and panel
.IsModified():
1035 tree
.Apply(xxx
, selection
)
1038 tree
.CreateTestWin(g
.testWin
.item
)
1039 panel
.modified
= False
1040 tree
.needUpdate
= False
1042 def OnAutoRefresh(self
, evt
):
1043 conf
.autoRefresh
= evt
.IsChecked()
1044 self
.menuBar
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
1045 self
.tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
1047 def OnAbout(self
, evt
):
1051 (c) Roman Rolinsky <rollrom@users.sourceforge.net>
1052 Homepage: http://xrced.sourceforge.net\
1054 dlg
= wx
.MessageDialog(self
, str, 'About XRCed', wx
.OK | wx
.CENTRE
)
1058 def OnReadme(self
, evt
):
1059 text
= open(os
.path
.join(basePath
, 'README.txt'), 'r').read()
1060 dlg
= ScrolledMessageDialog(self
, text
, "XRCed README")
1064 # Simple emulation of python command line
1065 def OnDebugCMD(self
, evt
):
1068 exec raw_input('C:\> ')
1073 (etype
, value
, tb
) =sys
.exc_info()
1074 tblist
=traceback
.extract_tb(tb
)[1:]
1075 msg
=' '.join(traceback
.format_exception_only(etype
, value
)
1076 +traceback
.format_list(tblist
))
1079 def OnCreate(self
, evt
):
1080 selected
= tree
.selection
1081 if tree
.ctrl
: appendChild
= False
1082 else: appendChild
= not tree
.NeedInsert(selected
)
1083 xxx
= tree
.GetPyData(selected
)
1087 # If has previous item, insert after it, else append to parent
1089 parentLeaf
= tree
.GetItemParent(selected
)
1091 # If has next item, insert, else append to parent
1092 nextItem
= tree
.GetNextSibling(selected
)
1093 parentLeaf
= tree
.GetItemParent(selected
)
1094 # Expanded container (must have children)
1095 elif tree
.shift
and tree
.IsExpanded(selected
) \
1096 and tree
.GetChildrenCount(selected
, False):
1097 nextItem
= tree
.GetFirstChild(selected
)[0]
1098 parentLeaf
= selected
1100 nextItem
= wx
.TreeItemId()
1101 parentLeaf
= selected
1102 parent
= tree
.GetPyData(parentLeaf
)
1103 if parent
.hasChild
: parent
= parent
.child
1105 self
.CreateXXX(parent
, parentLeaf
, nextItem
, evt
.GetId())
1107 # Actual method to create object and add to XML and wx trees
1108 def CreateXXX(self
, parent
, parentLeaf
, nextItem
, id):
1109 selected
= tree
.selection
1110 # Create object_ref?
1111 if id == ID_NEW
.REF
:
1112 ref
= wx
.GetTextFromUser('Create reference to:', 'Create reference')
1114 xxx
= MakeEmptyRefXXX(parent
, ref
)
1115 elif id == ID_NEW
.COMMENT
:
1116 xxx
= MakeEmptyCommentXXX(parent
)
1118 # Create empty element
1119 if id >= ID_NEW
.CUSTOM
:
1120 className
= pullDownMenu
.customMap
[id]
1122 className
= pullDownMenu
.createMap
[id]
1123 xxx
= MakeEmptyXXX(parent
, className
)
1125 # Insert new node, register undo
1126 if xxx
.isElement
: # true object
1127 # Set default name for top-level windows
1128 if parent
.__class
__ == xxxMainNode
:
1129 cl
= xxx
.treeObject().__class
__
1130 frame
.maxIDs
[cl
] += 1
1131 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
1132 # And for some other standard controls
1133 elif parent
.__class
__ == xxxStdDialogButtonSizer
:
1134 # ... we can even set automatically tree name
1135 xxx
.setTreeName(pullDownMenu
.stdButtonIDs
[id][0])
1136 obj
= xxx
.treeObject()
1138 elem
= g
.tree
.dom
.createElement('label')
1139 elem
.appendChild(g
.tree
.dom
.createTextNode(pullDownMenu
.stdButtonIDs
[id][1]))
1140 obj
.params
['label'] = xxxParam(elem
)
1141 xxx
.treeObject().node
.appendChild(elem
)
1142 # Else, set label if exists to class name
1143 elif 'label' in xxx
.treeObject().allParams
:
1145 if label
[:2] == 'wx': label
= label
[2:]
1146 xxx
.treeObject().set('label', label
.upper())
1147 # For comment nodes, simply add node
1148 newItem
= tree
.InsertNode(parentLeaf
, parent
, xxx
.node
, nextItem
)
1149 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
1150 tree
.EnsureVisible(newItem
)
1151 tree
.SelectItem(newItem
)
1152 if not tree
.IsVisible(newItem
):
1153 tree
.ScrollTo(newItem
)
1156 if xxx
.isElement
and g
.testWin
and tree
.IsHighlatable(newItem
):
1157 if conf
.autoRefresh
:
1158 tree
.needUpdate
= True
1159 tree
.pendingHighLight
= newItem
1161 tree
.pendingHighLight
= None
1163 if not xxx
.isElement
:
1164 tree
.EditLabel(newItem
)
1168 # Replace one object with another
1169 def OnReplace(self
, evt
):
1170 selected
= tree
.selection
1171 xxx
= tree
.GetPyData(selected
).treeObject()
1173 parent
= elem
.parentNode
1174 undoMan
.RegisterUndo(UndoReplace(selected
))
1176 className
= pullDownMenu
.createMap
[evt
.GetId() - 1000]
1178 # Create temporary empty node (with default values)
1179 dummy
= MakeEmptyDOM(className
)
1180 if className
== 'spacer' and xxx
.className
!= 'spacer':
1182 elif xxx
.className
== 'spacer' and className
!= 'spacer':
1183 klass
= xxxSizerItem
1185 klass
= xxxDict
[className
]
1186 # Remove non-compatible children
1187 if tree
.ItemHasChildren(selected
) and not klass
.hasChildren
:
1188 tree
.DeleteChildren(selected
)
1189 nodes
= elem
.childNodes
[:]
1192 if node
.nodeType
!= minidom
.Node
.ELEMENT_NODE
: continue
1196 if not klass
.hasChildren
: remove
= True
1197 elif tag
not in klass
.allParams
and \
1198 (not klass
.hasStyle
or tag
not in klass
.styles
):
1203 elem
.removeChild(node
)
1206 # Remove sizeritem child if spacer
1207 if className
== 'spacer' and xxx
.className
!= 'spacer':
1208 sizeritem
= elem
.parentNode
1209 assert sizeritem
.getAttribute('class') == 'sizeritem'
1210 sizeritem
.removeChild(elem
)
1213 tree
.GetPyData(selected
).hasChild
= False
1214 elif xxx
.className
== 'spacer' and className
!= 'spacer':
1215 # Create sizeritem element
1216 assert xxx
.parent
.isSizer
1217 elem
.setAttribute('class', 'sizeritem')
1218 node
= MakeEmptyDOM(className
)
1219 elem
.appendChild(node
)
1220 # Replace to point to new object
1221 xxx
= xxxSizerItem(xxx
.parent
, elem
)
1223 tree
.SetPyData(selected
, xxx
)
1226 # Copy parameters present in dummy but not in elem
1227 for node
in dummy
.childNodes
:
1228 if node
.tagName
not in tags
: elem
.appendChild(node
.cloneNode(True))
1232 elem
.setAttribute('class', className
)
1233 if elem
.hasAttribute('subclass'):
1234 elem
.removeAttribute('subclass') # clear subclassing
1235 # Re-create xxx element
1236 xxx
= MakeXXXFromDOM(xxx
.parent
, elem
)
1237 # Remove incompatible style flags
1238 if 'style' in xxx
.params
:
1239 styles
= map(string
.strip
, xxx
.params
['style'].value().split('|'))
1240 newStyles
= [s
for s
in styles
if s
in klass
.winStyles
or s
in genericStyles
]
1241 if newStyles
!= styles
:
1243 value
= reduce(lambda a
,b
: a
+'|'+b
, newStyles
)
1246 xxx
.params
['style'].update(value
)
1248 # Update parent in child objects
1249 if tree
.ItemHasChildren(selected
):
1250 i
, cookie
= tree
.GetFirstChild(selected
)
1252 x
= tree
.GetPyData(i
)
1254 if x
.hasChild
: x
.child
.parent
= xxx
1255 i
, cookie
= tree
.GetNextChild(selected
, cookie
)
1258 if tree
.GetPyData(selected
).hasChild
: # child container
1259 container
= tree
.GetPyData(selected
)
1260 container
.resetChild(xxx
)
1263 tree
.SetPyData(selected
, xxx
)
1264 tree
.SetItemText(selected
, xxx
.treeName())
1265 tree
.SetItemImage(selected
, xxx
.treeImage())
1267 # Set default name for top-level windows
1268 if parent
.__class
__ == xxxMainNode
:
1269 cl
= xxx
.treeObject().__class
__
1270 frame
.maxIDs
[cl
] += 1
1271 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
1274 g
.panel
.SetData(xxx
)
1278 #undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected))
1280 if g
.testWin
and tree
.IsHighlatable(selected
):
1281 if conf
.autoRefresh
:
1282 tree
.needUpdate
= True
1283 tree
.pendingHighLight
= selected
1285 tree
.pendingHighLight
= None
1289 # Expand/collapse subtree
1290 def OnExpand(self
, evt
):
1291 if tree
.selection
: tree
.ExpandAll(tree
.selection
)
1292 else: tree
.ExpandAll(tree
.root
)
1293 def OnCollapse(self
, evt
):
1294 if tree
.selection
: tree
.CollapseAll(tree
.selection
)
1295 else: tree
.CollapseAll(tree
.root
)
1297 def OnPullDownHighlight(self
, evt
):
1298 menuId
= evt
.GetMenuId()
1300 menu
= evt
.GetEventObject()
1301 help = menu
.GetHelpString(menuId
)
1302 self
.SetStatusText(help)
1304 self
.SetStatusText('')
1306 def OnUpdateUI(self
, evt
):
1307 if evt
.GetId() in [wx
.ID_CUT
, wx
.ID_COPY
, self
.ID_DELETE
]:
1308 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
1309 elif evt
.GetId() == wx
.ID_SAVE
:
1310 evt
.Enable(self
.modified
)
1311 elif evt
.GetId() in [wx
.ID_PASTE
, self
.ID_TOOL_PASTE
]:
1312 evt
.Enable(tree
.selection
is not None)
1313 elif evt
.GetId() == self
.ID_TEST
:
1314 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
1315 elif evt
.GetId() in [self
.ID_LOCATE
, self
.ID_TOOL_LOCATE
]:
1316 evt
.Enable(g
.testWin
is not None)
1317 elif evt
.GetId() == wx
.ID_UNDO
: evt
.Enable(undoMan
.CanUndo())
1318 elif evt
.GetId() == wx
.ID_REDO
: evt
.Enable(undoMan
.CanRedo())
1320 def OnIdle(self
, evt
):
1321 if self
.inIdle
: return # Recursive call protection
1325 if conf
.autoRefresh
:
1327 #self.SetStatusText('Refreshing test window...')
1329 tree
.CreateTestWin(g
.testWin
.item
)
1330 #self.SetStatusText('')
1331 tree
.needUpdate
= False
1332 elif tree
.pendingHighLight
:
1334 tree
.HighLight(tree
.pendingHighLight
)
1336 # Remove highlight if any problem
1337 if g
.testWin
.highLight
:
1338 g
.testWin
.highLight
.Remove()
1339 tree
.pendingHighLight
= None
1346 # We don't let close panel window
1347 def OnCloseMiniFrame(self
, evt
):
1350 def OnIconize(self
, evt
):
1352 conf
.x
, conf
.y
= self
.GetPosition()
1353 conf
.width
, conf
.height
= self
.GetSize()
1355 conf
.sashPos
= self
.splitter
.GetSashPosition()
1357 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1358 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1359 self
.miniFrame
.Iconize()
1361 if not conf
.embedPanel
:
1362 self
.miniFrame
.Iconize(False)
1365 def OnCloseWindow(self
, evt
):
1366 if not self
.AskSave(): return
1367 if g
.testWin
: g
.testWin
.Destroy()
1368 if not panel
.GetPageCount() == 2:
1369 panel
.page2
.Destroy()
1371 # If we don't do this, page does not get destroyed (a bug?)
1373 if not self
.IsIconized():
1374 conf
.x
, conf
.y
= self
.GetPosition()
1375 conf
.width
, conf
.height
= self
.GetSize()
1377 conf
.sashPos
= self
.splitter
.GetSashPosition()
1379 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1380 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1383 def CreateLocalConf(self
, path
):
1384 name
= os
.path
.splitext(path
)[0]
1386 return wx
.FileConfig(localFilename
=name
)
1390 conf
.localconf
= None
1392 self
.SetModified(False)
1398 # Numbers for new controls
1400 for cl
in [xxxPanel
, xxxDialog
, xxxFrame
,
1401 xxxMenuBar
, xxxMenu
, xxxToolBar
,
1402 xxxWizard
, xxxBitmap
, xxxIcon
]:
1404 # Restore handlers, menu, etc. to initial
1405 setHandlers(self
.handlers
[:])
1406 g
.pullDownMenu
.custom
= self
.custom
[:]
1407 # Remove modules imported from comment directives
1408 map(sys
.modules
.pop
, [m
for m
in sys
.modules
if m
not in self
.modules
])
1409 xxxParamComment
.locals = {} # clear local namespace
1410 xxxParamComment
.allow
= None # clear execution state
1412 def SetModified(self
, state
=True):
1413 self
.modified
= state
1414 name
= os
.path
.basename(self
.dataFile
)
1415 if not name
: name
= defaultName
1417 self
.SetTitle(progname
+ ': ' + name
+ ' *')
1419 self
.SetTitle(progname
+ ': ' + name
)
1421 def Open(self
, path
):
1422 if not os
.path
.exists(path
):
1423 wx
.LogError('File does not exists: %s' % path
)
1425 # Try to read the file
1429 dom
= minidom
.parse(f
)
1431 # Set encoding global variable and default encoding
1433 g
.currentEncoding
= dom
.encoding
1434 wx
.SetDefaultPyEncoding(g
.currentEncoding
.encode())
1436 g
.currentEncoding
= ''
1438 self
.dataFile
= path
= os
.path
.abspath(path
)
1439 dir = os
.path
.dirname(path
)
1440 if dir: os
.chdir(dir)
1441 # Allow importing modules from the same directory
1442 sys
.path
= sys_path
+ [dir]
1444 self
.SetTitle(progname
+ ': ' + os
.path
.basename(path
))
1445 conf
.localconf
= self
.CreateLocalConf(self
.dataFile
)
1447 # Nice exception printing
1448 inf
= sys
.exc_info()
1449 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1450 wx
.LogError('Error reading file: %s' % path
)
1455 def Indent(self
, node
, indent
= 0):
1456 if node
.nodeType
== minidom
.Node
.COMMENT_NODE
:
1457 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1458 node
.parentNode
.insertBefore(text
, node
)
1459 return # no children
1460 # Copy child list because it will change soon
1461 children
= node
.childNodes
[:]
1462 # Main node doesn't need to be indented
1464 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1465 node
.parentNode
.insertBefore(text
, node
)
1467 # Append newline after last child, except for text nodes
1468 if children
[-1].nodeType
== minidom
.Node
.ELEMENT_NODE
:
1469 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1470 node
.appendChild(text
)
1471 # Indent children which are elements
1473 if n
.nodeType
== minidom
.Node
.ELEMENT_NODE
or \
1474 n
.nodeType
== minidom
.Node
.COMMENT_NODE
:
1475 self
.Indent(n
, indent
+ 2)
1477 def Save(self
, path
):
1481 if tree
.selection
and panel
.IsModified():
1482 self
.OnRefresh(wx
.CommandEvent())
1483 if g
.currentEncoding
:
1484 f
= codecs
.open(path
, 'wt', g
.currentEncoding
)
1486 f
= codecs
.open(path
, 'wt')
1487 # Make temporary copy for formatting it
1488 # !!! We can't clone dom node, it works only once
1489 #self.domCopy = tree.dom.cloneNode(True)
1490 self
.domCopy
= MyDocument()
1491 mainNode
= self
.domCopy
.appendChild(tree
.mainNode
.cloneNode(True))
1492 # Remove first child (test element)
1493 testElem
= mainNode
.firstChild
1494 mainNode
.removeChild(testElem
)
1496 self
.Indent(mainNode
)
1497 self
.domCopy
.writexml(f
, encoding
= g
.currentEncoding
)
1499 self
.domCopy
.unlink()
1501 self
.SetModified(False)
1502 panel
.SetModified(False)
1503 conf
.localconf
.Flush()
1505 inf
= sys
.exc_info()
1506 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1507 wx
.LogError('Error writing file: %s' % path
)
1511 if not (self
.modified
or panel
.IsModified()): return True
1512 flags
= wx
.ICON_EXCLAMATION | wx
.YES_NO | wx
.CANCEL | wx
.CENTRE
1513 dlg
= wx
.MessageDialog( self
, 'File is modified. Save before exit?',
1514 'Save before too late?', flags
)
1515 say
= dlg
.ShowModal()
1518 if say
== wx
.ID_YES
:
1519 self
.OnSaveOrSaveAs(wx
.CommandEvent(wx
.ID_SAVE
))
1520 # If save was successful, modified flag is unset
1521 if not self
.modified
: return True
1522 elif say
== wx
.ID_NO
:
1523 self
.SetModified(False)
1524 panel
.SetModified(False)
1528 ################################################################################
1530 class PythonOptions(wx
.Dialog
):
1532 def __init__(self
, parent
, cfg
, dataFile
):
1533 pre
= wx
.PreDialog()
1534 g
.frame
.res
.LoadOnDialog(pre
, parent
, "PYTHON_OPTIONS")
1535 self
.PostCreate(pre
)
1538 self
.dataFile
= dataFile
1540 self
.AutoGenerateCB
= xrc
.XRCCTRL(self
, "AutoGenerateCB")
1541 self
.EmbedCB
= xrc
.XRCCTRL(self
, "EmbedCB")
1542 self
.GettextCB
= xrc
.XRCCTRL(self
, "GettextCB")
1543 self
.MakeXRSFileCB
= xrc
.XRCCTRL(self
, "MakeXRSFileCB")
1544 self
.FileNameTC
= xrc
.XRCCTRL(self
, "FileNameTC")
1545 self
.BrowseBtn
= xrc
.XRCCTRL(self
, "BrowseBtn")
1546 self
.GenerateBtn
= xrc
.XRCCTRL(self
, "GenerateBtn")
1547 self
.SaveOptsBtn
= xrc
.XRCCTRL(self
, "SaveOptsBtn")
1549 self
.Bind(wx
.EVT_BUTTON
, self
.OnBrowse
, self
.BrowseBtn
)
1550 self
.Bind(wx
.EVT_BUTTON
, self
.OnGenerate
, self
.GenerateBtn
)
1551 self
.Bind(wx
.EVT_BUTTON
, self
.OnSaveOpts
, self
.SaveOptsBtn
)
1553 if self
.cfg
.Read("filename", "") != "":
1554 self
.FileNameTC
.SetValue(self
.cfg
.Read("filename"))
1556 name
= os
.path
.splitext(os
.path
.split(dataFile
)[1])[0]
1558 self
.FileNameTC
.SetValue(name
)
1559 self
.AutoGenerateCB
.SetValue(self
.cfg
.ReadBool("autogenerate", False))
1560 self
.EmbedCB
.SetValue(self
.cfg
.ReadBool("embedResource", False))
1561 self
.MakeXRSFileCB
.SetValue(self
.cfg
.ReadBool("makeXRS", False))
1562 self
.GettextCB
.SetValue(self
.cfg
.ReadBool("genGettext", False))
1565 def OnBrowse(self
, evt
):
1566 path
= self
.FileNameTC
.GetValue()
1567 dirname
= os
.path
.abspath(os
.path
.dirname(path
))
1568 name
= os
.path
.split(path
)[1]
1569 dlg
= wx
.FileDialog(self
, 'Save As', dirname
, name
, '*.py',
1570 wx
.SAVE | wx
.OVERWRITE_PROMPT
)
1571 if dlg
.ShowModal() == wx
.ID_OK
:
1572 path
= dlg
.GetPath()
1573 self
.FileNameTC
.SetValue(path
)
1577 def OnGenerate(self
, evt
):
1578 pypath
= self
.FileNameTC
.GetValue()
1579 embed
= self
.EmbedCB
.GetValue()
1580 genGettext
= self
.GettextCB
.GetValue()
1581 frame
.GeneratePython(self
.dataFile
, pypath
, embed
, genGettext
)
1585 def OnSaveOpts(self
, evt
=None):
1586 self
.cfg
.Write("filename", self
.FileNameTC
.GetValue())
1587 self
.cfg
.WriteBool("autogenerate", self
.AutoGenerateCB
.GetValue())
1588 self
.cfg
.WriteBool("embedResource", self
.EmbedCB
.GetValue())
1589 self
.cfg
.WriteBool("makeXRS", self
.MakeXRSFileCB
.GetValue())
1590 self
.cfg
.WriteBool("genGettext", self
.GettextCB
.GetValue())
1592 self
.EndModal(wx
.ID_OK
)
1594 ################################################################################
1596 class PrefsDialog(wx
.Dialog
):
1598 def __init__(self
, parent
):
1599 pre
= wx
.PreDialog()
1600 g
.frame
.res
.LoadOnDialog(pre
, parent
, "DIALOG_PREFS")
1601 self
.PostCreate(pre
)
1602 self
.checkControls
= {} # map of check IDs to (control,dict,param)
1604 ##xxx = sys.modules['xxx']
1606 d
= xxx
.xxxSizerItem
.defaults_panel
1608 self
.check_proportion_panel
= xrc
.XRCCTRL(self
, 'check_proportion_panel')
1609 id = self
.check_proportion_panel
.GetId()
1610 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1611 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'spin_proportion_panel'),
1614 self
.check_flag_panel
= xrc
.XRCCTRL(self
, 'check_flag_panel')
1615 id = self
.check_flag_panel
.GetId()
1616 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1617 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'text_flag_panel'),
1620 d
= xxx
.xxxSizerItem
.defaults_control
1622 self
.check_proportion_panel
= xrc
.XRCCTRL(self
, 'check_proportion_control')
1623 id = self
.check_proportion_panel
.GetId()
1624 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1625 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'spin_proportion_control'),
1628 self
.check_flag_panel
= xrc
.XRCCTRL(self
, 'check_flag_control')
1629 id = self
.check_flag_panel
.GetId()
1630 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1631 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'text_flag_control'),
1634 for id,cdp
in self
.checkControls
.items():
1637 if isinstance(c
, wx
.SpinCtrl
):
1638 c
.SetValue(int(d
[p
]))
1641 self
.FindWindowById(id).SetValue(True)
1645 self
.radio_allow_exec
= xrc
.XRCCTRL(self
, 'radio_allow_exec')
1647 radio
= {'ask': 0, 'yes':1, 'no':2}
[g
.conf
.allowExec
]
1650 self
.radio_allow_exec
.SetSelection(radio
)
1652 def OnCheck(self
, evt
):
1653 self
.checkControls
[evt
.GetId()][0].Enable(evt
.IsChecked())
1656 ################################################################################
1658 # Parse string in form var1=val1[,var2=val2]* as dictionary
1659 def ReadDictFromString(s
):
1661 for vv
in s
.split(','):
1662 var
,val
= vv
.split(':')
1663 d
[var
.strip()] = val
1666 # Transform dictionary with strings into one string
1667 def DictToString(d
):
1668 return ','.join(map(':'.join
, d
.items()))
1671 print >> sys
.stderr
, 'usage: xrced [-dhiv] [file]'
1676 if wx
.VERSION
[:3] < MinWxVersion
:
1678 This version of XRCed may not work correctly on your version of wxWidgets. \
1679 Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion
)
1681 # Process comand-line
1684 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'dhiv')
1692 print 'XRCed version', version
1695 except getopt
.GetoptError
:
1696 if wx
.Platform
!= '__WXMAC__': # macs have some extra parameters
1697 print >> sys
.stderr
, 'Unknown option'
1701 self
.SetAppName('xrced')
1704 conf
= g
.conf
= wx
.Config(style
= wx
.CONFIG_USE_LOCAL_FILE
)
1705 conf
.localconf
= None
1706 conf
.autoRefresh
= conf
.ReadInt('autorefresh', True)
1707 pos
= conf
.ReadInt('x', -1), conf
.ReadInt('y', -1)
1708 size
= conf
.ReadInt('width', 800), conf
.ReadInt('height', 600)
1709 conf
.embedPanel
= conf
.ReadInt('embedPanel', True)
1710 conf
.showTools
= conf
.ReadInt('showTools', True)
1711 conf
.sashPos
= conf
.ReadInt('sashPos', 200)
1713 # read recently used files
1714 g
.fileHistory
= wx
.FileHistory()
1715 g
.fileHistory
.Load(conf
)
1717 if not conf
.embedPanel
:
1718 conf
.panelX
= conf
.ReadInt('panelX', -1)
1719 conf
.panelY
= conf
.ReadInt('panelY', -1)
1721 conf
.panelX
= conf
.panelY
= -1
1722 conf
.panelWidth
= conf
.ReadInt('panelWidth', 200)
1723 conf
.panelHeight
= conf
.ReadInt('panelHeight', 200)
1724 conf
.panic
= not conf
.HasEntry('nopanic')
1726 conf
.allowExec
= conf
.Read('Prefs/allowExec', 'ask')
1727 p
= 'Prefs/sizeritem_defaults_panel'
1729 if conf
.HasEntry(p
):
1730 ##sys.modules['xxx'].xxxSizerItem.defaults_panel = ReadDictFromString(conf.Read(p))
1731 xxx
.xxxSizerItem
.defaults_panel
= ReadDictFromString(conf
.Read(p
))
1732 p
= 'Prefs/sizeritem_defaults_control'
1733 if conf
.HasEntry(p
):
1734 ##sys.modules['xxx'].xxxSizerItem.defaults_control = ReadDictFromString(conf.Read(p))
1735 xxx
.xxxSizerItem
.defaults_control
= ReadDictFromString(conf
.Read(p
))
1738 wx
.FileSystem
.AddHandler(wx
.MemoryFSHandler())
1740 frame
= Frame(pos
, size
)
1744 plugins
= os
.getenv('XRCEDPATH')
1748 for dir in plugins
.split(':'):
1749 if os
.path
.isdir(dir) and \
1750 os
.path
.isfile(os
.path
.join(dir, '__init__.py')):
1752 dir = os
.path
.abspath(os
.path
.normpath(dir))
1753 sys
.path
= sys_path
+ [os
.path
.dirname(dir)]
1756 __import__(os
.path
.basename(dir), globals(), locals(), ['*'])
1758 print traceback
.print_exc()
1761 # Store important data
1762 frame
.handlers
= getHandlers()[:]
1763 frame
.custom
= g
.pullDownMenu
.custom
[:]
1764 frame
.modules
= sys
.modules
.copy()
1769 # Load file after showing
1772 frame
.open = frame
.Open(args
[0])
1780 wc
.WriteInt('autorefresh', conf
.autoRefresh
)
1781 wc
.WriteInt('x', conf
.x
)
1782 wc
.WriteInt('y', conf
.y
)
1783 wc
.WriteInt('width', conf
.width
)
1784 wc
.WriteInt('height', conf
.height
)
1785 wc
.WriteInt('embedPanel', conf
.embedPanel
)
1786 wc
.WriteInt('showTools', conf
.showTools
)
1787 if not conf
.embedPanel
:
1788 wc
.WriteInt('panelX', conf
.panelX
)
1789 wc
.WriteInt('panelY', conf
.panelY
)
1790 wc
.WriteInt('sashPos', conf
.sashPos
)
1791 wc
.WriteInt('panelWidth', conf
.panelWidth
)
1792 wc
.WriteInt('panelHeight', conf
.panelHeight
)
1793 wc
.WriteInt('nopanic', 1)
1794 g
.fileHistory
.Save(wc
)
1796 wc
.DeleteGroup('Prefs')
1797 wc
.Write('Prefs/allowExec', conf
.allowExec
)
1799 ##v = sys.modules['xxx'].xxxSizerItem.defaults_panel
1800 v
= xxx
.xxxSizerItem
.defaults_panel
1801 if v
: wc
.Write('Prefs/sizeritem_defaults_panel', DictToString(v
))
1802 ###v = sys.modules['xxx'].xxxSizerItem.defaults_control
1803 v
= xxx
.xxxSizerItem
.defaults_control
1804 if v
: wc
.Write('Prefs/sizeritem_defaults_control', DictToString(v
))
1809 app
= App(0, useBestVisual
=False)
1810 #app.SetAssertMode(wx.PYAPP_ASSERT_LOG)
1816 if __name__
== '__main__':