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 wxWindows/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
27 from tree
import * # imports xxx which imports params
30 # Cleanup recursive import sideeffects, otherwise we can't create undoMan
32 undo
.ParamPage
= ParamPage
33 undoMan
= g
.undoMan
= UndoManager()
35 # Set application path for loading resources
36 if __name__
== '__main__':
37 basePath
= os
.path
.dirname(sys
.argv
[0])
39 basePath
= os
.path
.dirname(__file__
)
41 # 1 adds CMD command to Help menu
45 <HTML><H2>Welcome to XRC<font color="blue">ed</font></H2><H3><font color="green">DON'T PANIC :)</font></H3>
46 Read this note before clicking on anything!<P>
47 To start select tree root, then popup menu with your right mouse button,
48 select "Append Child", and then any command.<P>
49 Or just press one of the buttons on the tools palette.<P>
50 Enter XML ID, change properties, create children.<P>
51 To test your interface select Test command (View menu).<P>
52 Consult README file for the details.</HTML>
55 defaultIDs
= {xxxPanel
:'PANEL', xxxDialog
:'DIALOG', xxxFrame
:'FRAME',
56 xxxMenuBar
:'MENUBAR', xxxMenu
:'MENU', xxxToolBar
:'TOOLBAR',
57 xxxWizard
:'WIZARD', xxxBitmap
:'BITMAP', xxxIcon
:'ICON'}
59 defaultName
= 'UNTITLED.xrc'
61 ################################################################################
63 # ScrolledMessageDialog - modified from wxPython lib to set fixed-width font
64 class ScrolledMessageDialog(wxDialog
):
65 def __init__(self
, parent
, msg
, caption
, pos
= wxDefaultPosition
, size
= (500,300)):
66 from wxPython
.lib
.layoutf
import Layoutf
67 wxDialog
.__init
__(self
, parent
, -1, caption
, pos
, size
)
68 text
= wxTextCtrl(self
, -1, msg
, wxDefaultPosition
,
69 wxDefaultSize
, wxTE_MULTILINE | wxTE_READONLY
)
70 text
.SetFont(g
.modernFont())
72 # !!! possible bug - GetTextExtent without font returns sysfont dims
73 w
, h
= dc
.GetFullTextExtent(' ', g
.modernFont())[:2]
74 ok
= wxButton(self
, wxID_OK
, "OK")
75 text
.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self
,ok
)))
76 text
.SetSize((w
* 80 + 30, h
* 40))
78 ok
.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self
,)))
79 self
.SetAutoLayout(True)
81 self
.CenterOnScreen(wxBOTH
)
83 ################################################################################
85 # Event handler for using during location
86 class Locator(wxEvtHandler
):
87 def ProcessEvent(self
, evt
):
91 def __init__(self
, pos
, size
):
92 wxFrame
.__init
__(self
, None, -1, '', pos
, size
)
94 frame
= g
.frame
= self
95 bar
= self
.CreateStatusBar(2)
96 bar
.SetStatusWidths([-1, 40])
97 self
.SetIcon(images
.getIconIcon())
102 # Load our own resources
103 self
.res
= wxXmlResource('')
104 # !!! Blocking of assert failure occurring in older unicode builds
106 quietlog
= wx
.LogNull()
107 self
.res
.Load(os
.path
.join(basePath
, 'xrced.xrc'))
108 except wx
._core
.PyAssertionError
:
109 print 'PyAssertionError was ignored'
112 menuBar
= wxMenuBar()
115 menu
.Append(wxID_NEW
, '&New\tCtrl-N', 'New file')
116 menu
.AppendSeparator()
117 menu
.Append(wxID_OPEN
, '&Open...\tCtrl-O', 'Open XRC file')
118 self
.recentMenu
= wxMenu()
119 self
.AppendRecent(self
.recentMenu
)
120 menu
.AppendMenu(-1, 'Open Recent', self
.recentMenu
, 'Open a recent file')
121 menu
.AppendSeparator()
122 menu
.Append(wxID_SAVE
, '&Save\tCtrl-S', 'Save XRC file')
123 menu
.Append(wxID_SAVEAS
, 'Save &As...', 'Save XRC file under different name')
124 menu
.AppendSeparator()
125 menu
.Append(wxID_EXIT
, '&Quit\tCtrl-Q', 'Exit application')
127 menuBar
.Append(menu
, '&File')
130 menu
.Append(wxID_UNDO
, '&Undo\tCtrl-Z', 'Undo')
131 menu
.Append(wxID_REDO
, '&Redo\tCtrl-Y', 'Redo')
132 menu
.AppendSeparator()
133 menu
.Append(wxID_CUT
, 'Cut\tCtrl-X', 'Cut to the clipboard')
134 menu
.Append(wxID_COPY
, '&Copy\tCtrl-C', 'Copy to the clipboard')
135 menu
.Append(wxID_PASTE
, '&Paste\tCtrl-V', 'Paste from the clipboard')
136 self
.ID_DELETE
= wxNewId()
137 menu
.Append(self
.ID_DELETE
, '&Delete\tCtrl-D', 'Delete object')
138 menu
.AppendSeparator()
139 self
.ID_LOCATE
= wxNewId()
140 self
.ID_TOOL_LOCATE
= wxNewId()
141 self
.ID_TOOL_PASTE
= wxNewId()
142 menu
.Append(self
.ID_LOCATE
, '&Locate\tCtrl-L', 'Locate control in test window and select it')
143 menuBar
.Append(menu
, '&Edit')
146 self
.ID_EMBED_PANEL
= wxNewId()
147 menu
.Append(self
.ID_EMBED_PANEL
, '&Embed Panel',
148 'Toggle embedding properties panel in the main window', True)
149 menu
.Check(self
.ID_EMBED_PANEL
, conf
.embedPanel
)
150 self
.ID_SHOW_TOOLS
= wxNewId()
151 menu
.Append(self
.ID_SHOW_TOOLS
, 'Show &Tools', 'Toggle tools', True)
152 menu
.Check(self
.ID_SHOW_TOOLS
, conf
.showTools
)
153 menu
.AppendSeparator()
154 self
.ID_TEST
= wxNewId()
155 menu
.Append(self
.ID_TEST
, '&Test\tF5', 'Show test window')
156 self
.ID_REFRESH
= wxNewId()
157 menu
.Append(self
.ID_REFRESH
, '&Refresh\tCtrl-R', 'Refresh test window')
158 self
.ID_AUTO_REFRESH
= wxNewId()
159 menu
.Append(self
.ID_AUTO_REFRESH
, '&Auto-refresh\tCtrl-A',
160 'Toggle auto-refresh mode', True)
161 menu
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
162 self
.ID_TEST_HIDE
= wxNewId()
163 menu
.Append(self
.ID_TEST_HIDE
, '&Hide\tCtrl-H', 'Close test window')
164 menuBar
.Append(menu
, '&View')
167 menu
.Append(wxID_ABOUT
, '&About...', 'About XCRed')
168 self
.ID_README
= wxNewId()
169 menu
.Append(self
.ID_README
, '&Readme...', 'View the README file')
171 self
.ID_DEBUG_CMD
= wxNewId()
172 menu
.Append(self
.ID_DEBUG_CMD
, 'CMD', 'Python command line')
173 EVT_MENU(self
, self
.ID_DEBUG_CMD
, self
.OnDebugCMD
)
174 menuBar
.Append(menu
, '&Help')
176 self
.menuBar
= menuBar
177 self
.SetMenuBar(menuBar
)
180 tb
= self
.CreateToolBar(wxTB_HORIZONTAL | wxNO_BORDER | wxTB_FLAT
)
181 tb
.SetToolBitmapSize((24,24))
182 new_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_NORMAL_FILE
, wx
.ART_TOOLBAR
)
183 open_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_OPEN
, wx
.ART_TOOLBAR
)
184 save_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_SAVE
, wx
.ART_TOOLBAR
)
185 undo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_UNDO
, wx
.ART_TOOLBAR
)
186 redo_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_REDO
, wx
.ART_TOOLBAR
)
187 cut_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_CUT
, wx
.ART_TOOLBAR
)
188 copy_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_COPY
, wx
.ART_TOOLBAR
)
189 paste_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_PASTE
, wx
.ART_TOOLBAR
)
191 tb
.AddSimpleTool(wxID_NEW
, new_bmp
, 'New', 'New file')
192 tb
.AddSimpleTool(wxID_OPEN
, open_bmp
, 'Open', 'Open file')
193 tb
.AddSimpleTool(wxID_SAVE
, save_bmp
, 'Save', 'Save file')
194 tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
))
195 tb
.AddSimpleTool(wxID_UNDO
, undo_bmp
, 'Undo', 'Undo')
196 tb
.AddSimpleTool(wxID_REDO
, redo_bmp
, 'Redo', 'Redo')
197 tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
))
198 tb
.AddSimpleTool(wxID_CUT
, cut_bmp
, 'Cut', 'Cut')
199 tb
.AddSimpleTool(wxID_COPY
, copy_bmp
, 'Copy', 'Copy')
200 tb
.AddSimpleTool(self
.ID_TOOL_PASTE
, paste_bmp
, 'Paste', 'Paste')
201 tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
))
202 tb
.AddSimpleTool(self
.ID_TOOL_LOCATE
,
203 images
.getLocateBitmap(), #images.getLocateArmedBitmap(),
204 'Locate', 'Locate control in test window and select it', True)
205 tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
))
206 tb
.AddSimpleTool(self
.ID_TEST
, images
.getTestBitmap(), 'Test', 'Test window')
207 tb
.AddSimpleTool(self
.ID_REFRESH
, images
.getRefreshBitmap(),
208 'Refresh', 'Refresh view')
209 tb
.AddSimpleTool(self
.ID_AUTO_REFRESH
, images
.getAutoRefreshBitmap(),
210 'Auto-refresh', 'Toggle auto-refresh mode', True)
211 # if wxPlatform == '__WXGTK__':
212 # tb.AddSeparator() # otherwise auto-refresh sticks in status line
213 tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
217 self
.minWidth
= tb
.GetSize()[0] # minimal width is the size of toolbar
220 EVT_MENU(self
, wxID_NEW
, self
.OnNew
)
221 EVT_MENU(self
, wxID_OPEN
, self
.OnOpen
)
222 EVT_MENU(self
, wxID_SAVE
, self
.OnSaveOrSaveAs
)
223 EVT_MENU(self
, wxID_SAVEAS
, self
.OnSaveOrSaveAs
)
224 EVT_MENU(self
, wxID_EXIT
, self
.OnExit
)
226 EVT_MENU(self
, wxID_UNDO
, self
.OnUndo
)
227 EVT_MENU(self
, wxID_REDO
, self
.OnRedo
)
228 EVT_MENU(self
, wxID_CUT
, self
.OnCutDelete
)
229 EVT_MENU(self
, wxID_COPY
, self
.OnCopy
)
230 EVT_MENU(self
, wxID_PASTE
, self
.OnPaste
)
231 EVT_MENU(self
, self
.ID_TOOL_PASTE
, self
.OnPaste
)
232 EVT_MENU(self
, self
.ID_DELETE
, self
.OnCutDelete
)
233 EVT_MENU(self
, self
.ID_LOCATE
, self
.OnLocate
)
234 EVT_MENU(self
, self
.ID_TOOL_LOCATE
, self
.OnLocate
)
236 EVT_MENU(self
, self
.ID_EMBED_PANEL
, self
.OnEmbedPanel
)
237 EVT_MENU(self
, self
.ID_SHOW_TOOLS
, self
.OnShowTools
)
238 EVT_MENU(self
, self
.ID_TEST
, self
.OnTest
)
239 EVT_MENU(self
, self
.ID_REFRESH
, self
.OnRefresh
)
240 EVT_MENU(self
, self
.ID_AUTO_REFRESH
, self
.OnAutoRefresh
)
241 EVT_MENU(self
, self
.ID_TEST_HIDE
, self
.OnTestHide
)
243 EVT_MENU(self
, wxID_ABOUT
, self
.OnAbout
)
244 EVT_MENU(self
, self
.ID_README
, self
.OnReadme
)
247 EVT_UPDATE_UI(self
, wxID_SAVE
, self
.OnUpdateUI
)
248 EVT_UPDATE_UI(self
, wxID_CUT
, self
.OnUpdateUI
)
249 EVT_UPDATE_UI(self
, wxID_COPY
, self
.OnUpdateUI
)
250 EVT_UPDATE_UI(self
, wxID_PASTE
, self
.OnUpdateUI
)
251 EVT_UPDATE_UI(self
, self
.ID_LOCATE
, self
.OnUpdateUI
)
252 EVT_UPDATE_UI(self
, self
.ID_TOOL_LOCATE
, self
.OnUpdateUI
)
253 EVT_UPDATE_UI(self
, self
.ID_TOOL_PASTE
, self
.OnUpdateUI
)
254 EVT_UPDATE_UI(self
, wxID_UNDO
, self
.OnUpdateUI
)
255 EVT_UPDATE_UI(self
, wxID_REDO
, self
.OnUpdateUI
)
256 EVT_UPDATE_UI(self
, self
.ID_DELETE
, self
.OnUpdateUI
)
257 EVT_UPDATE_UI(self
, self
.ID_TEST
, self
.OnUpdateUI
)
258 EVT_UPDATE_UI(self
, self
.ID_REFRESH
, self
.OnUpdateUI
)
261 sizer
= wxBoxSizer(wxVERTICAL
)
262 sizer
.Add(wxStaticLine(self
, -1), 0, wxEXPAND
)
263 # Horizontal sizer for toolbar and splitter
264 self
.toolsSizer
= sizer1
= wxBoxSizer()
265 splitter
= wxSplitterWindow(self
, -1, style
=wxSP_3DSASH
)
266 self
.splitter
= splitter
267 splitter
.SetMinimumPaneSize(100)
270 g
.tree
= tree
= XML_Tree(splitter
, -1)
272 # Init pull-down menu data
274 g
.pullDownMenu
= pullDownMenu
= PullDownMenu(self
)
276 # Vertical toolbar for GUI buttons
277 g
.tools
= tools
= Tools(self
)
278 tools
.Show(conf
.showTools
)
279 if conf
.showTools
: sizer1
.Add(tools
, 0, wxEXPAND
)
281 tree
.RegisterKeyEvents()
283 # !!! frame styles are broken
284 # Miniframe for not embedded mode
285 miniFrame
= wxFrame(self
, -1, 'Properties & Style',
286 (conf
.panelX
, conf
.panelY
),
287 (conf
.panelWidth
, conf
.panelHeight
))
288 self
.miniFrame
= miniFrame
289 sizer2
= wxBoxSizer()
290 miniFrame
.SetAutoLayout(True)
291 miniFrame
.SetSizer(sizer2
)
292 EVT_CLOSE(self
.miniFrame
, self
.OnCloseMiniFrame
)
293 # Create panel for parameters
296 panel
= Panel(splitter
)
297 # Set plitter windows
298 splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
300 panel
= Panel(miniFrame
)
301 sizer2
.Add(panel
, 1, wxEXPAND
)
303 splitter
.Initialize(tree
)
304 sizer1
.Add(splitter
, 1, wxEXPAND
)
305 sizer
.Add(sizer1
, 1, wxEXPAND
)
306 self
.SetAutoLayout(True)
313 EVT_IDLE(self
, self
.OnIdle
)
314 EVT_CLOSE(self
, self
.OnCloseWindow
)
315 EVT_KEY_DOWN(self
, tools
.OnKeyDown
)
316 EVT_KEY_UP(self
, tools
.OnKeyUp
)
317 EVT_ICONIZE(self
, self
.OnIconize
)
319 def AppendRecent(self
, menu
):
320 # add recently used files to the menu
321 for id,name
in conf
.recentfiles
.iteritems():
323 EVT_MENU(self
,id,self
.OnRecentFile
)
326 def OnRecentFile(self
,evt
):
327 # open recently used file
328 if not self
.AskSave(): return
331 path
=conf
.recentfiles
[evt
.GetId()]
333 self
.SetStatusText('Data loaded')
335 self
.SetStatusText('Failed')
337 self
.SetStatusText('No such file')
340 def OnNew(self
, evt
):
341 if not self
.AskSave(): return
344 def OnOpen(self
, evt
):
345 if not self
.AskSave(): return
346 dlg
= wxFileDialog(self
, 'Open', os
.path
.dirname(self
.dataFile
),
347 '', '*.xrc', wxOPEN | wxCHANGE_DIR
)
348 if dlg
.ShowModal() == wxID_OK
:
350 self
.SetStatusText('Loading...')
354 self
.SetStatusText('Data loaded')
356 self
.SetStatusText('Failed')
357 self
.SaveRecent(path
)
362 def OnSaveOrSaveAs(self
, evt
):
363 if evt
.GetId() == wxID_SAVEAS
or not self
.dataFile
:
364 if self
.dataFile
: name
= ''
365 else: name
= defaultName
366 dirname
= os
.path
.abspath(os
.path
.dirname(self
.dataFile
))
367 dlg
= wxFileDialog(self
, 'Save As', dirname
, name
, '*.xrc',
368 wxSAVE | wxOVERWRITE_PROMPT | wxCHANGE_DIR
)
369 if dlg
.ShowModal() == wxID_OK
:
377 self
.SetStatusText('Saving...')
381 tmpFile
,tmpName
= tempfile
.mkstemp(prefix
='xrced-')
383 self
.Save(tmpName
) # save temporary file first
384 shutil
.move(tmpName
, path
)
386 self
.SetStatusText('Data saved')
387 self
.SaveRecent(path
)
389 self
.SetStatusText('Failed')
393 def SaveRecent(self
,path
):
394 # append to recently used files
395 if path
not in conf
.recentfiles
.values():
397 self
.recentMenu
.Append(newid
, path
)
398 EVT_MENU(self
, newid
, self
.OnRecentFile
)
399 conf
.recentfiles
[newid
] = path
401 def OnExit(self
, evt
):
404 def OnUndo(self
, evt
):
405 # Extra check to not mess with idle updating
406 if undoMan
.CanUndo():
409 def OnRedo(self
, evt
):
410 if undoMan
.CanRedo():
413 def OnCopy(self
, evt
):
414 selected
= tree
.selection
415 if not selected
: return # key pressed event
416 xxx
= tree
.GetPyData(selected
)
417 if wx
.TheClipboard
.Open():
418 data
= wx
.CustomDataObject('XRCED')
419 # Set encoding in header
421 s
= (xxx
.element
.toxml(encoding
=g
.currentEncoding
),
422 xxx
.element
.toxml())[not g
.currentEncoding
]
423 data
.SetData(cPickle
.dumps(s
))
424 wx
.TheClipboard
.SetData(data
)
425 wx
.TheClipboard
.Close()
426 self
.SetStatusText('Copied')
428 wx
.MessageBox("Unable to open the clipboard", "Error")
430 def OnPaste(self
, evt
):
431 selected
= tree
.selection
432 if not selected
: return # key pressed event
433 # For pasting with Ctrl pressed
435 if evt
.GetId() == pullDownMenu
.ID_PASTE_SIBLING
: appendChild
= False
436 elif evt
.GetId() == self
.ID_TOOL_PASTE
:
437 if g
.tree
.ctrl
: appendChild
= False
438 else: appendChild
= not tree
.NeedInsert(selected
)
439 else: appendChild
= not tree
.NeedInsert(selected
)
440 xxx
= tree
.GetPyData(selected
)
442 # If has next item, insert, else append to parent
443 nextItem
= tree
.GetNextSibling(selected
)
444 parentLeaf
= tree
.GetItemParent(selected
)
445 # Expanded container (must have children)
446 elif tree
.IsExpanded(selected
) and tree
.GetChildrenCount(selected
, False):
447 # Insert as first child
448 nextItem
= tree
.GetFirstChild(selected
)[0]
449 parentLeaf
= selected
451 # No children or unexpanded item - appendChild stays True
452 nextItem
= wxTreeItemId() # no next item
453 parentLeaf
= selected
454 parent
= tree
.GetPyData(parentLeaf
).treeObject()
456 # Create a copy of clipboard pickled element
458 if wx
.TheClipboard
.Open():
459 data
= wx
.CustomDataObject('XRCED')
460 if wx
.TheClipboard
.IsSupported(data
.GetFormat()):
461 success
= wx
.TheClipboard
.GetData(data
)
462 wx
.TheClipboard
.Close()
466 "There is no data in the clipboard in the required format",
470 xml
= cPickle
.loads(data
.GetData()) # xml representation of element
471 elem
= minidom
.parseString(xml
).childNodes
[0]
472 # Tempopary xxx object to test things
473 xxx
= MakeXXXFromDOM(parent
, elem
)
474 # Check compatibility
478 if x
.__class
__ in [xxxDialog
, xxxFrame
, xxxWizard
]:
480 if parent
.__class
__ != xxxMainNode
: error
= True
481 elif x
.__class
__ == xxxMenuBar
:
482 # Menubar can be put in frame or dialog
483 if parent
.__class
__ not in [xxxMainNode
, xxxFrame
, xxxDialog
]: error
= True
484 elif x
.__class
__ == xxxToolBar
:
485 # Toolbar can be top-level of child of panel or frame
486 if parent
.__class
__ not in [xxxMainNode
, xxxPanel
, xxxFrame
] and \
487 not parent
.isSizer
: error
= True
488 elif x
.__class
__ == xxxPanel
and parent
.__class
__ == xxxMainNode
:
490 elif x
.__class
__ == xxxSpacer
:
491 if not parent
.isSizer
: error
= True
492 elif x
.__class
__ == xxxSeparator
:
493 if not parent
.__class
__ in [xxxMenu
, xxxToolBar
]: error
= True
494 elif x
.__class
__ == xxxTool
:
495 if parent
.__class
__ != xxxToolBar
: error
= True
496 elif x
.__class
__ == xxxMenu
:
497 if not parent
.__class
__ in [xxxMainNode
, xxxMenuBar
, xxxMenu
]: error
= True
498 elif x
.__class
__ == xxxMenuItem
:
499 if not parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
500 elif x
.isSizer
and parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]:
502 else: # normal controls can be almost anywhere
503 if parent
.__class
__ == xxxMainNode
or \
504 parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error
= True
506 if parent
.__class
__ == xxxMainNode
: parentClass
= 'root'
507 else: parentClass
= parent
.className
508 wxLogError('Incompatible parent/child: parent is %s, child is %s!' %
509 (parentClass
, x
.className
))
512 # Check parent and child relationships.
513 # If parent is sizer or notebook, child is of wrong class or
514 # parent is normal window, child is child container then detach child.
515 isChildContainer
= isinstance(xxx
, xxxChildContainer
)
516 parentIsBook
= parent
.__class
__ in [xxxNotebook
, xxxChoicebook
, xxxListbook
]
517 if isChildContainer
and \
518 ((parent
.isSizer
and not isinstance(xxx
, xxxSizerItem
)) or \
519 (parentIsBook
and not isinstance(xxx
, xxxPage
)) or \
520 not (parent
.isSizer
or parentIsBook
)):
521 elem
.removeChild(xxx
.child
.element
) # detach child
522 elem
.unlink() # delete child container
523 elem
= xxx
.child
.element
# replace
524 # This may help garbage collection
525 xxx
.child
.parent
= None
526 isChildContainer
= False
527 # Parent is sizer or notebook, child is not child container
528 if parent
.isSizer
and not isChildContainer
and not isinstance(xxx
, xxxSpacer
):
529 # Create sizer item element
530 sizerItemElem
= MakeEmptyDOM(parent
.itemTag
)
531 sizerItemElem
.appendChild(elem
)
533 elif isinstance(parent
, xxxNotebook
) and not isChildContainer
:
534 pageElem
= MakeEmptyDOM('notebookpage')
535 pageElem
.appendChild(elem
)
537 elif isinstance(parent
, xxxChoicebook
) and not isChildContainer
:
538 pageElem
= MakeEmptyDOM('choicebookpage')
539 pageElem
.appendChild(elem
)
541 elif isinstance(parent
, xxxListbook
) and not isChildContainer
:
542 pageElem
= MakeEmptyDOM('listbookpage')
543 pageElem
.appendChild(elem
)
545 # Insert new node, register undo
546 newItem
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
)
547 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
548 # Scroll to show new item (!!! redundant?)
549 tree
.EnsureVisible(newItem
)
550 tree
.SelectItem(newItem
)
551 if not tree
.IsVisible(newItem
):
552 tree
.ScrollTo(newItem
)
555 if g
.testWin
and tree
.IsHighlatable(newItem
):
557 tree
.needUpdate
= True
558 tree
.pendingHighLight
= newItem
560 tree
.pendingHighLight
= None
562 self
.SetStatusText('Pasted')
565 def OnCutDelete(self
, evt
):
566 selected
= tree
.selection
567 if not selected
: return # key pressed event
569 if evt
.GetId() == wxID_CUT
:
571 status
= 'Removed to clipboard'
573 self
.lastOp
= 'DELETE'
577 # If deleting top-level item, delete testWin
578 if selected
== g
.testWin
.item
:
582 # Remove highlight, update testWin
583 if g
.testWin
.highLight
:
584 g
.testWin
.highLight
.Remove()
585 tree
.needUpdate
= True
588 index
= tree
.ItemFullIndex(selected
)
589 parent
= tree
.GetPyData(tree
.GetItemParent(selected
)).treeObject()
590 elem
= tree
.RemoveLeaf(selected
)
591 undoMan
.RegisterUndo(UndoCutDelete(index
, parent
, elem
))
592 if evt
.GetId() == wxID_CUT
:
593 if wx
.TheClipboard
.Open():
594 data
= wx
.CustomDataObject('XRCED')
596 s
= (elem
.toxml(encoding
=g
.currentEncoding
),
597 elem
.toxml())[not g
.currentEncoding
]
598 data
.SetData(cPickle
.dumps(s
))
599 wx
.TheClipboard
.SetData(data
)
600 wx
.TheClipboard
.Close()
602 wx
.MessageBox("Unable to open the clipboard", "Error")
603 tree
.pendingHighLight
= None
605 tree
.selection
= None
610 self
.SetStatusText(status
)
612 def OnSubclass(self
, evt
):
613 selected
= tree
.selection
614 xxx
= tree
.GetPyData(selected
).treeObject()
616 subclass
= xxx
.subclass
617 dlg
= wxTextEntryDialog(self
, 'Subclass:', defaultValue
=subclass
)
618 if dlg
.ShowModal() == wxID_OK
:
619 subclass
= dlg
.GetValue()
621 elem
.setAttribute('subclass', subclass
)
622 elif elem
.hasAttribute('subclass'):
623 elem
.removeAttribute('subclass')
625 xxx
.subclass
= elem
.getAttribute('subclass')
626 tree
.SetItemText(selected
, xxx
.treeName())
627 panel
.pages
[0].box
.SetLabel(xxx
.panelName())
630 def OnEmbedPanel(self
, evt
):
631 conf
.embedPanel
= evt
.IsChecked()
633 # Remember last dimentions
634 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
635 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
636 size
= self
.GetSize()
637 pos
= self
.GetPosition()
638 sizePanel
= panel
.GetSize()
639 panel
.Reparent(self
.splitter
)
640 self
.miniFrame
.GetSizer().Remove(panel
)
642 self
.SetDimensions(pos
.x
, pos
.y
, size
.width
+ sizePanel
.width
, size
.height
)
643 self
.splitter
.SplitVertically(tree
, panel
, conf
.sashPos
)
644 self
.miniFrame
.Show(False)
646 conf
.sashPos
= self
.splitter
.GetSashPosition()
647 pos
= self
.GetPosition()
648 size
= self
.GetSize()
649 sizePanel
= panel
.GetSize()
650 self
.splitter
.Unsplit(panel
)
651 sizer
= self
.miniFrame
.GetSizer()
652 panel
.Reparent(self
.miniFrame
)
654 sizer
.Add(panel
, 1, wxEXPAND
)
655 self
.miniFrame
.Show(True)
656 self
.miniFrame
.SetDimensions(conf
.panelX
, conf
.panelY
,
657 conf
.panelWidth
, conf
.panelHeight
)
659 self
.SetDimensions(pos
.x
, pos
.y
,
660 max(size
.width
- sizePanel
.width
, self
.minWidth
), size
.height
)
662 def OnShowTools(self
, evt
):
663 conf
.showTools
= evt
.IsChecked()
664 g
.tools
.Show(conf
.showTools
)
666 self
.toolsSizer
.Prepend(g
.tools
, 0, wxEXPAND
)
668 self
.toolsSizer
.Remove(g
.tools
)
669 self
.toolsSizer
.Layout()
671 def OnTest(self
, evt
):
672 if not tree
.selection
: return # key pressed event
673 tree
.ShowTestWindow(tree
.selection
)
675 def OnTestHide(self
, evt
):
676 tree
.CloseTestWindow()
678 # Find object by relative position
679 def FindObject(self
, item
, obj
):
680 # We simply perform depth-first traversal, sinse it's too much
681 # hassle to deal with all sizer/window combinations
682 w
= tree
.FindNodeObject(item
)
685 if tree
.ItemHasChildren(item
):
686 child
= tree
.GetFirstChild(item
)[0]
688 found
= self
.FindObject(child
, obj
)
689 if found
: return found
690 child
= tree
.GetNextSibling(child
)
693 def OnTestWinLeftDown(self
, evt
):
694 pos
= evt
.GetPosition()
695 self
.SetHandler(g
.testWin
)
696 g
.testWin
.Disconnect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
)
697 item
= self
.FindObject(g
.testWin
.item
, evt
.GetEventObject())
699 tree
.SelectItem(item
)
700 self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, False)
702 self
.SetStatusText('Selected %s' % tree
.GetItemText(item
))
704 self
.SetStatusText('Locate failed!')
706 def SetHandler(self
, w
, h
=None):
709 w
.SetCursor(wxCROSS_CURSOR
)
712 w
.SetCursor(wxNullCursor
)
713 for ch
in w
.GetChildren():
714 self
.SetHandler(ch
, h
)
716 def OnLocate(self
, evt
):
718 if evt
.GetId() == self
.ID_LOCATE
or \
719 evt
.GetId() == self
.ID_TOOL_LOCATE
and evt
.IsChecked():
720 self
.SetHandler(g
.testWin
, g
.testWin
)
721 g
.testWin
.Connect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
, self
.OnTestWinLeftDown
)
722 if evt
.GetId() == self
.ID_LOCATE
:
723 self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, True)
724 elif evt
.GetId() == self
.ID_TOOL_LOCATE
and not evt
.IsChecked():
725 self
.SetHandler(g
.testWin
, None)
726 g
.testWin
.Disconnect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
)
727 self
.SetStatusText('Click somewhere in your test window now')
729 def OnRefresh(self
, evt
):
730 # If modified, apply first
731 selection
= tree
.selection
733 xxx
= tree
.GetPyData(selection
)
734 if xxx
and panel
.IsModified():
735 tree
.Apply(xxx
, selection
)
738 tree
.CreateTestWin(g
.testWin
.item
)
739 panel
.modified
= False
740 tree
.needUpdate
= False
742 def OnAutoRefresh(self
, evt
):
743 conf
.autoRefresh
= evt
.IsChecked()
744 self
.menuBar
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
745 self
.tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
)
747 def OnAbout(self
, evt
):
751 (c) Roman Rolinsky <rollrom@users.sourceforge.net>
752 Homepage: http://xrced.sourceforge.net\
754 dlg
= wxMessageDialog(self
, str, 'About XRCed', wxOK | wxCENTRE
)
758 def OnReadme(self
, evt
):
759 text
= open(os
.path
.join(basePath
, 'README.txt'), 'r').read()
760 dlg
= ScrolledMessageDialog(self
, text
, "XRCed README")
764 # Simple emulation of python command line
765 def OnDebugCMD(self
, evt
):
768 exec raw_input('C:\> ')
773 (etype
, value
, tb
) =sys
.exc_info()
774 tblist
=traceback
.extract_tb(tb
)[1:]
775 msg
=' '.join(traceback
.format_exception_only(etype
, value
)
776 +traceback
.format_list(tblist
))
779 def OnCreate(self
, evt
):
780 selected
= tree
.selection
781 if tree
.ctrl
: appendChild
= False
782 else: appendChild
= not tree
.NeedInsert(selected
)
783 xxx
= tree
.GetPyData(selected
)
787 # If has previous item, insert after it, else append to parent
789 parentLeaf
= tree
.GetItemParent(selected
)
791 # If has next item, insert, else append to parent
792 nextItem
= tree
.GetNextSibling(selected
)
793 parentLeaf
= tree
.GetItemParent(selected
)
794 # Expanded container (must have children)
795 elif tree
.shift
and tree
.IsExpanded(selected
) \
796 and tree
.GetChildrenCount(selected
, False):
797 nextItem
= tree
.GetFirstChild(selected
)[0]
798 parentLeaf
= selected
800 nextItem
= wxTreeItemId()
801 parentLeaf
= selected
802 parent
= tree
.GetPyData(parentLeaf
)
803 if parent
.hasChild
: parent
= parent
.child
806 if evt
.GetId() == ID_NEW
.REF
:
807 ref
= wxGetTextFromUser('Create reference to:', 'Create reference')
809 xxx
= MakeEmptyRefXXX(parent
, ref
)
811 # Create empty element
812 className
= pullDownMenu
.createMap
[evt
.GetId()]
813 xxx
= MakeEmptyXXX(parent
, className
)
815 # Set default name for top-level windows
816 if parent
.__class
__ == xxxMainNode
:
817 cl
= xxx
.treeObject().__class
__
818 frame
.maxIDs
[cl
] += 1
819 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
820 # And for some other standard controls
821 elif parent
.__class
__ == xxxStdDialogButtonSizer
:
822 xxx
.setTreeName(pullDownMenu
.stdButtonIDs
[evt
.GetId()][0])
823 # We can even set label
824 obj
= xxx
.treeObject()
825 elem
= g
.tree
.dom
.createElement('label')
826 elem
.appendChild(g
.tree
.dom
.createTextNode(pullDownMenu
.stdButtonIDs
[evt
.GetId()][1]))
827 obj
.params
['label'] = xxxParam(elem
)
828 xxx
.treeObject().element
.appendChild(elem
)
830 # Insert new node, register undo
832 newItem
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
)
833 undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
))
834 tree
.EnsureVisible(newItem
)
835 tree
.SelectItem(newItem
)
836 if not tree
.IsVisible(newItem
):
837 tree
.ScrollTo(newItem
)
840 if g
.testWin
and tree
.IsHighlatable(newItem
):
842 tree
.needUpdate
= True
843 tree
.pendingHighLight
= newItem
845 tree
.pendingHighLight
= None
849 # Replace one object with another
850 def OnReplace(self
, evt
):
851 selected
= tree
.selection
852 xxx
= tree
.GetPyData(selected
).treeObject()
854 parent
= elem
.parentNode
855 undoMan
.RegisterUndo(UndoReplace(selected
))
857 className
= pullDownMenu
.createMap
[evt
.GetId() - 1000]
858 # Create temporary empty node (with default values)
859 dummy
= MakeEmptyDOM(className
)
860 if className
== 'spacer' and xxx
.className
!= 'spacer':
862 elif xxx
.className
== 'spacer' and className
!= 'spacer':
865 klass
= xxxDict
[className
]
866 # Remove non-compatible children
867 if tree
.ItemHasChildren(selected
) and not klass
.hasChildren
:
868 tree
.DeleteChildren(selected
)
869 nodes
= elem
.childNodes
[:]
872 if node
.nodeType
!= minidom
.Node
.ELEMENT_NODE
: continue
876 if not klass
.hasChildren
: remove
= True
877 elif tag
not in klass
.allParams
and \
878 (not klass
.hasStyle
or tag
not in klass
.styles
):
883 elem
.removeChild(node
)
886 # Remove sizeritem child if spacer
887 if className
== 'spacer' and xxx
.className
!= 'spacer':
888 sizeritem
= elem
.parentNode
889 assert sizeritem
.getAttribute('class') == 'sizeritem'
890 sizeritem
.removeChild(elem
)
893 tree
.GetPyData(selected
).hasChild
= false
894 elif xxx
.className
== 'spacer' and className
!= 'spacer':
895 # Create sizeritem element
896 assert xxx
.parent
.isSizer
897 elem
.setAttribute('class', 'sizeritem')
898 node
= MakeEmptyDOM(className
)
899 elem
.appendChild(node
)
900 # Replace to point to new object
901 xxx
= xxxSizerItem(xxx
.parent
, elem
)
903 tree
.SetPyData(selected
, xxx
)
906 # Copy parameters present in dummy but not in elem
907 for node
in dummy
.childNodes
:
908 if node
.tagName
not in tags
: elem
.appendChild(node
.cloneNode(True))
912 elem
.setAttribute('class', className
)
913 if elem
.hasAttribute('subclass'):
914 elem
.removeAttribute('subclass') # clear subclassing
915 # Re-create xxx element
916 xxx
= MakeXXXFromDOM(xxx
.parent
, elem
)
917 # Update parent in child objects
918 if tree
.ItemHasChildren(selected
):
919 i
, cookie
= tree
.GetFirstChild(selected
)
921 x
= tree
.GetPyData(i
)
923 if x
.hasChild
: x
.child
.parent
= xxx
924 i
, cookie
= tree
.GetNextChild(selected
, cookie
)
927 if tree
.GetPyData(selected
).hasChild
: # child container
928 container
= tree
.GetPyData(selected
)
929 container
.child
= xxx
930 container
.hasChildren
= xxx
.hasChildren
931 container
.isSizer
= xxx
.isSizer
934 tree
.SetPyData(selected
, xxx
)
935 tree
.SetItemText(selected
, xxx
.treeName())
936 tree
.SetItemImage(selected
, xxx
.treeImage())
938 # Set default name for top-level windows
939 if parent
.__class
__ == xxxMainNode
:
940 cl
= xxx
.treeObject().__class
__
941 frame
.maxIDs
[cl
] += 1
942 xxx
.setTreeName('%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]))
949 #undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected))
951 if g
.testWin
and tree
.IsHighlatable(selected
):
953 tree
.needUpdate
= True
954 tree
.pendingHighLight
= selected
956 tree
.pendingHighLight
= None
960 # Expand/collapse subtree
961 def OnExpand(self
, evt
):
962 if tree
.selection
: tree
.ExpandAll(tree
.selection
)
963 else: tree
.ExpandAll(tree
.root
)
964 def OnCollapse(self
, evt
):
965 if tree
.selection
: tree
.CollapseAll(tree
.selection
)
966 else: tree
.CollapseAll(tree
.root
)
968 def OnPullDownHighlight(self
, evt
):
969 menuId
= evt
.GetMenuId()
971 menu
= evt
.GetEventObject()
972 help = menu
.GetHelpString(menuId
)
973 self
.SetStatusText(help)
975 self
.SetStatusText('')
977 def OnUpdateUI(self
, evt
):
978 if evt
.GetId() in [wxID_CUT
, wxID_COPY
, self
.ID_DELETE
]:
979 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
980 elif evt
.GetId() == wxID_SAVE
:
981 evt
.Enable(self
.modified
)
982 elif evt
.GetId() in [wxID_PASTE
, self
.ID_TOOL_PASTE
]:
983 evt
.Enable(tree
.selection
is not None)
984 elif evt
.GetId() == self
.ID_TEST
:
985 evt
.Enable(tree
.selection
is not None and tree
.selection
!= tree
.root
)
986 elif evt
.GetId() in [self
.ID_LOCATE
, self
.ID_TOOL_LOCATE
]:
987 evt
.Enable(g
.testWin
is not None)
988 elif evt
.GetId() == wxID_UNDO
: evt
.Enable(undoMan
.CanUndo())
989 elif evt
.GetId() == wxID_REDO
: evt
.Enable(undoMan
.CanRedo())
991 def OnIdle(self
, evt
):
992 if self
.inIdle
: return # Recursive call protection
998 self
.SetStatusText('Refreshing test window...')
1000 tree
.CreateTestWin(g
.testWin
.item
)
1001 self
.SetStatusText('')
1002 tree
.needUpdate
= False
1003 elif tree
.pendingHighLight
:
1005 tree
.HighLight(tree
.pendingHighLight
)
1007 # Remove highlight if any problem
1008 if g
.testWin
.highLight
:
1009 g
.testWin
.highLight
.Remove()
1010 tree
.pendingHighLight
= None
1017 # We don't let close panel window
1018 def OnCloseMiniFrame(self
, evt
):
1021 def OnIconize(self
, evt
):
1022 conf
.x
, conf
.y
= self
.GetPosition()
1023 conf
.width
, conf
.height
= self
.GetSize()
1025 conf
.sashPos
= self
.splitter
.GetSashPosition()
1027 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1028 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1029 self
.miniFrame
.Iconize()
1032 def OnCloseWindow(self
, evt
):
1033 if not self
.AskSave(): return
1034 if g
.testWin
: g
.testWin
.Destroy()
1035 if not panel
.GetPageCount() == 2:
1036 panel
.page2
.Destroy()
1038 # If we don't do this, page does not get destroyed (a bug?)
1040 if not self
.IsIconized():
1041 conf
.x
, conf
.y
= self
.GetPosition()
1042 conf
.width
, conf
.height
= self
.GetSize()
1044 conf
.sashPos
= self
.splitter
.GetSashPosition()
1046 conf
.panelX
, conf
.panelY
= self
.miniFrame
.GetPosition()
1047 conf
.panelWidth
, conf
.panelHeight
= self
.miniFrame
.GetSize()
1053 self
.SetModified(False)
1059 # Numbers for new controls
1061 for cl
in [xxxPanel
, xxxDialog
, xxxFrame
,
1062 xxxMenuBar
, xxxMenu
, xxxToolBar
,
1063 xxxWizard
, xxxBitmap
, xxxIcon
]:
1066 def SetModified(self
, state
=True):
1067 self
.modified
= state
1068 name
= os
.path
.basename(self
.dataFile
)
1069 if not name
: name
= defaultName
1071 self
.SetTitle(progname
+ ': ' + name
+ ' *')
1073 self
.SetTitle(progname
+ ': ' + name
)
1075 def Open(self
, path
):
1076 if not os
.path
.exists(path
):
1077 wxLogError('File does not exists: %s' % path
)
1079 # Try to read the file
1083 dom
= minidom
.parse(f
)
1085 # Set encoding global variable and default encoding
1087 g
.currentEncoding
= dom
.encoding
1088 wx
.SetDefaultPyEncoding(g
.currentEncoding
.encode())
1090 g
.currentEncoding
= ''
1092 self
.dataFile
= path
= os
.path
.abspath(path
)
1093 dir = os
.path
.dirname(path
)
1094 if dir: os
.chdir(dir)
1096 self
.SetTitle(progname
+ ': ' + os
.path
.basename(path
))
1098 # Nice exception printing
1099 inf
= sys
.exc_info()
1100 wxLogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1101 wxLogError('Error reading file: %s' % path
)
1106 def Indent(self
, node
, indent
= 0):
1107 # Copy child list because it will change soon
1108 children
= node
.childNodes
[:]
1109 # Main node doesn't need to be indented
1111 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1112 node
.parentNode
.insertBefore(text
, node
)
1114 # Append newline after last child, except for text nodes
1115 if children
[-1].nodeType
== minidom
.Node
.ELEMENT_NODE
:
1116 text
= self
.domCopy
.createTextNode('\n' + ' ' * indent
)
1117 node
.appendChild(text
)
1118 # Indent children which are elements
1120 if n
.nodeType
== minidom
.Node
.ELEMENT_NODE
:
1121 self
.Indent(n
, indent
+ 2)
1123 def Save(self
, path
):
1127 if tree
.selection
and panel
.IsModified():
1128 self
.OnRefresh(wxCommandEvent())
1129 if g
.currentEncoding
:
1130 f
= codecs
.open(path
, 'wt', g
.currentEncoding
)
1132 f
= codecs
.open(path
, 'wt')
1133 # Make temporary copy for formatting it
1134 # !!! We can't clone dom node, it works only once
1135 #self.domCopy = tree.dom.cloneNode(True)
1136 self
.domCopy
= MyDocument()
1137 mainNode
= self
.domCopy
.appendChild(tree
.mainNode
.cloneNode(True))
1138 # Remove first child (test element)
1139 testElem
= mainNode
.firstChild
1140 mainNode
.removeChild(testElem
)
1142 self
.Indent(mainNode
)
1143 self
.domCopy
.writexml(f
, encoding
= g
.currentEncoding
)
1145 self
.domCopy
.unlink()
1147 self
.SetModified(False)
1148 panel
.SetModified(False)
1150 inf
= sys
.exc_info()
1151 wxLogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1])
1152 wxLogError('Error writing file: %s' % path
)
1156 if not (self
.modified
or panel
.IsModified()): return True
1157 flags
= wxICON_EXCLAMATION | wxYES_NO | wxCANCEL | wxCENTRE
1158 dlg
= wxMessageDialog( self
, 'File is modified. Save before exit?',
1159 'Save before too late?', flags
)
1160 say
= dlg
.ShowModal()
1164 self
.OnSaveOrSaveAs(wxCommandEvent(wxID_SAVE
))
1165 # If save was successful, modified flag is unset
1166 if not self
.modified
: return True
1167 elif say
== wxID_NO
:
1168 self
.SetModified(False)
1169 panel
.SetModified(False)
1176 ################################################################################
1179 print >> sys
.stderr
, 'usage: xrced [-dhiv] [file]'
1184 if wxVERSION
[:3] < MinWxVersion
:
1186 This version of XRCed may not work correctly on your version of wxWindows. \
1187 Please upgrade wxWindows to %d.%d.%d or higher.''' % MinWxVersion
)
1189 # Process comand-line
1192 opts
, args
= getopt
.getopt(sys
.argv
[1:], 'dhiv')
1200 print 'XRCed version', version
1203 except getopt
.GetoptError
:
1204 if wxPlatform
!= '__WXMAC__': # macs have some extra parameters
1205 print >> sys
.stderr
, 'Unknown option'
1209 self
.SetAppName('xrced')
1212 conf
= g
.conf
= wxConfig(style
= wxCONFIG_USE_LOCAL_FILE
)
1213 conf
.autoRefresh
= conf
.ReadInt('autorefresh', True)
1214 pos
= conf
.ReadInt('x', -1), conf
.ReadInt('y', -1)
1215 size
= conf
.ReadInt('width', 800), conf
.ReadInt('height', 600)
1216 conf
.embedPanel
= conf
.ReadInt('embedPanel', True)
1217 conf
.showTools
= conf
.ReadInt('showTools', True)
1218 conf
.sashPos
= conf
.ReadInt('sashPos', 200)
1219 # read recently used files
1220 recentfiles
=conf
.Read('recentFiles','')
1223 for fil
in recentfiles
.split('|'):
1224 conf
.recentfiles
[wxNewId()]=fil
1225 if not conf
.embedPanel
:
1226 conf
.panelX
= conf
.ReadInt('panelX', -1)
1227 conf
.panelY
= conf
.ReadInt('panelY', -1)
1229 conf
.panelX
= conf
.panelY
= -1
1230 conf
.panelWidth
= conf
.ReadInt('panelWidth', 200)
1231 conf
.panelHeight
= conf
.ReadInt('panelHeight', 200)
1232 conf
.panic
= not conf
.HasEntry('nopanic')
1234 wxFileSystem_AddHandler(wxMemoryFSHandler())
1236 frame
= Frame(pos
, size
)
1239 # Load file after showing
1242 frame
.open = frame
.Open(args
[0])
1249 wc
= wxConfigBase_Get()
1250 wc
.WriteInt('autorefresh', conf
.autoRefresh
)
1251 wc
.WriteInt('x', conf
.x
)
1252 wc
.WriteInt('y', conf
.y
)
1253 wc
.WriteInt('width', conf
.width
)
1254 wc
.WriteInt('height', conf
.height
)
1255 wc
.WriteInt('embedPanel', conf
.embedPanel
)
1256 wc
.WriteInt('showTools', conf
.showTools
)
1257 if not conf
.embedPanel
:
1258 wc
.WriteInt('panelX', conf
.panelX
)
1259 wc
.WriteInt('panelY', conf
.panelY
)
1260 wc
.WriteInt('sashPos', conf
.sashPos
)
1261 wc
.WriteInt('panelWidth', conf
.panelWidth
)
1262 wc
.WriteInt('panelHeight', conf
.panelHeight
)
1263 wc
.WriteInt('nopanic', True)
1264 wc
.Write('recentFiles', '|'.join(conf
.recentfiles
.values()[-5:]))
1268 app
= App(0, useBestVisual
=False)
1269 #app.SetAssertMode(wxPYAPP_ASSERT_LOG)
1275 if __name__
== '__main__':