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 
  25 import os
, sys
, getopt
, re
, traceback
, tempfile
, shutil
 
  28 from tree 
import *                      # imports xxx which imports params 
  31 # Cleanup recursive import sideeffects, otherwise we can't create undoMan 
  33 undo
.ParamPage 
= ParamPage
 
  34 undoMan 
= g
.undoMan 
= UndoManager() 
  36 # Set application path for loading resources 
  37 if __name__ 
== '__main__': 
  38     basePath 
= os
.path
.dirname(sys
.argv
[0]) 
  40     basePath 
= os
.path
.dirname(__file__
) 
  42 # 1 adds CMD command to Help menu 
  46 <HTML><H2>Welcome to XRC<font color="blue">ed</font></H2><H3><font color="green">DON'T PANIC :)</font></H3> 
  47 Read this note before clicking on anything!<P> 
  48 To start select tree root, then popup menu with your right mouse button, 
  49 select "Append Child", and then any command.<P> 
  50 Or just press one of the buttons on the tools palette.<P> 
  51 Enter XML ID, change properties, create children.<P> 
  52 To test your interface select Test command (View menu).<P> 
  53 Consult README file for the details.</HTML> 
  56 defaultIDs 
= {xxxPanel
:'PANEL', xxxDialog
:'DIALOG', xxxFrame
:'FRAME', 
  57               xxxMenuBar
:'MENUBAR', xxxMenu
:'MENU', xxxToolBar
:'TOOLBAR', 
  60 ################################################################################ 
  62 # ScrolledMessageDialog - modified from wxPython lib to set fixed-width font 
  63 class ScrolledMessageDialog(wxDialog
): 
  64     def __init__(self
, parent
, msg
, caption
, pos 
= wxDefaultPosition
, size 
= (500,300)): 
  65         from wxPython
.lib
.layoutf 
import Layoutf
 
  66         wxDialog
.__init
__(self
, parent
, -1, caption
, pos
, size
) 
  67         text 
= wxTextCtrl(self
, -1, msg
, wxDefaultPosition
, 
  68                              wxDefaultSize
, wxTE_MULTILINE | wxTE_READONLY
) 
  69         text
.SetFont(g
.modernFont()) 
  71         # !!! possible bug - GetTextExtent without font returns sysfont dims 
  72         w
, h 
= dc
.GetFullTextExtent(' ', g
.modernFont())[:2] 
  73         ok 
= wxButton(self
, wxID_OK
, "OK") 
  74         text
.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self
,ok
))) 
  75         text
.SetSize((w 
* 80 + 30, h 
* 40)) 
  77         ok
.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self
,))) 
  78         self
.SetAutoLayout(True) 
  80         self
.CenterOnScreen(wxBOTH
) 
  82 ################################################################################ 
  84 # Event handler for using during location 
  85 class Locator(wxEvtHandler
): 
  86     def ProcessEvent(self
, evt
): 
  90     def __init__(self
, pos
, size
): 
  91         wxFrame
.__init
__(self
, None, -1, '', pos
, size
) 
  93         frame 
= g
.frame 
= self
 
  94         bar 
= self
.CreateStatusBar(2) 
  95         bar
.SetStatusWidths([-1, 40]) 
  96         self
.SetIcon(images
.getIconIcon()) 
 101         # Load our own resources 
 102         self
.res 
= wxXmlResource('') 
 103         # !!! Blocking of assert failure occurring in older unicode builds 
 105             self
.res
.Load(os
.path
.join(basePath
, 'xrced.xrc')) 
 106         except wx
._core
.PyAssertionError
: 
 107             print 'PyAssertionError was ignored' 
 110         menuBar 
= wxMenuBar() 
 113         menu
.Append(wxID_NEW
, '&New\tCtrl-N', 'New file') 
 114         menu
.AppendSeparator() 
 115         menu
.Append(wxID_OPEN
, '&Open...\tCtrl-O', 'Open XRC file') 
 116         self
.recentMenu 
= wxMenu() 
 117         self
.AppendRecent(self
.recentMenu
) 
 118         menu
.AppendMenu(-1, 'Open Recent', self
.recentMenu
, 'Open a recent file') 
 119         menu
.AppendSeparator() 
 120         menu
.Append(wxID_SAVE
, '&Save\tCtrl-S', 'Save XRC file') 
 121         menu
.Append(wxID_SAVEAS
, 'Save &As...', 'Save XRC file under different name') 
 122         menu
.AppendSeparator() 
 123         menu
.Append(wxID_EXIT
, '&Quit\tCtrl-Q', 'Exit application') 
 125         menuBar
.Append(menu
, '&File') 
 128         menu
.Append(wxID_UNDO
, '&Undo\tCtrl-Z', 'Undo') 
 129         menu
.Append(wxID_REDO
, '&Redo\tCtrl-Y', 'Redo') 
 130         menu
.AppendSeparator() 
 131         menu
.Append(wxID_CUT
, 'Cut\tCtrl-X', 'Cut to the clipboard') 
 132         menu
.Append(wxID_COPY
, '&Copy\tCtrl-C', 'Copy to the clipboard') 
 133         menu
.Append(wxID_PASTE
, '&Paste\tCtrl-V', 'Paste from the clipboard') 
 134         self
.ID_DELETE 
= wxNewId() 
 135         menu
.Append(self
.ID_DELETE
, '&Delete\tCtrl-D', 'Delete object') 
 136         menu
.AppendSeparator() 
 137         self
.ID_LOCATE 
= wxNewId() 
 138         self
.ID_TOOL_LOCATE 
= wxNewId() 
 139         self
.ID_TOOL_PASTE 
= wxNewId() 
 140         menu
.Append(self
.ID_LOCATE
, '&Locate\tCtrl-L', 'Locate control in test window and select it') 
 141         menuBar
.Append(menu
, '&Edit') 
 144         self
.ID_EMBED_PANEL 
= wxNewId() 
 145         menu
.Append(self
.ID_EMBED_PANEL
, '&Embed Panel', 
 146                     'Toggle embedding properties panel in the main window', True) 
 147         menu
.Check(self
.ID_EMBED_PANEL
, conf
.embedPanel
) 
 148         self
.ID_SHOW_TOOLS 
= wxNewId() 
 149         menu
.Append(self
.ID_SHOW_TOOLS
, 'Show &Tools', 'Toggle tools', True) 
 150         menu
.Check(self
.ID_SHOW_TOOLS
, conf
.showTools
) 
 151         menu
