]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/XRCed/xrced.py
c41e9592cca721a098a659134445240fa7a6381c
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
.XmlResource('')
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')
123 self
.recentMenu
= wx
.Menu()
124 self
.AppendRecent(self
.recentMenu
)
125 menu
.AppendMenu(-1, 'Open Recent', self
.recentMenu
, 'Open a recent file')
126 menu
.AppendSeparator()
127 menu
.Append(wx
.ID_SAVE
, '&Save\tCtrl-S', 'Save XRC file')
128 menu
.Append(wx
.ID_SAVEAS
, 'Save &As...', 'Save XRC file under different name')
129 self
.ID_GENERATE_PYTHON
= wx
.NewId()
130 menu
.Append(self
.ID_GENERATE_PYTHON
, '&Generate Python...',
131 'Generate a Python module that uses this XRC')
132 menu
.AppendSeparator()
133 self
.ID_PREFS
= wx
.NewId()
134 menu
.Append(self
.ID_PREFS
, 'Preferences...', 'Change XRCed settings')
135 menu
.AppendSeparator()
136 menu
.Append(wx
.ID_EXIT
, '&Quit\tCtrl-Q', 'Exit application')
138 menuBar
.Append(menu
, '&File')
141 menu
.Append(wx
.ID_UNDO
, '&Undo\tCtrl-Z', 'Undo')
142 menu
.Append(wx
.ID_REDO
, '&Redo\tCtrl-Y', 'Redo')
143 menu
.AppendSeparator()
144 menu
.Append(wx
.ID_CUT
, 'Cut\tCtrl-X', 'Cut to the clipboard')
145 menu
.Append(wx
.ID_COPY
, '&Copy\tCtrl-C', 'Copy to the clipboard')
146 menu
.Append(wx
.ID_PASTE
, '&Paste\tCtrl-V', 'Paste from the clipboard')
147 self
.ID_DELETE
= wx
.NewId()
148 menu
.Append(self
.ID_DELETE
, '&Delete\tCtrl-D', 'Delete object')
149 menu
.AppendSeparator()
150 self
.ID_LOCATE
= wx
.NewId()
151 self
.ID_TOOL_LOCATE
= wx
.NewId()
152 self
.ID_TOOL_PASTE
= wx
.NewId()
153 menu
.Append(self
.ID_LOCATE
, '&Locate\tCtrl-L', 'Locate control in test window and select it')
154 menuBar
.Append(menu
, '&Edit')
157 self
.ID_EMBED_PANEL
= wx
.NewId()
158 menu
.Append(self
.ID_EMBED_PANEL
, '&Embed Panel',
159 'Toggle embedding properties panel in the main window', True)
160 menu
.Check(self
.ID_EMBED_PANEL
, conf
.embedPanel
)
161 self
.ID_SHOW_TOOLS
= wx
.NewId()
162 menu
.Append(self
.ID_SHOW_TOOLS
, 'Show &Tools', 'Toggle tools', True)
163 menu
.Check(self
.ID_SHOW_TOOLS
, conf
.showTools
)
164 menu
.AppendSeparator()
165 self
.ID_TEST
= wx
.NewId()
166 menu
.Append(self
.ID_TEST
, '&Test\tF5', 'Show test window')
167 self
.ID_REFRESH
= wx
.NewId()
168 menu
.Append(self
.ID_REFRESH
, '&Refresh\tCtrl-R', 'Refresh test window')
169 self
.ID_AUTO_REFRESH
= wx
.NewId()
170 menu
.Append(self
.ID_AUTO_REFRESH
, '&Auto-refresh\tAlt-A',
171 'Toggle auto-refresh mode', True)
172 menu
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
173 self
.ID_TEST_HIDE
= wx
.NewId()
174 menu
.Append(self
.ID_TEST_HIDE
, '&Hide\tF6', 'Close test window')
175 menuBar
.Append(menu
, '&View')
178 self
.ID_MOVEUP
= wx
.NewId()
179 menu
.Append(self
.ID_MOVEUP
, '&Up', 'Move before previous sibling')
180 self
.ID_MOVEDOWN
= wx
.NewId()
181 menu
.Append(self
.ID_MOVEDOWN
, '&Down', 'Move after next sibling')
182 self
.ID_MOVELEFT
= wx
.NewId()
183 menu
.Append(self
.ID_MOVELEFT
, '&Make sibling', 'Make sibling of parent')
184 self
.ID_MOVERIGHT
= wx
.NewId()
185 menu
.Append(self
.ID_MOVERIGHT
, '&Make child', 'Make child of previous sibling')
186 menuBar
.Append(menu
, '&Move')
189 menu
.Append(wx
.ID_ABOUT
, '&About...', 'About XCRed')
190 self
.ID_README
= wx
.NewId()
191 menu
.Append(self
.ID_README
, '&Readme...\tF1', 'View the README file')
193 self
.ID_DEBUG_CMD
= wx
.NewId()
194 menu
.Append(self
.ID_DEBUG_CMD
, 'CMD', 'Python command line')
195 wx
.EVT_MENU(self
, self
.ID_DEBUG_CMD
, self
.OnDebugCMD
)
196 menuBar
.Append(menu
, '&Help')
198 self
.menuBar
= menuBar
199 self
.SetMenuBar(menuBar
)
202 tb
= self
.CreateToolBar(wx
.TB_HORIZONTAL | wx
.NO_BORDER | wx
.TB_FLAT
)
203 tb
.SetToolBitmapSize((24,24))
204 new_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_NORMAL_FILE
, wx
.ART_TOOLBAR
)
205 open_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_OPEN
, wx
.ART_TOOLBAR
)
206 save_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_SAVE
, wx
.ART_TOOLBAR
)
207 undo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_UNDO
, wx
.ART_TOOLBAR
)
208 redo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_REDO
, wx
.ART_TOOLBAR
)
209 cut_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_CUT
, wx
.ART_TOOLBAR
)
210 copy_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_COPY
, wx
.ART_TOOLBAR
)
211 paste_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_PASTE
, wx
.ART_TOOLBAR
)
213 tb
.AddSimpleTool(wx
.ID_NEW
, new_bmp
, 'New', 'New file')
214 tb
.AddSimpleTool(wx
.ID_OPEN
, open_bmp
, 'Open', 'Open file')
215 tb
.AddSimpleTool(wx
.ID_SAVE
, save_bmp
, 'Save', 'Save file')
216 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
217 tb
.AddSimpleTool(wx
.ID_UNDO
, undo_bmp
, 'Undo', 'Undo')
218 tb
.AddSimpleTool(wx
.ID_REDO
, redo_bmp
, 'Redo', 'Redo')
219 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
220 tb
.AddSimpleTool(wx
.ID_CUT
, cut_bmp
, 'Cut', 'Cut')
221 tb
.AddSimpleTool(wx
.ID_COPY
, copy_bmp
, 'Copy', 'Copy')
222 tb
.AddSimpleTool(self
.ID_TOOL_PASTE
, paste_bmp
, 'Paste', 'Paste')
223 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
224 tb
.AddSimpleTool(self
.ID_TOOL_LOCATE
,
225 images
.getLocateBitmap(), #images.getLocateArmedBitmap(),
226 'Locate', 'Locate control in test window and select it', True)
227 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
228 tb
.AddSimpleTool(self
.ID_TEST
, images
.getTestBitmap(), 'Test', 'Test window')
229 tb
.AddSimpleTool(self
.ID_REFRESH
, images
.getRefreshBitmap(),
230 'Refresh', 'Refresh view')
231 tb
.AddSimpleTool(self
.ID_AUTO_REFRESH
, images
.getAutoRefreshBitmap(),
232 'Auto-refresh', 'Toggle auto-refresh mode', True)
233 tb
.AddControl(wx
.StaticLine(tb
, -1, size
=(-1,23), style
=wx
.LI_VERTICAL
))
234 tb
.AddSimpleTool(self
.ID_MOVEUP
, images
.getToolMoveUpBitmap(),
235 'Up', 'Move before previous sibling')
236 tb
.AddSimpleTool(self
.ID_MOVEDOWN
, images
.getToolMoveDownBitmap(),
237 'Down', 'Move after next sibling')
238 tb
.AddSimpleTool(self
.ID_MOVELEFT
, images
.getToolMoveLeftBitmap(),
239 'Make Sibling', 'Make sibling of parent')
240 tb
.AddSimpleTool(self
.ID_MOVERIGHT
, images
.getToolMoveRightBitmap(),
241 'Make Child', 'Make child of previous sibling')
242 # if wx.Platform == '__WXGTK__':
243 # tb.AddSeparator() # otherwise auto-refresh sticks in status line
244 tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
248 self
.minWidth
= tb
.GetSize()[0] # minimal width is the size of toolbar
251 wx
.EVT_MENU(self
, wx
.ID_NEW
, self
.OnNew
)
252 wx
.EVT_MENU(self
, wx
.ID_OPEN
, self
.OnOpen
)
253 wx
.EVT_MENU(self
, wx
.ID_SAVE
, self
.OnSaveOrSaveAs
)
254 wx
.EVT_MENU(self
, wx
.ID_SAVEAS
, self
.OnSaveOrSaveAs
)
255 wx
.EVT_MENU(self
, self
.ID_GENERATE_PYTHON
, self
.OnGeneratePython
)
256 wx
.EVT_MENU(self
, self
.ID_PREFS
, self
.OnPrefs
)
257 wx
.EVT_MENU(self
, wx
.ID_EXIT
, self
.OnExit
)
259 wx
.EVT_MENU(self
, wx
.ID_UNDO
, self
.OnUndo
)
260 wx
.EVT_MENU(self
, wx
.ID_REDO
, self
.OnRedo
)
261 wx
.EVT_MENU(self
, wx
.ID_CUT
, self
.OnCutDelete
)
262 wx
.EVT_MENU(self
, wx
.ID_COPY
, self
.OnCopy
)
263 wx
.EVT_MENU(self
, wx
.ID_PASTE
, self
.OnPaste
)
264 wx
.EVT_MENU(self
, self
.ID_TOOL_PASTE
, self
.OnPaste
)
265 wx
.EVT_MENU(self
, self
.ID_DELETE
, self
.OnCutDelete
)
266 wx
.EVT_MENU(self
, self
.ID_LOCATE
, self
.OnLocate
)
267 wx
.EVT_MENU(self
, self
.ID_TOOL_LOCATE
, self
.OnLocate
)
269 wx
.EVT_MENU(self
, self
.ID_EMBED_PANEL
, self
.OnEmbedPanel
)
270 wx
.EVT_MENU(self
, self
.ID_SHOW_TOOLS
, self
.OnShowTools
)
271 wx
.EVT_MENU(self
, self
.ID_TEST
, self
.OnTest
)
272 wx
.EVT_MENU(self
, self
.ID_REFRESH
, self
.OnRefresh
)
273 wx
.EVT_MENU(self
, self
.ID_AUTO_REFRESH
, self
.OnAutoRefresh
)
274 wx
.EVT_MENU(self
, self
.ID_TEST_HIDE
, self
.OnTestHide
)
276 wx
.EVT_MENU(self
, self
.ID_MOVEUP
, self
.OnMoveUp
)
277 wx
.EVT_MENU(self
, self
.ID_MOVEDOWN
, self
.OnMoveDown
)
278 wx
.EVT_MENU(self
, self
.ID_MOVELEFT
, self
.OnMoveLeft
)
279 wx
.EVT_MENU(self
, self
.ID_MOVERIGHT
, self
.OnMoveRight
)
281 wx
.EVT_MENU(self
, wx
.ID_ABOUT
, self
.OnAbout
)
282 wx
.EVT_MENU(self
, self
.ID_README
, self
.OnReadme
)
285 wx
.EVT_UPDATE_UI(self
, wx
.ID_SAVE
, self
.OnUpdateUI
)
286 wx
.EVT_UPDATE_UI(self
, wx
.ID_CUT
, self
.OnUpdateUI
)
287 wx
.EVT_UPDATE_UI(self
, wx
.ID_COPY
, self
.OnUpdateUI
)
288 wx
.EVT_UPDATE_UI(self
, wx
.ID_PASTE
, self
.OnUpdateUI
)
289 wx
.EVT_UPDATE_UI(self
, self
.ID_LOCATE
, self
.OnUpdateUI
)
290 wx
.EVT_UPDATE_UI(self
, self
.ID_TOOL_LOCATE
, self
.OnUpdateUI
)
291 wx
.EVT_UPDATE_UI(self
, self
.ID_TOOL_PASTE
, self
.OnUpdateUI
)
292 wx
.EVT_UPDATE_UI(self
, wx
.ID_UNDO
, self
.OnUpdateUI
)
293 wx
.EVT_UPDATE_UI(self
, wx
.ID_REDO
, self
.OnUpdateUI
)
294 wx
.EVT_UPDATE_UI(self
, self
.ID_DELETE
, self
.OnUpdateUI
)
295 wx
.EVT_UPDATE_UI(self
, self
.ID_TEST
, self
.OnUpdateUI
)
296 wx
.EVT_UPDATE_UI(self
, self
.ID_REFRESH
, self
.OnUpdateUI
)
299 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
300 sizer
.Add(wx
.StaticLine(self
, -1), 0, wx
.EXPAND
)
301 # Horizontal sizer for toolbar and splitter
302 self
.toolsSizer
= sizer1
= wx
.BoxSizer()
303 splitter
= wx
.SplitterWindow(self
, -1, style
=wx
.SP_3DSASH
)
304 self
.splitter
= splitter
305 splitter
.SetMinimumPaneSize(100)
308 g
.tree
= tree
= XML_Tree(splitter
, -1)
310 # Init pull-down menu data
312 g
.pullDownMenu
= pullDownMenu
= PullDownMenu(self
)
314 # Vertical toolbar for GUI buttons
315 g
.tools
= tools
= Tools(self
)
316 tools
.Show(conf
.showTools
)
317 if conf
.showTools
: sizer1
.Add(tools
, 0, wx
.EXPAND
)
319 tree
.RegisterKeyEvents()
321 # Miniframe for split mode
322 miniFrame
= wx
.MiniFrame(self
, -1, 'Properties & Style',
323 (conf
.panelX
, conf
.panelY
),
324 (conf
.panelWidth
, conf
.panelHeight
))
325 self
.miniFrame
= miniFrame
326 sizer2
= wx
.BoxSizer()
327 miniFrame
.SetAutoLayout(True)
328 miniFrame
.SetSizer(sizer2
)
329 wx
.EVT_CLOSE(self
.miniFrame
, self
.OnCloseMiniFrame
)
330 # Create panel for parameters
333 panel
= Panel(splitter
)
334 # Set plitter windows
335 splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
337 panel
= Panel(miniFrame
)
338 sizer2
.Add(panel
, 1, wx
.EXPAND
)
340 splitter
.Initialize(tree
)
341 sizer1
.Add(splitter
, 1, wx
.EXPAND
)
342 sizer
.Add(sizer1
, 1, wx
.EXPAND
)
343 self
.SetAutoLayout(True)
347 wx
.EVT_IDLE(self
, self
.OnIdle
)
348 wx
.EVT_CLOSE(self
, self
.OnCloseWindow
)
349 wx
.EVT_KEY_DOWN(self
, tools
.OnKeyDown
)
350 wx
.EVT_KEY_UP(self
, tools
.OnKeyUp
)
351 wx
.EVT_ICONIZE(self
, self
.OnIconize
)
353 def AppendRecent(self
, menu
):
354 # add recently used files to the menu
355 for id,name
in conf
.recentfiles
.iteritems():
357 wx
.EVT_MENU(self
,id,self
.OnRecentFile
)
360 def OnRecentFile(self
,evt
):
361 # open recently used file
362 if not self
.AskSave(): return
365 path
=conf
.recentfiles
[evt
.GetId()]
367 self
.SetStatusText('Data loaded')
369 self
.SetStatusText('Failed')
371 self
.SetStatusText('No such file')
374 def OnNew(self
, evt
):
375 if not self
.AskSave(): return
378 def OnOpen(self
, evt
):
379 if not self
.AskSave(): return
380 dlg
= wx
.FileDialog(self
, 'Open', os
.path
.dirname(self
.dataFile
),
381 '', '*.xrc', wx
.OPEN | wx
.CHANGE_DIR
)
382 if dlg
.ShowModal() == wx
.ID_OK
:
384 self
.SetStatusText('Loading...')
388 self
.SetStatusText('Data loaded')
390 self
.SetStatusText('Failed')
391 self
.SaveRecent(path
)
396 def OnSaveOrSaveAs(self
, evt
):
397 if evt
.GetId() == wx
.ID_SAVEAS
or not self
.dataFile
:
398 if self
.dataFile
: name
= ''
399 else: name
= defaultName
400 dirname
= os
.path
.abspath(os
.path
.dirname(self
.dataFile
))
401 dlg
= wx
.FileDialog(self
, 'Save As', dirname
, name
, '*.xrc',
402 wx
.SAVE | wx
.OVERWRITE_PROMPT | wx
.CHANGE_DIR
)
403 if dlg
.ShowModal() == wx
.ID_OK
:
405 if isinstance(path
, unicode):
406 path
= path
.encode(sys
.getfilesystemencoding())
413 # if we already have a localconf then it needs to be
414 # copied to a new config with the new name
416 nc
= self
.CreateLocalConf(path
)
417 flag
, key
, idx
= lc
.GetFirstEntry()
419 nc
.Write(key
, lc
.Read(key
))
420 flag
, key
, idx
= lc
.GetNextEntry(idx
)
423 # otherwise create a new one
424 conf
.localconf
= self
.CreateLocalConf(path
)
427 self
.SetStatusText('Saving...')
431 tmpFile
,tmpName
= tempfile
.mkstemp(prefix
='xrced-')
433 self
.Save(tmpName
) # save temporary file first
434 shutil
.move(tmpName
, path
)
436 if conf
.localconf
.ReadBool("autogenerate", False):
437 pypath
= conf
.localconf
.Read("filename")
438 embed
= conf
.localconf
.ReadBool("embedResource", False)
439 genGettext
= conf
.localconf
.ReadBool("genGettext", False)
440 self
.GeneratePython(self
.dataFile
, pypath
, embed
, genGettext
)
442 self
.SetStatusText('Data saved')
443 self
.SaveRecent(path
)
445 self
.SetStatusText('Failed')
449 def SaveRecent(self
,path
):
450 # append to recently used files
451 if path
not in conf
.recentfiles
.values():
453 self
.recentMenu
.Append(newid
, path
)
454 wx
.EVT_MENU(self
, newid
, self
.OnRecentFile
)
455 conf
.recentfiles
[newid
] = path
457 def GeneratePython(self
, dataFile
, pypath
, embed
, genGettext
):
459 import wx
.tools
.pywxrc
460 rescomp
= wx
.tools
.pywxrc
.XmlResourceCompiler()
461 rescomp
.MakePythonModule([dataFile
], pypath
, embed
, genGettext
)
464 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
465 wx
.LogError('Error generating python code : %s' % pypath
)
469 def OnGeneratePython(self
, evt
):
470 if self
.modified
or not conf
.localconf
:
471 wx
.MessageBox("Save the XRC file first!", "Error")
474 dlg
= PythonOptions(self
, conf
.localconf
, self
.dataFile
)
478 def OnPrefs(self
, evt
):
479 dlg
= PrefsDialog(self
)
480 if dlg
.ShowModal() == wx
.ID_OK
:
481 # Fetch new preferences
482 for id,cdp
in dlg
.checkControls
.items():
484 if dlg
.FindWindowById(id).IsChecked():
485 d
[p
] = str(c
.GetValue())
486 elif p
in d
: del d
[p
]
489 def OnExit(self
, evt
):
492 def OnUndo(self
, evt
):
493 # Extra check to not mess with idle updating
494 if undoMan
.CanUndo():
496 g
.panel
.SetModified(False)
497 if not undoMan
.CanUndo():
498 self
.SetModified(False)
500 def OnRedo(self
, evt
):
501 if undoMan
.CanRedo():
503 self
.SetModified(True)
505 def OnCopy(self
, evt
):
506 selected
= tree
.selection
507 if not selected
: return # key pressed event
508 xxx
= tree
.GetPyData(selected
)
509 if wx
.TheClipboard
.Open():
511 data
= wx
.CustomDataObject('XRCED')
512 # Set encoding in header
514 s
= xxx
.node
.toxml(encoding
=expat
.native_encoding
)
516 data
= wx
.CustomDataObject('XRCED_node')
518 data
.SetData(cPickle
.dumps(s
))
519 wx
.TheClipboard
.SetData(data
)
520 wx
.TheClipboard
.Close()
521 self
.SetStatusText('Copied')
523 wx
.MessageBox("Unable to open the clipboard", "Error")
525 def OnPaste(self
, evt
):
526 selected
= tree
.selection
527 if not selected
: return # key pressed event
528 # For pasting with Ctrl pressed
530 if evt
.GetId() == pullDownMenu
.ID_PASTE_SIBLING
: appendChild
= False
531 elif evt
.GetId() == self
.ID_TOOL_PASTE
:
532 if g
.tree
.ctrl
: appendChild
= False
533 else: appendChild
= not tree
.NeedInsert(selected
)
534 else: appendChild
= not tree
.NeedInsert(selected
)
535 xxx
= tree
.GetPyData(selected
)
537 # If has next item, insert, else append to parent
538 nextItem
= tree
.GetNextSibling(selected
)
539 parentLeaf
= tree
.GetItemParent(selected
)
540 # Expanded container (must have children)
541 elif tree
.IsExpanded(selected
) and tree
.GetChildrenCount(selected
, False):
542 # Insert as first child
543 nextItem
= tree
.GetFirstChild(selected
)[0]
544 parentLeaf
= selected
546 # No children or unexpanded item - appendChild stays True
547 nextItem
= wx
.TreeItemId() # no next item
548 parentLeaf
= selected
549 parent
= tree
.GetPyData(parentLeaf
).treeObject()
551 # Create a copy of clipboard pickled element
552 success
= success_node
= False
553 if wx
.TheClipboard
.Open():
555 data
= wx
.CustomDataObject('XRCED')
556 if wx
.TheClipboard
.IsSupported(data
.GetFormat()):
558 success
= wx
.TheClipboard
.GetData(data
)
560 # there is a problem if XRCED_node is in clipboard
561 # but previous SetData was for XRCED
563 if not success
: # try other format
564 data
= wx
.CustomDataObject('XRCED_node')
565 if wx
.TheClipboard
.IsSupported(data
.GetFormat()):
566 success_node
= wx
.TheClipboard
.GetData(data
)
568 wx
.TheClipboard
.Close()
570 if not success
and not success_node
:
572 "There is no data in the clipboard in the required format",
576 xml
= cPickle
.loads(data
.GetData()) # xml representation of element
578 elem
= minidom
.parseString(xml
).childNodes
[0]
580 elem
= g
.tree
.dom
.createComment(xml
)
582 # Tempopary xxx object to test things
583 xxx
= MakeXXXFromDOM(parent
, elem
)
585 # Check compatibility
586 if not self
.ItemsAreCompatible(parent
, xxx
.treeObject()): return
588 # Check parent and child relationships.
589 # If parent is sizer or notebook, child is of wrong class or
590 # parent is normal window, child is child container then detach child.
591 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
592 parentIsBook
= parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]
593 if isChildContainer
and \
594 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
595 (parentIsBook
and not isinstance(xxx
, xxxPage
)) or \
596 not (parent
.isSizer
or parentIsBook
)):
597 elem
.removeChild(xxx
.child
.node
) # detach child
598 elem
.unlink() # delete child container
599 elem
= xxx
.child
.node
# replace
600 # This may help garbage collection
601 xxx
.child
.parent
= None
602 isChildContainer
= False
603 # Parent is sizer or notebook, child is not child container
604 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
605 # Create sizer item element
606 sizerItemElem
= MakeEmptyDOM(parent
.itemTag
)
607 sizerItemElem
.appendChild(elem
)
609 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
610 pageElem
= MakeEmptyDOM('notebookpage')
611 pageElem
.appendChild(elem
)
613 elif isinstance(parent
, xxxChoicebook
) and not isChildContainer
:
614 pageElem
= MakeEmptyDOM('choicebookpage')
615 pageElem
.appendChild(elem
)
617 elif isinstance(parent
, xxxListbook
) and not isChildContainer
:
618 pageElem
= MakeEmptyDOM('listbookpage')
619 pageElem
.appendChild(elem
)
621 # Insert new node, register undo
622 newItem
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
)
623 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
624 # Scroll to show new item (!!! redundant?)
625 tree
.EnsureVisible(newItem
)
626 tree
.SelectItem(newItem
)
627 if not tree
.IsVisible(newItem
):
628 tree
.ScrollTo(newItem
)
631 if g
.testWin
and tree
.IsHighlatable(newItem
):
633 tree
.needUpdate
= True
634 tree
.pendingHighLight
= newItem
636 tree
.pendingHighLight
= None
638 self
.SetStatusText('Pasted')
641 def ItemsAreCompatible(self
, parent
, child
):
642 # Check compatibility
644 # Comments are always compatible
645 if child
.__class
__ == xxxComment
:
648 if child
.__class
__ in [xxxDialog
, xxxFrame
, xxxWizard
]:
650 if parent
.__class
__ != xxxMainNode
: error
= True
651 elif child
.__class
__ == xxxMenuBar
:
652 # Menubar can be put in frame or dialog
653 if parent
.__class
__ not in [xxxMainNode
, xxxFrame
, xxxDialog
]: error
= True
654 elif child
.__class
__ == xxxToolBar
:
655 # Toolbar can be top-level of child of panel or frame
656 if parent
.__class
__ not in [xxxMainNode
, xxxPanel
, xxxFrame
] and \
657 not parent
.isSizer
: error
= True
658 elif child
.__class
__ == xxxPanel
and parent
.__class
__ == xxxMainNode
:
660 elif child
.__class
__ == xxxSpacer
:
661 if not parent
.isSizer
: error
= True
662 elif child
.__class
__ == xxxSeparator
:
663 if not parent
.__class
__ in [xxxMenu
, xxxToolBar
]: error
= True
664 elif child
.__class
__ == xxxTool
:
665 if parent
.__class
__ != xxxToolBar
: error
= True
666 elif child
.__class
__ == xxxMenu
:
667 if not parent
.__class
__ in [xxxMainNode
, xxxMenuBar
, xxxMenu
]: error
= True
668 elif child
.__class
__ == xxxMenuItem
:
669 if not parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
670 elif child
.isSizer
and parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]:
672 else: # normal controls can be almost anywhere
673 if parent
.__class
__ == xxxMainNode
or \
674 parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
676 if parent
.__class
__ == xxxMainNode
: parentClass
= 'root'
677 else: parentClass
= parent
.className
678 wx
.LogError('Incompatible parent/child: parent is %s, child is %s!' %
679 (parentClass
, child
.className
))
683 def OnMoveUp(self
, evt
):
684 selected
= tree
.selection
685 if not selected
: return
687 index
= tree
.ItemIndex(selected
)
688 if index
== 0: return # No previous sibling found
691 self
.lastOp
= 'MOVEUP'
692 status
= 'Moved before previous sibling'
697 parent
= tree
.GetItemParent(selected
)
698 elem
= tree
.RemoveLeaf(selected
)
699 nextItem
= tree
.GetFirstChild(parent
)[0]
700 for i
in range(index
- 1): nextItem
= tree
.GetNextSibling(nextItem
)
701 selected
= tree
.InsertNode(parent
, tree
.GetPyData(parent
).treeObject(), elem
, nextItem
)
702 newIndex
= tree
.ItemIndex(selected
)
703 tree
.SelectItem(selected
)
705 undoMan
.RegisterUndo(UndoMove(parent
, index
, parent
, newIndex
))
708 self
.SetStatusText(status
)
712 def OnMoveDown(self
, evt
):
713 selected
= tree
.selection
714 if not selected
: return
716 index
= tree
.ItemIndex(selected
)
717 next
= tree
.GetNextSibling(selected
)
721 self
.lastOp
= 'MOVEDOWN'
722 status
= 'Moved after next sibling'
727 parent
= tree
.GetItemParent(selected
)
728 elem
= tree
.RemoveLeaf(selected
)
729 nextItem
= tree
.GetFirstChild(parent
)[0]
730 for i
in range(index
+ 1): nextItem
= tree
.GetNextSibling(nextItem
)
731 selected
= tree
.InsertNode(parent
, tree
.GetPyData(parent
).treeObject(), elem
, nextItem
)
732 newIndex
= tree
.ItemIndex(selected
)
733 tree
.SelectItem(selected
)
735 undoMan
.RegisterUndo(UndoMove(parent
, index
, parent
, newIndex
))
738 self
.SetStatusText(status
)
742 def OnMoveLeft(self
, evt
):
743 selected
= tree
.selection
744 if not selected
: return
746 oldParent
= tree
.GetItemParent(selected
)
747 if not oldParent
: return
748 pparent
= tree
.GetItemParent(oldParent
)
749 if not pparent
: return
751 # Check compatibility
752 if not self
.ItemsAreCompatible(tree
.GetPyData(pparent
).treeObject(), tree
.GetPyData(selected
).treeObject()): return
755 self
.lastOp
= 'MOVELEFT'
756 status
= 'Made next sibling of parent'
758 oldIndex
= tree
.ItemIndex(selected
)
759 elem
= tree
.RemoveLeaf(selected
)
760 nextItem
= tree
.GetFirstChild(pparent
)[0]
761 parentIndex
= tree
.ItemIndex(oldParent
)
762 for i
in range(parentIndex
+ 1): nextItem
= tree
.GetNextSibling(nextItem
)
764 # Check parent and child relationships.
765 # If parent is sizer or notebook, child is of wrong class or
766 # parent is normal window, child is child container then detach child.
767 parent
= tree
.GetPyData(pparent
).treeObject()
768 xxx
= MakeXXXFromDOM(parent
, elem
)
769 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
770 if isChildContainer
and \
771 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
772 (isinstance(parent
, xxxNotebook
) and not isinstance(xxx
, xxxNotebookPage
)) or \
773 not (parent
.isSizer
or isinstance(parent
, xxxNotebook
))):
774 elem
.removeChild(xxx
.child
.node
) # detach child
775 elem
.unlink() # delete child container
776 elem
= xxx
.child
.node
# replace
777 # This may help garbage collection
778 xxx
.child
.parent
= None
779 isChildContainer
= False
780 # Parent is sizer or notebook, child is not child container
781 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
782 # Create sizer item element
783 sizerItemElem
= MakeEmptyDOM('sizeritem')
784 sizerItemElem
.appendChild(elem
)
786 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
787 pageElem
= MakeEmptyDOM('notebookpage')
788 pageElem
.appendChild(elem
)
791 selected
= tree
.InsertNode(pparent
, tree
.GetPyData(pparent
).treeObject(), elem
, nextItem
)
792 newIndex
= tree
.ItemIndex(selected
)
793 tree
.SelectItem(selected
)
795 undoMan
.RegisterUndo(UndoMove(oldParent
, oldIndex
, pparent
, newIndex
))
798 self
.SetStatusText(status
)
800 def OnMoveRight(self
, evt
):
801 selected
= tree
.selection
802 if not selected
: return
804 oldParent
= tree
.GetItemParent(selected
)
805 if not oldParent
: return
807 newParent
= tree
.GetPrevSibling(selected
)
808 if not newParent
: return
810 parent
= tree
.GetPyData(newParent
).treeObject()
812 # Check compatibility
813 if not self
.ItemsAreCompatible(parent
, tree
.GetPyData(selected
).treeObject()): return
816 self
.lastOp
= 'MOVERIGHT'
817 status
= 'Made last child of previous sibling'
819 oldIndex
= tree
.ItemIndex(selected
)
820 elem
= tree
.RemoveLeaf(selected
)
822 # Check parent and child relationships.
823 # If parent is sizer or notebook, child is of wrong class or
824 # parent is normal window, child is child container then detach child.
825 xxx
= MakeXXXFromDOM(parent
, elem
)
826 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
827 if isChildContainer
and \
828 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
829 (isinstance(parent
, xxxNotebook
) and not isinstance(xxx
, xxxNotebookPage
)) or \
830 not (parent
.isSizer
or isinstance(parent
, xxxNotebook
))):
831 elem
.removeChild(xxx
.child
.node
) # detach child
832 elem
.unlink() # delete child container
833 elem
= xxx
.child
.node
# replace
834 # This may help garbage collection
835 xxx
.child
.parent
= None
836 isChildContainer
= False
837 # Parent is sizer or notebook, child is not child container
838 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
839 # Create sizer item element
840 sizerItemElem
= MakeEmptyDOM('sizeritem')
841 sizerItemElem
.appendChild(elem
)
843 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
844 pageElem
= MakeEmptyDOM('notebookpage')
845 pageElem
.appendChild(elem
)
848 selected
= tree
.InsertNode(newParent
, tree
.GetPyData(newParent
).treeObject(), elem
, wx
.TreeItemId())
850 newIndex
= tree
.ItemIndex(selected
)
851 tree
.SelectItem(selected
)
853 undoMan
.RegisterUndo(UndoMove(oldParent
, oldIndex
, newParent
, newIndex
))
856 self
.SetStatusText(status
)
859 def OnCutDelete(self
, evt
):
860 selected
= tree
.selection
861 if not selected
: return # key pressed event
863 if evt
.GetId() == wx
.ID_CUT
:
865 status
= 'Removed to clipboard'
867 self
.lastOp
= 'DELETE'
871 # If deleting top-level item, delete testWin
872 if selected
== g
.testWin
.item
:
876 # Remove highlight, update testWin
877 if g
.testWin
.highLight
:
878 g
.testWin
.highLight
.Remove()
879 tree
.needUpdate
= True
882 index
= tree
.ItemFullIndex(selected
)
883 xxx
= tree
.GetPyData(selected
)
884 parent
= tree
.GetPyData(tree
.GetItemParent(selected
)).treeObject()
885 elem
= tree
.RemoveLeaf(selected
)
886 undoMan
.RegisterUndo(UndoCutDelete(index
, parent
, elem
))
887 if evt
.GetId() == wx
.ID_CUT
:
888 if wx
.TheClipboard
.Open():
890 data
= wx
.CustomDataObject('XRCED')
892 s
= elem
.toxml(encoding
=expat
.native_encoding
)
894 data
= wx
.CustomDataObject('XRCED_node')
896 data
.SetData(cPickle
.dumps(s
))
897 wx
.TheClipboard
.SetData(data
)
898 wx
.TheClipboard
.Close()
900 wx
.MessageBox("Unable to open the clipboard", "Error")
901 tree
.pendingHighLight
= None
903 tree
.selection
= None
908 self
.SetStatusText(status
)
910 def OnSubclass(self
, evt
):
911 selected
= tree
.selection
912 xxx
= tree
.GetPyData(selected
).treeObject()
914 subclass
= xxx
.subclass
915 dlg
= wx
.TextEntryDialog(self
, 'Subclass:', defaultValue
=subclass
)
916 if dlg
.ShowModal() == wx
.ID_OK
:
917 subclass
= dlg
.GetValue()
919 elem
.setAttribute('subclass', subclass
)
920 elif elem
.hasAttribute('subclass'):
921 elem
.removeAttribute('subclass')
923 xxx
.subclass
= elem
.getAttribute('subclass')
924 tree
.SetItemText(selected
, xxx
.treeName())
925 panel
.pages
[0].box
.SetLabel(xxx
.panelName())
928 def OnEmbedPanel(self
, evt
):
929 conf
.embedPanel
= evt
.IsChecked()
931 # Remember last dimentions
932 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
933 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
934 size
= self
.GetSize()
935 pos
= self
.GetPosition()
936 sizePanel
= panel
.GetSize()
937 panel
.Reparent(self
.splitter
)
938 self
.miniFrame
.GetSizer().Remove(panel
)
940 self
.SetDimensions(pos
.x
, pos
.y
, size
.width
+ sizePanel
.width
, size
.height
)
941 self
.splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
942 self
.miniFrame
.Show(False)
944 conf
.sashPos
= self
.splitter
.GetSashPosition()
945 pos
= self
.GetPosition()
946 size
= self
.GetSize()
947 sizePanel
= panel
.GetSize()
948 self
.splitter
.Unsplit(panel
)
949 sizer
= self
.miniFrame
.GetSizer()
950 panel
.Reparent(self
.miniFrame
)
952 sizer
.Add(panel
, 1, wx
.EXPAND
)
953 self
.miniFrame
.Show(True)
954 self
.miniFrame
.SetDimensions(conf
.panelX
, conf
.panelY
,
955 conf
.panelWidth
, conf
.panelHeight
)
956 self
.miniFrame
.Layout()
958 self
.SetDimensions(pos
.x
, pos
.y
,
959 max(size
.width
- sizePanel
.width
, self
.minWidth
), size
.height
)
961 def OnShowTools(self
, evt
):
962 conf
.showTools
= evt
.IsChecked()
963 g
.tools
.Show(conf
.showTools
)
965 self
.toolsSizer
.Prepend(g
.tools
, 0, wx
.EXPAND
)
967 self
.toolsSizer
.Remove(g
.tools
)
968 self
.toolsSizer
.Layout()
970 def OnTest(self
, evt
):
971 if not tree
.selection
: return # key pressed event
972 tree
.ShowTestWindow(tree
.selection
)
974 def OnTestHide(self
, evt
):
975 tree
.CloseTestWindow()
977 # Find object by relative position
978 def FindObject(self
, item
, obj
):
979 # We simply perform depth-first traversal, sinse it's too much
980 # hassle to deal with all sizer/window combinations
981 w
= tree
.FindNodeObject(item
)
982 if w
== obj
or isinstance(w
, wx
.GBSizerItem
) and w
.GetWindow() == obj
:
984 if tree
.ItemHasChildren(item
):
985 child
= tree
.GetFirstChild(item
)[0]
987 found
= self
.FindObject(child
, obj
)
988 if found
: return found
989 child
= tree
.GetNextSibling(child
)
992 def OnTestWinLeftDown(self
, evt
):
993 pos
= evt
.GetPosition()
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 # Create object_ref?
1106 if evt
.GetId() == ID_NEW
.REF
:
1107 ref
= wx
.GetTextFromUser('Create reference to:', 'Create reference')
1109 xxx
= MakeEmptyRefXXX(parent
, ref
)
1110 elif evt
.GetId() == ID_NEW
.COMMENT
:
1111 xxx
= MakeEmptyCommentXXX(parent
)
1113 # Create empty element
1114 if evt
.GetId() >= ID_NEW
.CUSTOM
:
1115 className
= pullDownMenu
.customMap
[evt
.GetId()]
1117 className
= pullDownMenu
.createMap
[evt
.GetId()]
1118 xxx
= MakeEmptyXXX(parent
, className
)
1120 # Insert new node, register undo
1121 if xxx
.isElement
: # true object
1122 # Set default name for top-level windows
1123 if parent
.__class
__ == xxxMainNode
:
1124 cl
= xxx
.treeObject().__class
__
1125 frame
.maxIDs
[cl
] += 1
1126 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
1127 # And for some other standard controls
1128 elif parent
.__class
__ == xxxStdDialogButtonSizer
:
1129 xxx
.setTreeName(pullDownMenu
.stdButtonIDs
[evt
.GetId()][0])
1130 # We can even set label
1131 obj
= xxx
.treeObject()
1132 elem
= g
.tree
.dom
.createElement('label')
1133 elem
.appendChild(g
.tree
.dom
.createTextNode(pullDownMenu
.stdButtonIDs
[evt
.GetId()][1]))
1134 obj
.params
['label'] = xxxParam(elem
)
1135 xxx
.treeObject().node
.appendChild(elem
)
1137 newItem
= tree
.InsertNode(parentLeaf
, parent
, xxx
.node
, nextItem
)
1138 else: # comment node
1139 newItem
= tree
.InsertNode(parentLeaf
, parent
, xxx
.node
, nextItem
)
1140 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
1141 tree
.EnsureVisible(newItem
)
1142 tree
.SelectItem(newItem
)
1143 if not tree
.IsVisible(newItem
):
1144 tree
.ScrollTo(newItem
)
1147 if xxx
.isElement
and g
.testWin
and tree
.IsHighlatable(newItem
):
1148 if conf
.autoRefresh
:
1149 tree
.needUpdate
= True
1150 tree
.pendingHighLight
= newItem
1152 tree
.pendingHighLight
= None
1154 if not xxx
.isElement
:
1155 tree
.EditLabel(newItem
)
1158 # Replace one object with another
1159 def OnReplace(self
, evt
):
1160 selected
= tree
.selection
1161 xxx
= tree
.GetPyData(selected
).treeObject()
1163 parent
= elem
.parentNode
1164 undoMan
.RegisterUndo(UndoReplace(selected
))
1166 className
= pullDownMenu
.createMap
[evt
.GetId() - 1000]
1168 # Create temporary empty node (with default values)
1169 dummy
= MakeEmptyDOM(className
)
1170 if className
== 'spacer' and xxx
.className
!= 'spacer':
1172 elif xxx
.className
== 'spacer' and className
!= 'spacer':
1173 klass
= xxxSizerItem
1175 klass
= xxxDict
[className
]
1176 # Remove non-compatible children
1177 if tree
.ItemHasChildren(selected
) and not klass
.hasChildren
:
1178 tree
.DeleteChildren(selected
)
1179 nodes
= elem
.childNodes
[:]
1182 if node
.nodeType
!= minidom
.Node
.ELEMENT_NODE
: continue
1186 if not klass
.hasChildren
: remove
= True
1187 elif tag
not in klass
.allParams
and \
1188 (not klass
.hasStyle
or tag
not in klass
.styles
):
1193 elem
.removeChild(node
)
1196 # Remove sizeritem child if spacer
1197 if className
== 'spacer' and xxx
.className
!= 'spacer':
1198 sizeritem
= elem
.parentNode
1199 assert sizeritem
.getAttribute('class') == 'sizeritem'
1200 sizeritem
.removeChild(elem
)
1203 tree
.GetPyData(selected
).hasChild
= False
1204 elif xxx
.className
== 'spacer' and className
!= 'spacer':
1205 # Create sizeritem element
1206 assert xxx
.parent
.isSizer
1207 elem
.setAttribute('class', 'sizeritem')
1208 node
= MakeEmptyDOM(className
)
1209 elem
.appendChild(node
)
1210 # Replace to point to new object
1211 xxx
= xxxSizerItem(xxx
.parent
, elem
)
1213 tree
.SetPyData(selected
, xxx
)
1216 # Copy parameters present in dummy but not in elem
1217 for node
in dummy
.childNodes
:
1218 if node
.tagName
not in tags
: elem
.appendChild(node
.cloneNode(True))
1222 elem
.setAttribute('class', className
)
1223 if elem
.hasAttribute('subclass'):
1224 elem
.removeAttribute('subclass') # clear subclassing
1225 # Re-create xxx element
1226 xxx
= MakeXXXFromDOM(xxx
.parent
, elem
)
1227 # Remove incompatible style flags
1228 if 'style' in xxx
.params
:
1229 styles
= map(string
.strip
, xxx
.params
['style'].value().split('|'))
1230 newStyles
= [s
for s
in styles
if s
in klass
.winStyles
or s
in genericStyles
]
1231 if newStyles
!= styles
:
1233 value
= reduce(lambda a
,b
: a
+'|'+b
, newStyles
)
1236 xxx
.params
['style'].update(value
)
1238 # Update parent in child objects
1239 if tree
.ItemHasChildren(selected
):
1240 i
, cookie
= tree
.GetFirstChild(selected
)
1242 x
= tree
.GetPyData(i
)
1244 if x
.hasChild
: x
.child
.parent
= xxx
1245 i
, cookie
= tree
.GetNextChild(selected
, cookie
)
1248 if tree
.GetPyData(selected
).hasChild
: # child container
1249 container
= tree
.GetPyData(selected
)
1250 container
.resetChild(xxx
)
1253 tree
.SetPyData(selected
, xxx
)
1254 tree
.SetItemText(selected
, xxx
.treeName())
1255 tree
.SetItemImage(selected
, xxx
.treeImage())
1257 # Set default name for top-level windows
1258 if parent
.__class
__ == xxxMainNode
:
1259 cl
= xxx
.treeObject().__class
__
1260 frame
.maxIDs
[cl
] += 1
1261 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
1264 g
.panel
.SetData(xxx
)
1268 #undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected))
1270 if g
.testWin
and tree
.IsHighlatable(selected
):
1271 if conf
.autoRefresh
:
1272 tree
.needUpdate
= True
1273 tree
.pendingHighLight
= selected
1275 tree
.pendingHighLight
= None
1279 # Expand/collapse subtree
1280 def OnExpand(self
, evt
):
1281 if tree
.selection
: tree
.ExpandAll(tree
.selection
)
1282 else: tree
.ExpandAll(tree
.root
)
1283 def OnCollapse(self
, evt
):
1284 if tree
.selection
: tree
.CollapseAll(tree
.selection
)
1285 else: tree
.CollapseAll(tree
.root
)
1287 def OnPullDownHighlight(self
, evt
):
1288 menuId
= evt
.GetMenuId()
1290 menu
= evt
.GetEventObject()
1291 help = menu
.GetHelpString(menuId
)
1292 self
.SetStatusText(help)
1294 self
.SetStatusText('')
1296 def OnUpdateUI(self
, evt
):
1297 if evt
.GetId() in [wx
.ID_CUT
, wx
.ID_COPY
, self
.ID_DELETE
]:
1298 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
1299 elif evt
.GetId() == wx
.ID_SAVE
:
1300 evt
.Enable(self
.modified
)
1301 elif evt
.GetId() in [wx
.ID_PASTE
, self
.ID_TOOL_PASTE
]:
1302 evt
.Enable(tree
.selection
is not None)
1303 elif evt
.GetId() == self
.ID_TEST
:
1304 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
1305 elif evt
.GetId() in [self
.ID_LOCATE
, self
.ID_TOOL_LOCATE
]:
1306 evt
.Enable(g
.testWin
is not None)
1307 elif evt
.GetId() == wx
.ID_UNDO
: evt
.Enable(undoMan
.CanUndo())
1308 elif evt
.GetId() == wx
.ID_REDO
: evt
.Enable(undoMan
.CanRedo())
1310 def OnIdle(self
, evt
):
1311 if self
.inIdle
: return # Recursive call protection
1315 if conf
.autoRefresh
:
1317 self
.SetStatusText('Refreshing test window...')
1319 tree
.CreateTestWin(g
.testWin
.item
)
1320 self
.SetStatusText('')
1321 tree
.needUpdate
= False
1322 elif tree
.pendingHighLight
:
1324 tree
.HighLight(tree
.pendingHighLight
)
1326 # Remove highlight if any problem
1327 if g
.testWin
.highLight
:
1328 g
.testWin
.highLight
.Remove()
1329 tree
.pendingHighLight
= None
1336 # We don't let close panel window
1337 def OnCloseMiniFrame(self
, evt
):
1340 def OnIconize(self
, evt
):
1342 conf
.x
, conf
.y
= self
.GetPosition()
1343 conf
.width
, conf
.height
= self
.GetSize()
1345 conf
.sashPos
= self
.splitter
.GetSashPosition()
1347 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1348 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1349 self
.miniFrame
.Iconize()
1351 if not conf
.embedPanel
:
1352 self
.miniFrame
.Iconize(False)
1355 def OnCloseWindow(self
, evt
):
1356 if not self
.AskSave(): return
1357 if g
.testWin
: g
.testWin
.Destroy()
1358 if not panel
.GetPageCount() == 2:
1359 panel
.page2
.Destroy()
1361 # If we don't do this, page does not get destroyed (a bug?)
1363 if not self
.IsIconized():
1364 conf
.x
, conf
.y
= self
.GetPosition()
1365 conf
.width
, conf
.height
= self
.GetSize()
1367 conf
.sashPos
= self
.splitter
.GetSashPosition()
1369 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1370 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1373 def CreateLocalConf(self
, path
):
1374 name
= os
.path
.splitext(path
)[0]
1376 return wx
.FileConfig(localFilename
=name
)
1380 conf
.localconf
= None
1382 self
.SetModified(False)
1388 # Numbers for new controls
1390 for cl
in [xxxPanel
, xxxDialog
, xxxFrame
,
1391 xxxMenuBar
, xxxMenu
, xxxToolBar
,
1392 xxxWizard
, xxxBitmap
, xxxIcon
]:
1394 # Restore handlers, menu, etc. to initial
1395 setHandlers(self
.handlers
[:])
1396 g
.pullDownMenu
.custom
= self
.custom
[:]
1397 # Remove modules imported from comment directives
1398 map(sys
.modules
.pop
, [m
for m
in sys
.modules
if m
not in self
.modules
])
1400 def SetModified(self
, state
=True):
1401 self
.modified
= state
1402 name
= os
.path
.basename(self
.dataFile
)
1403 if not name
: name
= defaultName
1405 self
.SetTitle(progname
+ ': ' + name
+ ' *')
1407 self
.SetTitle(progname
+ ': ' + name
)
1409 def Open(self
, path
):
1410 if not os
.path
.exists(path
):
1411 wx
.LogError('File does not exists: %s' % path
)
1413 # Try to read the file
1417 dom
= minidom
.parse(f
)
1419 # Set encoding global variable and default encoding
1421 g
.currentEncoding
= dom
.encoding
1422 wx
.SetDefaultPyEncoding(g
.currentEncoding
.encode())
1424 g
.currentEncoding
= ''
1426 self
.dataFile
= path
= os
.path
.abspath(path
)
1427 dir = os
.path
.dirname(path
)
1428 if dir: os
.chdir(dir)
1429 # Allow importing modules from the same directory
1430 sys
.path
= sys_path
+ [dir]
1432 self
.SetTitle(progname
+ ': ' + os
.path
.basename(path
))
1433 conf
.localconf
= self
.CreateLocalConf(self
.dataFile
)
1435 # Nice exception printing
1436 inf
= sys
.exc_info()
1437 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1438 wx
.LogError('Error reading file: %s' % path
)
1443 def Indent(self
, node
, indent
= 0):
1444 if node
.nodeType
== minidom
.Node
.COMMENT_NODE
:
1445 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1446 node
.parentNode
.insertBefore(text
, node
)
1447 return # no children
1448 # Copy child list because it will change soon
1449 children
= node
.childNodes
[:]
1450 # Main node doesn't need to be indented
1452 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1453 node
.parentNode
.insertBefore(text
, node
)
1455 # Append newline after last child, except for text nodes
1456 if children
[-1].nodeType
== minidom
.Node
.ELEMENT_NODE
:
1457 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1458 node
.appendChild(text
)
1459 # Indent children which are elements
1461 if n
.nodeType
== minidom
.Node
.ELEMENT_NODE
or \
1462 n
.nodeType
== minidom
.Node
.COMMENT_NODE
:
1463 self
.Indent(n
, indent
+ 2)
1465 def Save(self
, path
):
1469 if tree
.selection
and panel
.IsModified():
1470 self
.OnRefresh(wx
.CommandEvent())
1471 if g
.currentEncoding
:
1472 f
= codecs
.open(path
, 'wt', g
.currentEncoding
)
1474 f
= codecs
.open(path
, 'wt')
1475 # Make temporary copy for formatting it
1476 # !!! We can't clone dom node, it works only once
1477 #self.domCopy = tree.dom.cloneNode(True)
1478 self
.domCopy
= MyDocument()
1479 mainNode
= self
.domCopy
.appendChild(tree
.mainNode
.cloneNode(True))
1480 # Remove first child (test element)
1481 testElem
= mainNode
.firstChild
1482 mainNode
.removeChild(testElem
)
1484 self
.Indent(mainNode
)
1485 self
.domCopy
.writexml(f
, encoding
= g
.currentEncoding
)
1487 self
.domCopy
.unlink()
1489 self
.SetModified(False)
1490 panel
.SetModified(False)
1491 conf
.localconf
.Flush()
1493 inf
= sys
.exc_info()
1494 wx
.LogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1495 wx
.LogError('Error writing file: %s' % path
)
1499 if not (self
.modified
or panel
.IsModified()): return True
1500 flags
= wx
.ICON_EXCLAMATION | wx
.YES_NO | wx
.CANCEL | wx
.CENTRE
1501 dlg
= wx
.MessageDialog( self
, 'File is modified. Save before exit?',
1502 'Save before too late?', flags
)
1503 say
= dlg
.ShowModal()
1506 if say
== wx
.ID_YES
:
1507 self
.OnSaveOrSaveAs(wx
.CommandEvent(wx
.ID_SAVE
))
1508 # If save was successful, modified flag is unset
1509 if not self
.modified
: return True
1510 elif say
== wx
.ID_NO
:
1511 self
.SetModified(False)
1512 panel
.SetModified(False)
1519 ################################################################################
1521 class PythonOptions(wx
.Dialog
):
1523 def __init__(self
, parent
, cfg
, dataFile
):
1524 pre
= wx
.PreDialog()
1525 g
.frame
.res
.LoadOnDialog(pre
, parent
, "PYTHON_OPTIONS")
1526 self
.PostCreate(pre
)
1529 self
.dataFile
= dataFile
1531 self
.AutoGenerateCB
= xrc
.XRCCTRL(self
, "AutoGenerateCB")
1532 self
.EmbedCB
= xrc
.XRCCTRL(self
, "EmbedCB")
1533 self
.GettextCB
= xrc
.XRCCTRL(self
, "GettextCB")
1534 self
.MakeXRSFileCB
= xrc
.XRCCTRL(self
, "MakeXRSFileCB")
1535 self
.FileNameTC
= xrc
.XRCCTRL(self
, "FileNameTC")
1536 self
.BrowseBtn
= xrc
.XRCCTRL(self
, "BrowseBtn")
1537 self
.GenerateBtn
= xrc
.XRCCTRL(self
, "GenerateBtn")
1538 self
.SaveOptsBtn
= xrc
.XRCCTRL(self
, "SaveOptsBtn")
1540 self
.Bind(wx
.EVT_BUTTON
, self
.OnBrowse
, self
.BrowseBtn
)
1541 self
.Bind(wx
.EVT_BUTTON
, self
.OnGenerate
, self
.GenerateBtn
)
1542 self
.Bind(wx
.EVT_BUTTON
, self
.OnSaveOpts
, self
.SaveOptsBtn
)
1544 if self
.cfg
.Read("filename", "") != "":
1545 self
.FileNameTC
.SetValue(self
.cfg
.Read("filename"))
1547 name
= os
.path
.splitext(os
.path
.split(dataFile
)[1])[0]
1549 self
.FileNameTC
.SetValue(name
)
1550 self
.AutoGenerateCB
.SetValue(self
.cfg
.ReadBool("autogenerate", False))
1551 self
.EmbedCB
.SetValue(self
.cfg
.ReadBool("embedResource", False))
1552 self
.MakeXRSFileCB
.SetValue(self
.cfg
.ReadBool("makeXRS", False))
1553 self
.GettextCB
.SetValue(self
.cfg
.ReadBool("genGettext", False))
1556 def OnBrowse(self
, evt
):
1557 path
= self
.FileNameTC
.GetValue()
1558 dirname
= os
.path
.abspath(os
.path
.dirname(path
))
1559 name
= os
.path
.split(path
)[1]
1560 dlg
= wx
.FileDialog(self
, 'Save As', dirname
, name
, '*.py',
1561 wx
.SAVE | wx
.OVERWRITE_PROMPT
)
1562 if dlg
.ShowModal() == wx
.ID_OK
:
1563 path
= dlg
.GetPath()
1564 self
.FileNameTC
.SetValue(path
)
1568 def OnGenerate(self
, evt
):
1569 pypath
= self
.FileNameTC
.GetValue()
1570 embed
= self
.EmbedCB
.GetValue()
1571 genGettext
= self
.GettextCB
.GetValue()
1572 frame
.GeneratePython(self
.dataFile
, pypath
, embed
, genGettext
)
1576 def OnSaveOpts(self
, evt
=None):
1577 self
.cfg
.Write("filename", self
.FileNameTC
.GetValue())
1578 self
.cfg
.WriteBool("autogenerate", self
.AutoGenerateCB
.GetValue())
1579 self
.cfg
.WriteBool("embedResource", self
.EmbedCB
.GetValue())
1580 self
.cfg
.WriteBool("makeXRS", self
.MakeXRSFileCB
.GetValue())
1581 self
.cfg
.WriteBool("genGettext", self
.GettextCB
.GetValue())
1583 self
.EndModal(wx
.ID_OK
)
1585 ################################################################################
1587 class PrefsDialog(wx
.Dialog
):
1589 def __init__(self
, parent
):
1590 pre
= wx
.PreDialog()
1591 g
.frame
.res
.LoadOnDialog(pre
, parent
, "DIALOG_PREFS")
1592 self
.PostCreate(pre
)
1593 self
.checkControls
= {} # map of check IDs to (control,dict,param)
1595 xxx
= sys
.modules
['xxx']
1596 d
= xxx
.xxxSizerItem
.defaults_panel
1598 self
.check_proportion_panel
= xrc
.XRCCTRL(self
, 'check_proportion_panel')
1599 id = self
.check_proportion_panel
.GetId()
1600 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1601 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'spin_proportion_panel'),
1604 self
.check_flag_panel
= xrc
.XRCCTRL(self
, 'check_flag_panel')
1605 id = self
.check_flag_panel
.GetId()
1606 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1607 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'text_flag_panel'),
1610 d
= xxx
.xxxSizerItem
.defaults_control
1612 self
.check_proportion_panel
= xrc
.XRCCTRL(self
, 'check_proportion_control')
1613 id = self
.check_proportion_panel
.GetId()
1614 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1615 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'spin_proportion_control'),
1618 self
.check_flag_panel
= xrc
.XRCCTRL(self
, 'check_flag_control')
1619 id = self
.check_flag_panel
.GetId()
1620 wx
.EVT_CHECKBOX(self
, id, self
.OnCheck
)
1621 self
.checkControls
[id] = (xrc
.XRCCTRL(self
, 'text_flag_control'),
1624 for id,cdp
in self
.checkControls
.items():
1627 if isinstance(c
, wx
.SpinCtrl
):
1628 c
.SetValue(int(d
[p
]))
1631 self
.FindWindowById(id).SetValue(True)
1635 def OnCheck(self
, evt
):
1636 self
.checkControls
[evt
.GetId()][0].Enable(evt
.IsChecked())
1639 ################################################################################
1641 # Parse string in form var1=val1[,var2=val2]* as dictionary
1642 def ReadDictFromString(s
):
1644 for vv
in s
.split(','):
1645 var
,val
= vv
.split(':')
1646 d
[var
.strip()] = val
1649 # Transform dictionary with strings into one string
1650 def DictToString(d
):
1651 return ','.join(map(':'.join
, d
.items()))
1654 print >> sys
.stderr
, 'usage: xrced [-dhiv] [file]'
1659 if wx
.VERSION
[:3] < MinWxVersion
:
1661 This version of XRCed may not work correctly on your version of wxWidgets. \
1662 Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion
)
1664 # Process comand-line
1667 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'dhiv')
1675 print 'XRCed version', version
1678 except getopt
.GetoptError
:
1679 if wx
.Platform
!= '__WXMAC__': # macs have some extra parameters
1680 print >> sys
.stderr
, 'Unknown option'
1684 self
.SetAppName('xrced')
1687 conf
= g
.conf
= wx
.Config(style
= wx
.CONFIG_USE_LOCAL_FILE
)
1688 conf
.localconf
= None
1689 conf
.autoRefresh
= conf
.ReadInt('autorefresh', True)
1690 pos
= conf
.ReadInt('x', -1), conf
.ReadInt('y', -1)
1691 size
= conf
.ReadInt('width', 800), conf
.ReadInt('height', 600)
1692 conf
.embedPanel
= conf
.ReadInt('embedPanel', True)
1693 conf
.showTools
= conf
.ReadInt('showTools', True)
1694 conf
.sashPos
= conf
.ReadInt('sashPos', 200)
1695 # read recently used files
1696 recentfiles
=conf
.Read('recentFiles','')
1699 for fil
in recentfiles
.split('|'):
1700 conf
.recentfiles
[wx
.NewId()]=fil
1701 if not conf
.embedPanel
:
1702 conf
.panelX
= conf
.ReadInt('panelX', -1)
1703 conf
.panelY
= conf
.ReadInt('panelY', -1)
1705 conf
.panelX
= conf
.panelY
= -1
1706 conf
.panelWidth
= conf
.ReadInt('panelWidth', 200)
1707 conf
.panelHeight
= conf
.ReadInt('panelHeight', 200)
1708 conf
.panic
= not conf
.HasEntry('nopanic')
1710 p
= 'Prefs/sizeritem_defaults_panel'
1711 if conf
.HasEntry(p
):
1712 sys
.modules
['xxx'].xxxSizerItem
.defaults_panel
= ReadDictFromString(conf
.Read(p
))
1713 p
= 'Prefs/sizeritem_defaults_control'
1714 if conf
.HasEntry(p
):
1715 sys
.modules
['xxx'].xxxSizerItem
.defaults_control
= ReadDictFromString(conf
.Read(p
))
1718 wx
.FileSystem
.AddHandler(wx
.MemoryFSHandler())
1720 frame
= Frame(pos
, size
)
1724 plugins
= os
.getenv('XRCEDPATH')
1728 for dir in plugins
.split(':'):
1729 if os
.path
.isdir(dir) and \
1730 os
.path
.isfile(os
.path
.join(dir, '__init__.py')):
1732 dir = os
.path
.abspath(os
.path
.normpath(dir))
1733 sys
.path
= sys_path
+ [os
.path
.dirname(dir)]
1736 __import__(os
.path
.basename(dir), globals(), locals(), ['*'])
1738 print traceback
.print_exc()
1741 # Store important data
1742 frame
.handlers
= getHandlers()[:]
1743 frame
.custom
= g
.pullDownMenu
.custom
[:]
1744 frame
.modules
= set(sys
.modules
.keys())
1749 # Load file after showing
1752 frame
.open = frame
.Open(args
[0])
1760 wc
.WriteInt('autorefresh', conf
.autoRefresh
)
1761 wc
.WriteInt('x', conf
.x
)
1762 wc
.WriteInt('y', conf
.y
)
1763 wc
.WriteInt('width', conf
.width
)
1764 wc
.WriteInt('height', conf
.height
)
1765 wc
.WriteInt('embedPanel', conf
.embedPanel
)
1766 wc
.WriteInt('showTools', conf
.showTools
)
1767 if not conf
.embedPanel
:
1768 wc
.WriteInt('panelX', conf
.panelX
)
1769 wc
.WriteInt('panelY', conf
.panelY
)
1770 wc
.WriteInt('sashPos', conf
.sashPos
)
1771 wc
.WriteInt('panelWidth', conf
.panelWidth
)
1772 wc
.WriteInt('panelHeight', conf
.panelHeight
)
1773 wc
.WriteInt('nopanic', True)
1774 wc
.Write('recentFiles', '|'.join(conf
.recentfiles
.values()[-5:]))
1776 wc
.DeleteGroup('Prefs')
1777 v
= sys
.modules
['xxx'].xxxSizerItem
.defaults_panel
1778 if v
: wc
.Write('Prefs/sizeritem_defaults_panel', DictToString(v
))
1779 v
= sys
.modules
['xxx'].xxxSizerItem
.defaults_control
1780 if v
: wc
.Write('Prefs/sizeritem_defaults_control', DictToString(v
))
1784 app
= App(0, useBestVisual
=False)
1785 #app.SetAssertMode(wx.PYAPP_ASSERT_LOG)
1791 if __name__
== '__main__':