.AppendSeparator() 
 152         self
.ID_TEST 
= wxNewId() 
 153         menu
.Append(self
.ID_TEST
, '&Test\tF5', 'Show test window') 
 154         self
.ID_REFRESH 
= wxNewId() 
 155         menu
.Append(self
.ID_REFRESH
, '&Refresh\tCtrl-R', 'Refresh test window') 
 156         self
.ID_AUTO_REFRESH 
= wxNewId() 
 157         menu
.Append(self
.ID_AUTO_REFRESH
, '&Auto-refresh\tCtrl-A', 
 158                     'Toggle auto-refresh mode', True) 
 159         menu
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
) 
 160         self
.ID_TEST_HIDE 
= wxNewId() 
 161         menu
.Append(self
.ID_TEST_HIDE
, '&Hide\tCtrl-H', 'Close test window') 
 162         menuBar
.Append(menu
, '&View') 
 165         menu
.Append(wxID_ABOUT
, '&About...', 'About XCRed') 
 166         self
.ID_README 
= wxNewId() 
 167         menu
.Append(self
.ID_README
, '&Readme...', 'View the README file') 
 169             self
.ID_DEBUG_CMD 
= wxNewId() 
 170             menu
.Append(self
.ID_DEBUG_CMD
, 'CMD', 'Python command line') 
 171             EVT_MENU(self
, self
.ID_DEBUG_CMD
, self
.OnDebugCMD
) 
 172         menuBar
.Append(menu
, '&Help') 
 174         self
.menuBar 
= menuBar
 
 175         self
.SetMenuBar(menuBar
) 
 178         tb 
= self
.CreateToolBar(wxTB_HORIZONTAL | wxNO_BORDER | wxTB_FLAT
) 
 179         tb
.SetToolBitmapSize((24,24)) 
 180         new_bmp  
= wx
.ArtProvider
.GetBitmap(wx
.ART_NEW
, wx
.ART_TOOLBAR
) 
 181         open_bmp 
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_OPEN
, wx
.ART_TOOLBAR
) 
 182         save_bmp 
= wx
.ArtProvider
.GetBitmap(wx
.ART_FILE_SAVE
, wx
.ART_TOOLBAR
) 
 183         undo_bmp 
= wx
.ArtProvider
.GetBitmap(wx
.ART_UNDO
, wx
.ART_TOOLBAR
) 
 184         redo_bmp 
= wx
.ArtProvider
.GetBitmap(wx
.ART_REDO
, wx
.ART_TOOLBAR
) 
 185         cut_bmp  
= wx
.ArtProvider
.GetBitmap(wx
.ART_CUT
, wx
.ART_TOOLBAR
) 
 186         copy_bmp 
= wx
.ArtProvider
.GetBitmap(wx
.ART_COPY
, wx
.ART_TOOLBAR
) 
 187         paste_bmp
= wx
.ArtProvider
.GetBitmap(wx
.ART_PASTE
, wx
.ART_TOOLBAR
) 
 189         tb
.AddSimpleTool(wxID_NEW
, new_bmp
, 'New', 'New file') 
 190         tb
.AddSimpleTool(wxID_OPEN
, open_bmp
, 'Open', 'Open file') 
 191         tb
.AddSimpleTool(wxID_SAVE
, save_bmp
, 'Save', 'Save file') 
 192         tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
)) 
 193         tb
.AddSimpleTool(wxID_UNDO
, undo_bmp
, 'Undo', 'Undo') 
 194         tb
.AddSimpleTool(wxID_REDO
, redo_bmp
, 'Redo', 'Redo') 
 195         tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
)) 
 196         tb
.AddSimpleTool(wxID_CUT
, cut_bmp
, 'Cut', 'Cut') 
 197         tb
.AddSimpleTool(wxID_COPY
, copy_bmp
, 'Copy', 'Copy') 
 198         tb
.AddSimpleTool(self
.ID_TOOL_PASTE
, paste_bmp
, 'Paste', 'Paste') 
 199         tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
)) 
 200         tb
.AddSimpleTool(self
.ID_TOOL_LOCATE
, 
 201                         images
.getLocateBitmap(), #images.getLocateArmedBitmap(), 
 202                         'Locate', 'Locate control in test window and select it', True) 
 203         tb
.AddControl(wxStaticLine(tb
, -1, size
=(-1,23), style
=wxLI_VERTICAL
)) 
 204         tb
.AddSimpleTool(self
.ID_TEST
, images
.getTestBitmap(), 'Test', 'Test window') 
 205         tb
.AddSimpleTool(self
.ID_REFRESH
, images
.getRefreshBitmap(), 
 206                          'Refresh', 'Refresh view') 
 207         tb
.AddSimpleTool(self
.ID_AUTO_REFRESH
, images
.getAutoRefreshBitmap(), 
 208                          'Auto-refresh', 'Toggle auto-refresh mode', True) 
 209         if wxPlatform 
== '__WXGTK__': 
 210             tb
.AddSeparator()   # otherwise auto-refresh sticks in status line 
 211         tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
) 
 215         self
.minWidth 
= tb
.GetSize()[0] # minimal width is the size of toolbar 
 218         EVT_MENU(self
, wxID_NEW
, self
.OnNew
) 
 219         EVT_MENU(self
, wxID_OPEN
, self
.OnOpen
) 
 220         EVT_MENU(self
, wxID_SAVE
, self
.OnSaveOrSaveAs
) 
 221         EVT_MENU(self
, wxID_SAVEAS
, self
.OnSaveOrSaveAs
) 
 222         EVT_MENU(self
, wxID_EXIT
, self
.OnExit
) 
 224         EVT_MENU(self
, wxID_UNDO
, self
.OnUndo
) 
 225         EVT_MENU(self
, wxID_REDO
, self
.OnRedo
) 
 226         EVT_MENU(self
, wxID_CUT
, self
.OnCutDelete
) 
 227         EVT_MENU(self
, wxID_COPY
, self
.OnCopy
) 
 228         EVT_MENU(self
, wxID_PASTE
, self
.OnPaste
) 
 229         EVT_MENU(self
, self
.ID_TOOL_PASTE
, self
.OnPaste
) 
 230         EVT_MENU(self
, self
.ID_DELETE
, self
.OnCutDelete
) 
 231         EVT_MENU(self
, self
.ID_LOCATE
, self
.OnLocate
) 
 232         EVT_MENU(self
, self
.ID_TOOL_LOCATE
, self
.OnLocate
) 
 234         EVT_MENU(self
, self
.ID_EMBED_PANEL
, self
.OnEmbedPanel
) 
 235         EVT_MENU(self
, self
.ID_SHOW_TOOLS
, self
.OnShowTools
) 
 236         EVT_MENU(self
, self
.ID_TEST
, self
.OnTest
) 
 237         EVT_MENU(self
, self
.ID_REFRESH
, self
.OnRefresh
) 
 238         EVT_MENU(self
, self
.ID_AUTO_REFRESH
, self
.OnAutoRefresh
) 
 239         EVT_MENU(self
, self
.ID_TEST_HIDE
, self
.OnTestHide
) 
 241         EVT_MENU(self
, wxID_ABOUT
, self
.OnAbout
) 
 242         EVT_MENU(self
, self
.ID_README
, self
.OnReadme
) 
 245         EVT_UPDATE_UI(self
, wxID_CUT
, self
.OnUpdateUI
) 
 246         EVT_UPDATE_UI(self
, wxID_COPY
, self
.OnUpdateUI
) 
 247         EVT_UPDATE_UI(self
, wxID_PASTE
, self
.OnUpdateUI
) 
 248         EVT_UPDATE_UI(self
, self
.ID_LOCATE
, self
.OnUpdateUI
) 
 249         EVT_UPDATE_UI(self
, self
.ID_TOOL_LOCATE
, self
.OnUpdateUI
) 
 250         EVT_UPDATE_UI(self
, self
.ID_TOOL_PASTE
, self
.OnUpdateUI
) 
 251         EVT_UPDATE_UI(self
, wxID_UNDO
, self
.OnUpdateUI
) 
 252         EVT_UPDATE_UI(self
, wxID_REDO
, self
.OnUpdateUI
) 
 253         EVT_UPDATE_UI(self
, self
.ID_DELETE
, self
.OnUpdateUI
) 
 254         EVT_UPDATE_UI(self
, self
.ID_TEST
, self
.OnUpdateUI
) 
 255         EVT_UPDATE_UI(self
, self
.ID_REFRESH
, self
.OnUpdateUI
) 
 258         sizer 
= wxBoxSizer(wxVERTICAL
) 
 259         sizer
.Add(wxStaticLine(self
, -1), 0, wxEXPAND
) 
 260         # Horizontal sizer for toolbar and splitter 
 261         self
.toolsSizer 
= sizer1 
= wxBoxSizer() 
 262         splitter 
= wxSplitterWindow(self
, -1, style
=wxSP_3DSASH
) 
 263         self
.splitter 
= splitter
 
 264         splitter
.SetMinimumPaneSize(100) 
 267         g
.tree 
= tree 
= XML_Tree(splitter
, -1) 
 269         # Init pull-down menu data 
 271         g
.pullDownMenu 
= pullDownMenu 
= PullDownMenu(self
) 
 273         # Vertical toolbar for GUI buttons 
 274         g
.tools 
= tools 
= Tools(self
) 
 275         tools
.Show(conf
.showTools
) 
 276         if conf
.showTools
: sizer1
.Add(tools
, 0, wxEXPAND
) 
 278         tree
.RegisterKeyEvents() 
 280         # !!! frame styles are broken 
 281         # Miniframe for not embedded mode 
 282         miniFrame 
= wxFrame(self
, -1, 'Properties Panel', 
 283                             (conf
.panelX
, conf
.panelY
), 
 284                             (conf
.panelWidth
, conf
.panelHeight
)) 
 285         self
.miniFrame 
= miniFrame
 
 286         sizer2 
= wxBoxSizer() 
 287         miniFrame
.SetAutoLayout(True) 
 288         miniFrame
.SetSizer(sizer2
) 
 289         EVT_CLOSE(self
.miniFrame
, self
.OnCloseMiniFrame
) 
 290         # Create panel for parameters 
 293             panel 
= Panel(splitter
) 
 294             # Set plitter windows 
 295             splitter
.SplitVertically(tree
, panel
, conf
.sashPos
) 
 297             panel 
= Panel(miniFrame
) 
 298             sizer2
.Add(panel
, 1, wxEXPAND
) 
 300             splitter
.Initialize(tree
) 
 301         sizer1
.Add(splitter
, 1, wxEXPAND
) 
 302         sizer
.Add(sizer1
, 1, wxEXPAND
) 
 303         self
.SetAutoLayout(True) 
 307         self
.clipboard 
= None 
 311         EVT_IDLE(self
, self
.OnIdle
) 
 312         EVT_CLOSE(self
, self
.OnCloseWindow
) 
 313         EVT_KEY_DOWN(self
, tools
.OnKeyDown
) 
 314         EVT_KEY_UP(self
, tools
.OnKeyUp
) 
 316     def AppendRecent(self
, menu
): 
 317         # add recently used files to the menu 
 318         for id,name 
in conf
.recentfiles
.iteritems(): 
 320             EVT_MENU(self
,id,self
.OnRecentFile
) 
 323     def OnRecentFile(self
,evt
): 
 324         # open recently used file 
 325         if not self
.AskSave(): return 
 328             path
=conf
.recentfiles
[evt
.GetId()] 
 330                 self
.SetStatusText('Data loaded') 
 332                 self
.SetStatusText('Failed') 
 334             self
.SetStatusText('No such file') 
 337     def OnNew(self
, evt
): 
 338         if not self
.AskSave(): return 
 341     def OnOpen(self
, evt
): 
 342         if not self
.AskSave(): return 
 343         dlg 
= wxFileDialog(self
, 'Open', os
.path
.dirname(self
.dataFile
), 
 344                            '', '*.xrc', wxOPEN | wxCHANGE_DIR
) 
 345         if dlg
.ShowModal() == wxID_OK
: 
 347             self
.SetStatusText('Loading...') 
 352                     self
.SetStatusText('Data loaded') 
 354                     self
.SetStatusText('Failed') 
 355                 self
.SaveRecent(path
) 
 360     def OnSaveOrSaveAs(self
, evt
): 
 361         if evt
.GetId() == wxID_SAVEAS 
or not self
.dataFile
: 
 362             if self
.dataFile
: defaultName 
= '' 
 363             else: defaultName 
= 'UNTITLED.xrc' 
 364             dirname 
= os
.path
.dirname(self
.dataFile
) 
 365             dlg 
= wxFileDialog(self
, 'Save As', dirname
, defaultName
, '*.xrc', 
 366                                wxSAVE | wxOVERWRITE_PROMPT | wxCHANGE_DIR
) 
 367             if dlg
.ShowModal() == wxID_OK
: 
 375         self
.SetStatusText('Saving...') 
 380                 tmpFile
,tmpName 
= tempfile
.mkstemp(prefix
='xrced-') 
 382                 self
.Save(tmpName
) # save temporary file first 
 383                 shutil
.move(tmpName
, path
) 
 385                 self
.SetStatusText('Data saved') 
 386                 self
.SaveRecent(path
) 
 388                 self
.SetStatusText('Failed') 
 392     def SaveRecent(self
,path
): 
 393         # append to recently used files 
 394         if path 
not in conf
.recentfiles
.values(): 
 396             self
.recentMenu
.Append(newid
, path
) 
 397             EVT_MENU(self
, newid
, self
.OnRecentFile
) 
 398             conf
.recentfiles
[newid
] = path
 
 400     def OnExit(self
, evt
): 
 403     def OnUndo(self
, evt
): 
 404         # Extra check to not mess with idle updating 
 405         if undoMan
.CanUndo(): 
 408     def OnRedo(self
, evt
): 
 409         if undoMan
.CanRedo(): 
 412     def OnCopy(self
, evt
): 
 413         selected 
= tree
.selection
 
 414         if not selected
: return         # key pressed event 
 415         xxx 
= tree
.GetPyData(selected
) 
 416         self
.clipboard 
= xxx
.element
.cloneNode(True) 
 417         self
.SetStatusText('Copied') 
 419     def OnPaste(self
, evt
): 
 420         selected 
= tree
.selection
 
 421         if not selected
: return         # key pressed event 
 422         # For pasting with Ctrl pressed 
 424         if evt
.GetId() == pullDownMenu
.ID_PASTE_SIBLING
: appendChild 
= False 
 425         elif evt
.GetId() == self
.ID_TOOL_PASTE
: 
 426             if g
.tree
.ctrl
: appendChild 
= False 
 427             else: appendChild 
= not tree
.NeedInsert(selected
) 
 428         else: appendChild 
= not tree
.NeedInsert(selected
) 
 429         xxx 
= tree
.GetPyData(selected
) 
 431             # If has next item, insert, else append to parent 
 432             nextItem 
= tree
.GetNextSibling(selected
) 
 433             parentLeaf 
= tree
.GetItemParent(selected
) 
 434         # Expanded container (must have children) 
 435         elif tree
.IsExpanded(selected
) and tree
.GetChildrenCount(selected
, False): 
 436             # Insert as first child 
 437             nextItem 
= tree
.GetFirstChild(selected
)[0] 
 438             parentLeaf 
= selected
 
 440             # No children or unexpanded item - appendChild stays True 
 441             nextItem 
= wxTreeItemId()   # no next item 
 442             parentLeaf 
= selected
 
 443         parent 
= tree
.GetPyData(parentLeaf
).treeObject() 
 445         # Create a copy of clipboard element 
 446         elem 
= self
.clipboard
.cloneNode(True) 
 447         # Tempopary xxx object to test things 
 448         xxx 
= MakeXXXFromDOM(parent
, elem
) 
 450         # Check compatibility 
 454         if x
.__class
__ in [xxxDialog
, xxxFrame
, xxxMenuBar
, xxxWizard
]: 
 456             if parent
.__class
__ != xxxMainNode
: error 
= True 
 457         elif x
.__class
__ == xxxToolBar
: 
 458             # Toolbar can be top-level of child of panel or frame 
 459             if parent
.__class
__ not in [xxxMainNode
, xxxPanel
, xxxFrame
]: error 
= True 
 460         elif x
.__class
__ == xxxPanel 
and parent
.__class
__ == xxxMainNode
: 
 462         elif x
.__class
__ == xxxSpacer
: 
 463             if not parent
.isSizer
: error 
= True 
 464         elif x
.__class
__ == xxxSeparator
: 
 465             if not parent
.__class
__ in [xxxMenu
, xxxToolBar
]: error 
= True 
 466         elif x
.__class
__ == xxxTool
: 
 467             if parent
.__class
__ != xxxToolBar
: error 
= True 
 468         elif x
.__class
__ == xxxMenu
: 
 469             if not parent
.__class
__ in [xxxMainNode
, xxxMenuBar
, xxxMenu
]: error 
= True 
 470         elif x
.__class
__ == xxxMenuItem
: 
 471             if not parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error 
= True 
 472         elif x
.isSizer 
and parent
.__class
__ == xxxNotebook
: error 
= True 
 473         else:                           # normal controls can be almost anywhere 
 474             if parent
.__class
__ == xxxMainNode 
or \
 
 475                parent
.__class
__ in [xxxMenuBar
, xxxMenu
]: error 
= True 
 477             if parent
.__class
__ == xxxMainNode
: parentClass 
= 'root' 
 478             else: parentClass 
= parent
.className
 
 479             wxLogError('Incompatible parent/child: parent is %s, child is %s!' % 
 480                        (parentClass
, x
.className
)) 
 483         # Check parent and child relationships. 
 484         # If parent is sizer or notebook, child is of wrong class or 
 485         # parent is normal window, child is child container then detach child. 
 486         isChildContainer 
= isinstance(xxx
, xxxChildContainer
) 
 487         if isChildContainer 
and \
 
 488            ((parent
.isSizer 
and not isinstance(xxx
, xxxSizerItem
)) or \
 
 489             (isinstance(parent
, xxxNotebook
) and not isinstance(xxx
, xxxNotebookPage
)) or \
 
 490            not (parent
.isSizer 
or isinstance(parent
, xxxNotebook
))): 
 491             elem
.removeChild(xxx
.child
.element
) # detach child 
 492             elem
.unlink()           # delete child container 
 493             elem 
= xxx
.child
.element 
# replace 
 494             # This may help garbage collection 
 495             xxx
.child
.parent 
= None 
 496             isChildContainer 
= False 
 497         # Parent is sizer or notebook, child is not child container 
 498         if parent
.isSizer 
and not isChildContainer 
and not isinstance(xxx
, xxxSpacer
): 
 499             # Create sizer item element 
 500             sizerItemElem 
= MakeEmptyDOM('sizeritem') 
 501             sizerItemElem
.appendChild(elem
) 
 503         elif isinstance(parent
, xxxNotebook
) and not isChildContainer
: 
 504             pageElem 
= MakeEmptyDOM('notebookpage') 
 505             pageElem
.appendChild(elem
) 
 507         # Insert new node, register undo 
 508         newItem 
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
) 
 509         undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
)) 
 510         # Scroll to show new item (!!! redundant?) 
 511         tree
.EnsureVisible(newItem
) 
 512         tree
.SelectItem(newItem
) 
 513         if not tree
.IsVisible(newItem
): 
 514             tree
.ScrollTo(newItem
) 
 517         if g
.testWin 
and tree
.IsHighlatable(newItem
): 
 519                 tree
.needUpdate 
= True 
 520                 tree
.pendingHighLight 
= newItem
 
 522                 tree
.pendingHighLight 
= None 
 524         self
.SetStatusText('Pasted') 
 526     def OnCutDelete(self
, evt
): 
 527         selected 
= tree
.selection
 
 528         if not selected
: return         # key pressed event 
 530         if evt
.GetId() == wxID_CUT
: 
 532             status 
= 'Removed to clipboard' 
 534             self
.lastOp 
= 'DELETE' 
 538             # If deleting top-level item, delete testWin 
 539             if selected 
== g
.testWin
.item
: 
 543                 # Remove highlight, update testWin 
 544                 if g
.testWin
.highLight
: 
 545                     g
.testWin
.highLight
.Remove() 
 546                 tree
.needUpdate 
= True 
 549         index 
= tree
.ItemFullIndex(selected
) 
 550         parent 
= tree
.GetPyData(tree
.GetItemParent(selected
)).treeObject() 
 551         elem 
= tree
.RemoveLeaf(selected
) 
 552         undoMan
.RegisterUndo(UndoCutDelete(index
, parent
, elem
)) 
 553         if evt
.GetId() == wxID_CUT
: 
 554             if self
.clipboard
: self
.clipboard
.unlink() 
 555             self
.clipboard 
= elem
.cloneNode(True) 
 556         tree
.pendingHighLight 
= None 
 560         self
.SetStatusText(status
) 
 562     def OnSubclass(self
, evt
): 
 563         selected 
= tree
.selection
 
 564         xxx 
= tree
.GetPyData(selected
).treeObject() 
 566         subclass 
= xxx
.subclass
 
 567         dlg 
= wxTextEntryDialog(self
, 'Subclass:', defaultValue
=subclass
) 
 568         if dlg
.ShowModal() == wxID_OK
: 
 569             subclass 
= dlg
.GetValue() 
 571                 elem
.setAttribute('subclass', subclass
) 
 573             elif elem
.hasAttribute('subclass'): 
 574                 elem
.removeAttribute('subclass') 
 576             xxx
.subclass 
= elem
.getAttribute('subclass') 
 577             tree
.SetItemText(selected
, xxx
.treeName()) 
 578             panel
.pages
[0].box
.SetLabel(xxx
.panelName()) 
 581     def OnEmbedPanel(self
, evt
): 
 582         conf
.embedPanel 
= evt
.IsChecked() 
 584             # Remember last dimentions 
 585             conf
.panelX
, conf
.panelY 
= self
.miniFrame
.GetPosition() 
 586             conf
.panelWidth
, conf
.panelHeight 
= self
.miniFrame
.GetSize() 
 587             size 
= self
.GetSize() 
 588             pos 
= self
.GetPosition() 
 589             sizePanel 
= panel
.GetSize() 
 590             panel
.Reparent(self
.splitter
) 
 591             self
.miniFrame
.GetSizer().Remove(panel
) 
 594             self
.SetDimensions(pos
.x
, pos
.y
, size
.width 
+ sizePanel
.width
, size
.height
) 
 595             self
.splitter
.SplitVertically(tree
, panel
, conf
.sashPos
) 
 596             self
.miniFrame
.Show(False) 
 598             conf
.sashPos 
= self
.splitter
.GetSashPosition() 
 599             pos 
= self
.GetPosition() 
 600             size 
= self
.GetSize() 
 601             sizePanel 
= panel
.GetSize() 
 602             self
.splitter
.Unsplit(panel
) 
 603             sizer 
= self
.miniFrame
.GetSizer() 
 604             panel
.Reparent(self
.miniFrame
) 
 606             sizer
.Add(panel
, 1, wxEXPAND
) 
 607             self
.miniFrame
.Show(True) 
 608             self
.miniFrame
.SetDimensions(conf
.panelX
, conf
.panelY
, 
 609                                          conf
.panelWidth
, conf
.panelHeight
) 
 612             self
.SetDimensions(pos
.x
, pos
.y
, 
 613                                max(size
.width 
- sizePanel
.width
, self
.minWidth
), size
.height
) 
 615     def OnShowTools(self
, evt
): 
 616         conf
.showTools 
= evt
.IsChecked() 
 617         g
.tools
.Show(conf
.showTools
) 
 619             self
.toolsSizer
.Prepend(g
.tools
, 0, wxEXPAND
) 
 621             self
.toolsSizer
.Remove(g
.tools
) 
 622         self
.toolsSizer
.Layout() 
 624     def OnTest(self
, evt
): 
 625         if not tree
.selection
: return   # key pressed event 
 626         tree
.ShowTestWindow(tree
.selection
) 
 628     def OnTestHide(self
, evt
): 
 629         tree
.CloseTestWindow() 
 631     # Find object by relative position 
 632     def FindObject(self
, item
, obj
): 
 633         # We simply perform depth-first traversal, sinse it's too much 
 634         # hassle to deal with all sizer/window combinations 
 635         w 
= tree
.FindNodeObject(item
) 
 638         if tree
.ItemHasChildren(item
): 
 639             child 
= tree
.GetFirstChild(item
)[0] 
 641                 found 
= self
.FindObject(child
, obj
) 
 642                 if found
: return found
 
 643                 child 
= tree
.GetNextSibling(child
) 
 646     def OnTestWinLeftDown(self
, evt
): 
 647         pos 
= evt
.GetPosition() 
 648         self
.SetHandler(g
.testWin
) 
 649         g
.testWin
.Disconnect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
) 
 650         item 
= self
.FindObject(g
.testWin
.item
, evt
.GetEventObject()) 
 652             tree
.SelectItem(item
) 
 653         self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, False) 
 655             self
.SetStatusText('Selected %s' % tree
.GetItemText(item
)) 
 657             self
.SetStatusText('Locate failed!') 
 659     def SetHandler(self
, w
, h
=None): 
 662             w
.SetCursor(wxCROSS_CURSOR
) 
 665             w
.SetCursor(wxNullCursor
) 
 666         for ch 
in w
.GetChildren(): 
 667             self
.SetHandler(ch
, h
) 
 669     def OnLocate(self
, evt
): 
 671             if evt
.GetId() == self
.ID_LOCATE 
or \
 
 672                evt
.GetId() == self
.ID_TOOL_LOCATE 
and evt
.IsChecked(): 
 673                 self
.SetHandler(g
.testWin
, g
.testWin
) 
 674                 g
.testWin
.Connect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
, self
.OnTestWinLeftDown
) 
 675                 if evt
.GetId() == self
.ID_LOCATE
: 
 676                     self
.tb
.ToggleTool(self
.ID_TOOL_LOCATE
, True) 
 677             elif evt
.GetId() == self
.ID_TOOL_LOCATE 
and not evt
.IsChecked(): 
 678                 self
.SetHandler(g
.testWin
, None) 
 679                 g
.testWin
.Disconnect(wxID_ANY
, wxID_ANY
, wxEVT_LEFT_DOWN
) 
 680             self
.SetStatusText('Click somewhere in your test window now') 
 682     def OnRefresh(self
, evt
): 
 683         # If modified, apply first 
 684         selection 
= tree
.selection
 
 686             xxx 
= tree
.GetPyData(selection
) 
 687             if xxx 
and panel
.IsModified(): 
 688                 tree
.Apply(xxx
, selection
) 
 691             tree
.CreateTestWin(g
.testWin
.item
) 
 692         panel
.modified 
= False 
 693         tree
.needUpdate 
= False 
 695     def OnAutoRefresh(self
, evt
): 
 696         conf
.autoRefresh 
= evt
.IsChecked() 
 697         self
.menuBar
.Check(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
) 
 698         self
.tb
.ToggleTool(self
.ID_AUTO_REFRESH
, conf
.autoRefresh
) 
 700     def OnAbout(self
, evt
): 
 704 (c) Roman Rolinsky <rollrom@users.sourceforge.net> 
 705 Homepage: http://xrced.sourceforge.net\ 
 707         dlg 
= wxMessageDialog(self
, str, 'About XRCed', wxOK | wxCENTRE
) 
 711     def OnReadme(self
, evt
): 
 712         text 
= open(os
.path
.join(basePath
, 'README.txt'), 'r').read() 
 713         dlg 
= ScrolledMessageDialog(self
, text
, "XRCed README") 
 717     # Simple emulation of python command line 
 718     def OnDebugCMD(self
, evt
): 
 721                 exec raw_input('C:\> ') 
 726                 (etype
, value
, tb
) =sys
.exc_info() 
 727                 tblist 
=traceback
.extract_tb(tb
)[1:] 
 728                 msg 
=' '.join(traceback
.format_exception_only(etype
, value
) 
 729                         +traceback
.format_list(tblist
)) 
 732     def OnCreate(self
, evt
): 
 733         selected 
= tree
.selection
 
 734         if tree
.ctrl
: appendChild 
= False 
 735         else: appendChild 
= not tree
.NeedInsert(selected
) 
 736         xxx 
= tree
.GetPyData(selected
) 
 740                 # If has previous item, insert after it, else append to parent 
 742                 parentLeaf 
= tree
.GetItemParent(selected
) 
 744                 # If has next item, insert, else append to parent 
 745                 nextItem 
= tree
.GetNextSibling(selected
) 
 746                 parentLeaf 
= tree
.GetItemParent(selected
) 
 747         # Expanded container (must have children) 
 748         elif tree
.shift 
and tree
.IsExpanded(selected
) \
 
 749            and tree
.GetChildrenCount(selected
, False): 
 750             nextItem 
= tree
.GetFirstChild(selected
)[0] 
 751             parentLeaf 
= selected
 
 753             nextItem 
= wxTreeItemId() 
 754             parentLeaf 
= selected
 
 755         parent 
= tree
.GetPyData(parentLeaf
) 
 756         if parent
.hasChild
: parent 
= parent
.child
 
 759         className 
= pullDownMenu
.createMap
[evt
.GetId()] 
 760         xxx 
= MakeEmptyXXX(parent
, className
) 
 762         # Set default name for top-level windows 
 763         if parent
.__class
__ == xxxMainNode
: 
 764             cl 
= xxx
.treeObject().__class
__ 
 765             frame
.maxIDs
[cl
] += 1 
 766             xxx
.treeObject().name 
= '%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]) 
 767             xxx
.treeObject().element
.setAttribute('name', xxx
.treeObject().name
) 
 769         # Insert new node, register undo 
 771         newItem 
= tree
.InsertNode(parentLeaf
, parent
, elem
, nextItem
) 
 772         undoMan
.RegisterUndo(UndoPasteCreate(parentLeaf
, parent
, newItem
, selected
)) 
 773         tree
.EnsureVisible(newItem
) 
 774         tree
.SelectItem(newItem
) 
 775         if not tree
.IsVisible(newItem
): 
 776             tree
.ScrollTo(newItem
) 
 779         if g
.testWin 
and tree
.IsHighlatable(newItem
): 
 781                 tree
.needUpdate 
= True 
 782                 tree
.pendingHighLight 
= newItem
 
 784                 tree
.pendingHighLight 
= None 
 788     # Replace one object with another 
 789     def OnReplace(self
, evt
): 
 790         selected 
= tree
.selection
 
 791         xxx 
= tree
.GetPyData(selected
).treeObject() 
 793         parent 
= elem
.parentNode
 
 794         parentXXX 
= xxx
.parent
 
 796         className 
= pullDownMenu
.createMap
[evt
.GetId() - 1000] 
 797         # Create temporary empty node (with default values) 
 798         dummy 
= MakeEmptyDOM(className
) 
 799         xxxClass 
= xxxDict
[className
] 
 800         # Remove non-compatible children 
 801         if tree
.ItemHasChildren(selected
) and not xxxClass
.hasChildren
: 
 802             tree
.DeleteChildren(selected
) 
 803         nodes 
= elem
.childNodes
[:] 
 806             if node
.nodeType 
!= minidom
.Node
.ELEMENT_NODE
: continue 
 810                 if not xxxClass
.hasChildren
: 
 812             elif tag 
not in xxxClass
.allParams 
and \
 
 813                      (not xxxClass
.hasStyle 
or tag 
not in xxxClass
.styles
): 
 818                 elem
.removeChild(node
) 
 821         # Copy parameters present in dummy but not in elem 
 822         for node 
in dummy
.childNodes
: 
 825                 elem
.appendChild(node
.cloneNode(True)) 
 828         elem
.setAttribute('class', className
)         
 829         if elem
.hasAttribute('subclass'): 
 830             elem
.removeAttribute('subclass') # clear subclassing 
 831         # Re-create xxx element 
 832         xxx 
= MakeXXXFromDOM(parentXXX
, elem
) 
 833         # Update parent in child objects 
 834         if tree
.ItemHasChildren(selected
): 
 835             i
, cookie 
= tree
.GetFirstChild(selected
) 
 837                 x 
= tree
.GetPyData(i
) 
 839                 if x
.hasChild
: x
.child
.parent 
= xxx
 
 840                 i
, cookie 
= tree
.GetNextChild(selected
, cookie
) 
 843         if tree
.GetPyData(selected
).hasChild
: # child container 
 844             container 
= tree
.GetPyData(selected
) 
 845             container
.child 
= xxx
 
 846             container
.hasChildren 
= xxx
.hasChildren
 
 847             container
.isSizer 
= xxx
.isSizer
 
 849             tree
.SetPyData(selected
, xxx
) 
 850         tree
.SetItemText(selected
, xxx
.treeName()) 
 851         tree
.SetItemImage(selected
, xxx
.treeImage()) 
 853         # Set default name for top-level windows 
 854         if parent
.__class
__ == xxxMainNode
: 
 855             cl 
= xxx
.treeObject().__class
__ 
 856             frame
.maxIDs
[cl
] += 1 
 857             xxx
.treeObject().name 
= '%s%d' % (defaultIDs
[cl
], frame
.maxIDs
[cl
]) 
 858             xxx
.treeObject().element
.setAttribute('name', xxx
.treeObject().name
) 
 865         #undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) 
 867         if g
.testWin 
and tree
.IsHighlatable(selected
): 
 869                 tree
.needUpdate 
= True 
 870                 tree
.pendingHighLight 
= selected
 
 872                 tree
.pendingHighLight 
= None 
 876     # Expand/collapse subtree 
 877     def OnExpand(self
, evt
): 
 878         if tree
.selection
: tree
.ExpandAll(tree
.selection
) 
 879         else: tree
.ExpandAll(tree
.root
) 
 880     def OnCollapse(self
, evt
): 
 881         if tree
.selection
: tree
.CollapseAll(tree
.selection
) 
 882         else: tree
.CollapseAll(tree
.root
) 
 884     def OnPullDownHighlight(self
, evt
): 
 885         menuId 
= evt
.GetMenuId() 
 887             menu 
= evt
.GetEventObject() 
 888             help = menu
.GetHelpString(menuId
) 
 889             self
.SetStatusText(help) 
 891             self
.SetStatusText('') 
 893     def OnUpdateUI(self
, evt
): 
 894         if evt
.GetId() in [wxID_CUT
, wxID_COPY
, self
.ID_DELETE
]: 
 895             evt
.Enable(tree
.selection 
is not None and tree
.selection 
!= tree
.root
) 
 896         elif evt
.GetId() in [wxID_PASTE
, self
.ID_TOOL_PASTE
]: 
 897             evt
.Enable((self
.clipboard 
and tree
.selection
) != None) 
 898         elif evt
.GetId() == self
.ID_TEST
: 
 899             evt
.Enable(tree
.selection 
is not None and tree
.selection 
!= tree
.root
) 
 900         elif evt
.GetId() in [self
.ID_LOCATE
, self
.ID_TOOL_LOCATE
]: 
 901             evt
.Enable(g
.testWin 
is not None) 
 902         elif evt
.GetId() == wxID_UNDO
:  evt
.Enable(undoMan
.CanUndo()) 
 903         elif evt
.GetId() == wxID_REDO
:  evt
.Enable(undoMan
.CanRedo()) 
 905     def OnIdle(self
, evt
): 
 906         if self
.inIdle
: return          # Recursive call protection 
 911                     self
.SetStatusText('Refreshing test window...') 
 913                     tree
.CreateTestWin(g
.testWin
.item
) 
 915                     self
.SetStatusText('') 
 916                 tree
.needUpdate 
= False 
 917         elif tree
.pendingHighLight
: 
 918             tree
.HighLight(tree
.pendingHighLight
) 
 923     # We don't let close panel window 
 924     def OnCloseMiniFrame(self
, evt
): 
 927     def OnCloseWindow(self
, evt
): 
 928         if not self
.AskSave(): return 
 929         if g
.testWin
: g
.testWin
.Destroy() 
 930         if not panel
.GetPageCount() == 2: 
 931             panel
.page2
.Destroy() 
 933             # If we don't do this, page does not get destroyed (a bug?) 
 935         if not self
.IsIconized(): 
 936             conf
.x
, conf
.y 
= self
.GetPosition() 
 937             conf
.width
, conf
.height 
= self
.GetSize() 
 939                 conf
.sashPos 
= self
.splitter
.GetSashPosition() 
 941                 conf
.panelX
, conf
.panelY 
= self
.miniFrame
.GetPosition() 
 942                 conf
.panelWidth
, conf
.panelHeight 
= self
.miniFrame
.GetSize() 
 948             self
.clipboard
.unlink() 
 949             self
.clipboard 
= None 
 951         self
.modified 
= False 
 957         self
.SetTitle(progname
) 
 958         # Numbers for new controls 
 960         self
.maxIDs
[xxxPanel
] = self
.maxIDs
[xxxDialog
] = self
.maxIDs
[xxxFrame
] = \
 
 961         self
.maxIDs
[xxxMenuBar
] = self
.maxIDs
[xxxMenu
] = self
.maxIDs
[xxxToolBar
] = \
 
 962         self
.maxIDs
[xxxWizard
] = 0 
 964     def Open(self
, path
): 
 965         if not os
.path
.exists(path
): 
 966             wxLogError('File does not exists: %s' % path
) 
 968         # Try to read the file 
 972             dom 
= minidom
.parse(f
) 
 974             # Set encoding global variable and default encoding 
 976                 g
.currentEncoding 
= dom
.encoding
 
 977                 wx
.SetDefaultPyEncoding(g
.currentEncoding
.encode()) 
 979                 g
.currentEncoding 
= '' 
 981             self
.dataFile 
= path 
= os
.path
.abspath(path
) 
 982             dir = os
.path
.dirname(path
) 
 983             if dir: os
.chdir(dir) 
 985             self
.SetTitle(progname 
+ ': ' + os
.path
.basename(path
)) 
 987             # Nice exception printing 
 989             wxLogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1]) 
 990             wxLogError('Error reading file: %s' % path
) 
 995     def Indent(self
, node
, indent 
= 0): 
 996         # Copy child list because it will change soon 
 997         children 
= node
.childNodes
[:] 
 998         # Main node doesn't need to be indented 
1000             text 
= self
.domCopy
.createTextNode('\n' + ' ' * indent
) 
1001             node
.parentNode
.insertBefore(text
, node
) 
1003             # Append newline after last child, except for text nodes 
1004             if children
[-1].nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
1005                 text 
= self
.domCopy
.createTextNode('\n' + ' ' * indent
) 
1006                 node
.appendChild(text
) 
1007             # Indent children which are elements 
1009                 if n
.nodeType 
== minidom
.Node
.ELEMENT_NODE
: 
1010                     self
.Indent(n
, indent 
+ 2) 
1012     def Save(self
, path
): 
1016             if tree
.selection 
and panel
.IsModified(): 
1017                 self
.OnRefresh(wxCommandEvent()) 
1018             if g
.currentEncoding
: 
1019                 f 
= codecs
.open(path
, 'wt', g
.currentEncoding
) 
1021                 f 
= codecs
.open(path
, 'wt') 
1022             # Make temporary copy for formatting it 
1023             # !!! We can't clone dom node, it works only once 
1024             #self.domCopy = tree.dom.cloneNode(True) 
1025             self
.domCopy 
= MyDocument() 
1026             mainNode 
= self
.domCopy
.appendChild(tree
.mainNode
.cloneNode(True)) 
1027             self
.Indent(mainNode
) 
1028             self
.domCopy
.writexml(f
, encoding 
= g
.currentEncoding
) 
1030             self
.domCopy
.unlink() 
1032             self
.modified 
= False 
1033             panel
.SetModified(False) 
1035             inf 
= sys
.exc_info() 
1036             wxLogError(traceback
.format_exception(inf
[0], inf
[1], None)[-1]) 
1037             wxLogError('Error writing file: %s' % path
) 
1041         if not (self
.modified 
or panel
.IsModified()): return True 
1042         flags 
= wxICON_EXCLAMATION | wxYES_NO | wxCANCEL | wxCENTRE
 
1043         dlg 
= wxMessageDialog( self
, 'File is modified. Save before exit?', 
1044                                'Save before too late?', flags 
) 
1045         say 
= dlg
.ShowModal() 
1048             self
.OnSaveOrSaveAs(wxCommandEvent(wxID_SAVE
)) 
1049             # If save was successful, modified flag is unset 
1050             if not self
.modified
: return True 
1051         elif say 
== wxID_NO
: 
1052             self
.modified 
= False 
1053             panel
.SetModified(False) 
1060 ################################################################################ 
1063     print >> sys
.stderr
, 'usage: xrced [-dhiv] [file]' 
1068         # Process comand-line 
1071             opts
, args 
= getopt
.getopt(sys
.argv
[1:], 'dhiv') 
1079                     print 'XRCed version', version
 
1082         except getopt
.GetoptError
: 
1083             if wxPlatform 
!= '__WXMAC__': # macs have some extra parameters 
1084                 print >> sys
.stderr
, 'Unknown option' 
1088         self
.SetAppName('xrced') 
1091         conf 
= g
.conf 
= wxConfig(style 
= wxCONFIG_USE_LOCAL_FILE
) 
1092         conf
.autoRefresh 
= conf
.ReadInt('autorefresh', True) 
1093         pos 
= conf
.ReadInt('x', -1), conf
.ReadInt('y', -1) 
1094         size 
= conf
.ReadInt('width', 800), conf
.ReadInt('height', 600) 
1095         conf
.embedPanel 
= conf
.ReadInt('embedPanel', True) 
1096         conf
.showTools 
= conf
.ReadInt('showTools', True) 
1097         conf
.sashPos 
= conf
.ReadInt('sashPos', 200) 
1098         # read recently used files 
1099         recentfiles
=conf
.Read('recentFiles','') 
1102             for fil 
in recentfiles
.split('|'): 
1103                 conf
.recentfiles
[wxNewId()]=fil
 
1104         if not conf
.embedPanel
: 
1105             conf
.panelX 
= conf
.ReadInt('panelX', -1) 
1106             conf
.panelY 
= conf
.ReadInt('panelY', -1) 
1108             conf
.panelX 
= conf
.panelY 
= -1 
1109         conf
.panelWidth 
= conf
.ReadInt('panelWidth', 200) 
1110         conf
.panelHeight 
= conf
.ReadInt('panelHeight', 200) 
1111         conf
.panic 
= not conf
.HasEntry('nopanic') 
1113         wxFileSystem_AddHandler(wxMemoryFSHandler()) 
1114         wxInitAllImageHandlers() 
1116         frame 
= Frame(pos
, size
) 
1119         # Load file after showing 
1122             frame
.open = frame
.Open(args
[0]) 
1129         wc 
= wxConfigBase_Get() 
1130         wc
.WriteInt('autorefresh', conf
.autoRefresh
) 
1131         wc
.WriteInt('x', conf
.x
) 
1132         wc
.WriteInt('y', conf
.y
) 
1133         wc
.WriteInt('width', conf
.width
) 
1134         wc
.WriteInt('height', conf
.height
) 
1135         wc
.WriteInt('embedPanel', conf
.embedPanel
) 
1136         wc
.WriteInt('showTools', conf
.showTools
) 
1137         if not conf
.embedPanel
: 
1138             wc
.WriteInt('panelX', conf
.panelX
) 
1139             wc
.WriteInt('panelY', conf
.panelY
) 
1140         wc
.WriteInt('sashPos', conf
.sashPos
) 
1141         wc
.WriteInt('panelWidth', conf
.panelWidth
) 
1142         wc
.WriteInt('panelHeight', conf
.panelHeight
) 
1143         wc
.WriteInt('nopanic', True) 
1144         wc
.Write('recentFiles', '|'.join(conf
.recentfiles
.values()[-5:])) 
1148     app 
= App(0, useBestVisual
=False) 
1149     #app.SetAssertMode(wxPYAPP_ASSERT_LOG) 
1155 if __name__ 
== '__main__':