X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a023b456b4daf8768225c64afd63782b674ea0b1..b86ad1d632e9d7c677177631d3a5484cb3195f0e:/wxPython/wx/tools/XRCed/xrced.py diff --git a/wxPython/wx/tools/XRCed/xrced.py b/wxPython/wx/tools/XRCed/xrced.py index 36bd890746..26d6bc6f30 100644 --- a/wxPython/wx/tools/XRCed/xrced.py +++ b/wxPython/wx/tools/XRCed/xrced.py @@ -105,7 +105,7 @@ class Frame(wx.Frame): self.inIdle = False # Load our own resources - self.res = xrc.XmlResource('') + self.res = xrc.EmptyXmlResource() # !!! Blocking of assert failure occurring in older unicode builds try: quietlog = wx.LogNull() @@ -120,9 +120,13 @@ class Frame(wx.Frame): menu.Append(wx.ID_NEW, '&New\tCtrl-N', 'New file') menu.AppendSeparator() menu.Append(wx.ID_OPEN, '&Open...\tCtrl-O', 'Open XRC file') + self.recentMenu = wx.Menu() - self.AppendRecent(self.recentMenu) - menu.AppendMenu(-1, 'Open Recent', self.recentMenu, 'Open a recent file') + g.fileHistory.UseMenu(self.recentMenu) + g.fileHistory.AddFilesToMenu() + self.Bind(wx.EVT_MENU, self.OnRecentFile, id=wx.ID_FILE1, id2=wx.ID_FILE9) + menu.AppendMenu(-1, 'Open &Recent', self.recentMenu, 'Open a recent file') + menu.AppendSeparator() menu.Append(wx.ID_SAVE, '&Save\tCtrl-S', 'Save XRC file') menu.Append(wx.ID_SAVEAS, 'Save &As...', 'Save XRC file under different name') @@ -130,6 +134,9 @@ class Frame(wx.Frame): menu.Append(self.ID_GENERATE_PYTHON, '&Generate Python...', 'Generate a Python module that uses this XRC') menu.AppendSeparator() + self.ID_PREFS = wx.NewId() + menu.Append(self.ID_PREFS, 'Preferences...', 'Change XRCed settings') + menu.AppendSeparator() menu.Append(wx.ID_EXIT, '&Quit\tCtrl-Q', 'Exit application') menuBar.Append(menu, '&File') @@ -164,7 +171,7 @@ class Frame(wx.Frame): self.ID_REFRESH = wx.NewId() menu.Append(self.ID_REFRESH, '&Refresh\tCtrl-R', 'Refresh test window') self.ID_AUTO_REFRESH = wx.NewId() - menu.Append(self.ID_AUTO_REFRESH, '&Auto-refresh\tCtrl-A', + menu.Append(self.ID_AUTO_REFRESH, '&Auto-refresh\tAlt-A', 'Toggle auto-refresh mode', True) menu.Check(self.ID_AUTO_REFRESH, conf.autoRefresh) self.ID_TEST_HIDE = wx.NewId() @@ -250,6 +257,7 @@ class Frame(wx.Frame): wx.EVT_MENU(self, wx.ID_SAVE, self.OnSaveOrSaveAs) wx.EVT_MENU(self, wx.ID_SAVEAS, self.OnSaveOrSaveAs) wx.EVT_MENU(self, self.ID_GENERATE_PYTHON, self.OnGeneratePython) + wx.EVT_MENU(self, self.ID_PREFS, self.OnPrefs) wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit) # Edit wx.EVT_MENU(self, wx.ID_UNDO, self.OnUndo) @@ -293,7 +301,7 @@ class Frame(wx.Frame): # Build interface sizer = wx.BoxSizer(wx.VERTICAL) - sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND) + #sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND) # Horizontal sizer for toolbar and splitter self.toolsSizer = sizer1 = wx.BoxSizer() splitter = wx.SplitterWindow(self, -1, style=wx.SP_3DSASH) @@ -346,25 +354,22 @@ class Frame(wx.Frame): wx.EVT_KEY_UP(self, tools.OnKeyUp) wx.EVT_ICONIZE(self, self.OnIconize) - def AppendRecent(self, menu): - # add recently used files to the menu - for id,name in conf.recentfiles.iteritems(): - menu.Append(id,name) - wx.EVT_MENU(self,id,self.OnRecentFile) - return - def OnRecentFile(self,evt): # open recently used file if not self.AskSave(): return wx.BeginBusyCursor() - try: - path=conf.recentfiles[evt.GetId()] - if self.Open(path): - self.SetStatusText('Data loaded') - else: - self.SetStatusText('Failed') - except KeyError: - self.SetStatusText('No such file') + + # get the pathname based on the menu ID + fileNum = evt.GetId() - wx.ID_FILE1 + path = g.fileHistory.GetHistoryFile(fileNum) + + if self.Open(path): + self.SetStatusText('Data loaded') + # add it back to the history so it will be moved up the list + self.SaveRecent(path) + else: + self.SetStatusText('Failed') + wx.EndBusyCursor() def OnNew(self, evt): @@ -382,9 +387,9 @@ class Frame(wx.Frame): try: if self.Open(path): self.SetStatusText('Data loaded') + self.SaveRecent(path) else: self.SetStatusText('Failed') - self.SaveRecent(path) finally: wx.EndBusyCursor() dlg.Destroy() @@ -429,6 +434,7 @@ class Frame(wx.Frame): self.Save(tmpName) # save temporary file first shutil.move(tmpName, path) self.dataFile = path + self.SetModified(False) if conf.localconf.ReadBool("autogenerate", False): pypath = conf.localconf.Read("filename") embed = conf.localconf.ReadBool("embedResource", False) @@ -444,11 +450,7 @@ class Frame(wx.Frame): def SaveRecent(self,path): # append to recently used files - if path not in conf.recentfiles.values(): - newid = wx.NewId() - self.recentMenu.Append(newid, path) - wx.EVT_MENU(self, newid, self.OnRecentFile) - conf.recentfiles[newid] = path + g.fileHistory.AddFileToHistory(path) def GeneratePython(self, dataFile, pypath, embed, genGettext): try: @@ -470,7 +472,18 @@ class Frame(wx.Frame): dlg = PythonOptions(self, conf.localconf, self.dataFile) dlg.ShowModal() dlg.Destroy() - + + def OnPrefs(self, evt): + dlg = PrefsDialog(self) + if dlg.ShowModal() == wx.ID_OK: + # Fetch new preferences + for id,cdp in dlg.checkControls.items(): + c,d,p = cdp + if dlg.FindWindowById(id).IsChecked(): + d[p] = str(c.GetValue()) + elif p in d: del d[p] + g.conf.allowExec = ('ask', 'yes', 'no')[dlg.radio_allow_exec.GetSelection()] + dlg.Destroy() def OnExit(self, evt): self.Close() @@ -673,12 +686,18 @@ class Frame(wx.Frame): index = tree.ItemIndex(selected) if index == 0: return # No previous sibling found + # Remove highlight, update testWin + if g.testWin and g.testWin.highLight: + g.testWin.highLight.Remove() + tree.needUpdate = True + # Undo info self.lastOp = 'MOVEUP' status = 'Moved before previous sibling' # Prepare undo data panel.Apply() + tree.UnselectAll() parent = tree.GetItemParent(selected) elem = tree.RemoveLeaf(selected) @@ -703,12 +722,18 @@ class Frame(wx.Frame): next = tree.GetNextSibling(selected) if not next: return + # Remove highlight, update testWin + if g.testWin and g.testWin.highLight: + g.testWin.highLight.Remove() + tree.needUpdate = True + # Undo info self.lastOp = 'MOVEDOWN' status = 'Moved after next sibling' # Prepare undo data panel.Apply() + tree.UnselectAll() parent = tree.GetItemParent(selected) elem = tree.RemoveLeaf(selected) @@ -737,6 +762,11 @@ class Frame(wx.Frame): # Check compatibility if not self.ItemsAreCompatible(tree.GetPyData(pparent).treeObject(), tree.GetPyData(selected).treeObject()): return + # Remove highlight, update testWin + if g.testWin and g.testWin.highLight: + g.testWin.highLight.Remove() + tree.needUpdate = True + # Undo info self.lastOp = 'MOVELEFT' status = 'Made next sibling of parent' @@ -776,6 +806,7 @@ class Frame(wx.Frame): selected = tree.InsertNode(pparent, tree.GetPyData(pparent).treeObject(), elem, nextItem) newIndex = tree.ItemIndex(selected) + tree.oldItem = None tree.SelectItem(selected) undoMan.RegisterUndo(UndoMove(oldParent, oldIndex, pparent, newIndex)) @@ -798,6 +829,11 @@ class Frame(wx.Frame): # Check compatibility if not self.ItemsAreCompatible(parent, tree.GetPyData(selected).treeObject()): return + # Remove highlight, update testWin + if g.testWin and g.testWin.highLight: + g.testWin.highLight.Remove() + tree.needUpdate = True + # Undo info self.lastOp = 'MOVERIGHT' status = 'Made last child of previous sibling' @@ -834,10 +870,11 @@ class Frame(wx.Frame): selected = tree.InsertNode(newParent, tree.GetPyData(newParent).treeObject(), elem, wx.TreeItemId()) newIndex = tree.ItemIndex(selected) + tree.oldItem = None tree.SelectItem(selected) undoMan.RegisterUndo(UndoMove(oldParent, oldIndex, newParent, newIndex)) - + self.modified = True self.SetStatusText(status) @@ -975,8 +1012,9 @@ class Frame(wx.Frame): child = tree.GetNextSibling(child) return None + # Click event after locate activated def OnTestWinLeftDown(self, evt): - pos = evt.GetPosition() + # Restore normal event processing self.SetHandler(g.testWin) g.testWin.Disconnect(wx.ID_ANY, wx.ID_ANY, wx.wxEVT_LEFT_DOWN) item = self.FindObject(g.testWin.item, evt.GetEventObject()) @@ -1063,6 +1101,10 @@ Homepage: http://xrced.sourceforge.net\ print msg def OnCreate(self, evt): + # Ignore fake events generated while dragging + if g.tools.drag: + g.tools.drag = False + return selected = tree.selection if tree.ctrl: appendChild = False else: appendChild = not tree.NeedInsert(selected) @@ -1088,19 +1130,24 @@ Homepage: http://xrced.sourceforge.net\ parent = tree.GetPyData(parentLeaf) if parent.hasChild: parent = parent.child + self.CreateXXX(parent, parentLeaf, nextItem, evt.GetId()) + + # Actual method to create object and add to XML and wx trees + def CreateXXX(self, parent, parentLeaf, nextItem, id): + selected = tree.selection # Create object_ref? - if evt.GetId() == ID_NEW.REF: + if id == ID_NEW.REF: ref = wx.GetTextFromUser('Create reference to:', 'Create reference') if not ref: return xxx = MakeEmptyRefXXX(parent, ref) - elif evt.GetId() == ID_NEW.COMMENT: + elif id == ID_NEW.COMMENT: xxx = MakeEmptyCommentXXX(parent) else: # Create empty element - if evt.GetId() >= ID_NEW.CUSTOM: - className = pullDownMenu.customMap[evt.GetId()] + if id >= ID_NEW.CUSTOM: + className = pullDownMenu.customMap[id] else: - className = pullDownMenu.createMap[evt.GetId()] + className = pullDownMenu.createMap[id] xxx = MakeEmptyXXX(parent, className) # Insert new node, register undo @@ -1112,17 +1159,21 @@ Homepage: http://xrced.sourceforge.net\ xxx.setTreeName('%s%d' % (defaultIDs[cl], frame.maxIDs[cl])) # And for some other standard controls elif parent.__class__ == xxxStdDialogButtonSizer: - xxx.setTreeName(pullDownMenu.stdButtonIDs[evt.GetId()][0]) - # We can even set label + # ... we can even set automatically tree name + xxx.setTreeName(pullDownMenu.stdButtonIDs[id][0]) obj = xxx.treeObject() + # ... and label elem = g.tree.dom.createElement('label') - elem.appendChild(g.tree.dom.createTextNode(pullDownMenu.stdButtonIDs[evt.GetId()][1])) + elem.appendChild(g.tree.dom.createTextNode(pullDownMenu.stdButtonIDs[id][1])) obj.params['label'] = xxxParam(elem) xxx.treeObject().node.appendChild(elem) - - newItem = tree.InsertNode(parentLeaf, parent, xxx.node, nextItem) - else: # comment node - newItem = tree.InsertNode(parentLeaf, parent, xxx.node, nextItem) + # Else, set label if exists to class name + elif 'label' in xxx.treeObject().allParams: + label = className + if label[:2] == 'wx': label = label[2:] + xxx.treeObject().set('label', label.upper()) + # For comment nodes, simply add node + newItem = tree.InsertNode(parentLeaf, parent, xxx.node, nextItem) undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) tree.EnsureVisible(newItem) tree.SelectItem(newItem) @@ -1140,6 +1191,7 @@ Homepage: http://xrced.sourceforge.net\ if not xxx.isElement: tree.EditLabel(newItem) self.SetModified() + return xxx # Replace one object with another def OnReplace(self, evt): @@ -1300,17 +1352,17 @@ Homepage: http://xrced.sourceforge.net\ if tree.needUpdate: if conf.autoRefresh: if g.testWin: - self.SetStatusText('Refreshing test window...') + #self.SetStatusText('Refreshing test window...') # (re)create tree.CreateTestWin(g.testWin.item) - self.SetStatusText('') + #self.SetStatusText('') tree.needUpdate = False elif tree.pendingHighLight: try: tree.HighLight(tree.pendingHighLight) except: # Remove highlight if any problem - if g.testWin.highLight: + if g.testWin and g.testWin.highLight: g.testWin.highLight.Remove() tree.pendingHighLight = None raise @@ -1382,6 +1434,8 @@ Homepage: http://xrced.sourceforge.net\ g.pullDownMenu.custom = self.custom[:] # Remove modules imported from comment directives map(sys.modules.pop, [m for m in sys.modules if m not in self.modules]) + xxxParamComment.locals = {} # clear local namespace + xxxParamComment.allow = None # clear execution state def SetModified(self, state=True): self.modified = state @@ -1499,9 +1553,6 @@ Homepage: http://xrced.sourceforge.net\ return True return False - def SaveUndo(self): - pass # !!! - ################################################################################ class PythonOptions(wx.Dialog): @@ -1568,9 +1619,82 @@ class PythonOptions(wx.Dialog): self.EndModal(wx.ID_OK) - ################################################################################ +class PrefsDialog(wx.Dialog): + + def __init__(self, parent): + pre = wx.PreDialog() + g.frame.res.LoadOnDialog(pre, parent, "DIALOG_PREFS") + self.PostCreate(pre) + self.checkControls = {} # map of check IDs to (control,dict,param) + + ##xxx = sys.modules['xxx'] + import xxx + d = xxx.xxxSizerItem.defaults_panel + + self.check_proportion_panel = xrc.XRCCTRL(self, 'check_proportion_panel') + id = self.check_proportion_panel.GetId() + wx.EVT_CHECKBOX(self, id, self.OnCheck) + self.checkControls[id] = (xrc.XRCCTRL(self, 'spin_proportion_panel'), + d, 'option') + + self.check_flag_panel = xrc.XRCCTRL(self, 'check_flag_panel') + id = self.check_flag_panel.GetId() + wx.EVT_CHECKBOX(self, id, self.OnCheck) + self.checkControls[id] = (xrc.XRCCTRL(self, 'text_flag_panel'), + d, 'flag') + + d = xxx.xxxSizerItem.defaults_control + + self.check_proportion_panel = xrc.XRCCTRL(self, 'check_proportion_control') + id = self.check_proportion_panel.GetId() + wx.EVT_CHECKBOX(self, id, self.OnCheck) + self.checkControls[id] = (xrc.XRCCTRL(self, 'spin_proportion_control'), + d, 'option') + + self.check_flag_panel = xrc.XRCCTRL(self, 'check_flag_control') + id = self.check_flag_panel.GetId() + wx.EVT_CHECKBOX(self, id, self.OnCheck) + self.checkControls[id] = (xrc.XRCCTRL(self, 'text_flag_control'), + d, 'flag') + + for id,cdp in self.checkControls.items(): + c,d,p = cdp + try: + if isinstance(c, wx.SpinCtrl): + c.SetValue(int(d[p])) + else: + c.SetValue(d[p]) + self.FindWindowById(id).SetValue(True) + except KeyError: + c.Enable(False) + + self.radio_allow_exec = xrc.XRCCTRL(self, 'radio_allow_exec') + try: + radio = {'ask': 0, 'yes':1, 'no':2}[g.conf.allowExec] + except KeyError: + radio = 0 + self.radio_allow_exec.SetSelection(radio) + + def OnCheck(self, evt): + self.checkControls[evt.GetId()][0].Enable(evt.IsChecked()) + evt.Skip() + +################################################################################ + +# Parse string in form var1=val1[,var2=val2]* as dictionary +def ReadDictFromString(s): + d = {} + for vv in s.split(','): + var,val = vv.split(':') + d[var.strip()] = val + return d + +# Transform dictionary with strings into one string +def DictToString(d): + return ','.join(map(':'.join, d.items())) + def usage(): print >> sys.stderr, 'usage: xrced [-dhiv] [file]' @@ -1613,12 +1737,11 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion) conf.embedPanel = conf.ReadInt('embedPanel', True) conf.showTools = conf.ReadInt('showTools', True) conf.sashPos = conf.ReadInt('sashPos', 200) + # read recently used files - recentfiles=conf.Read('recentFiles','') - conf.recentfiles={} - if recentfiles: - for fil in recentfiles.split('|'): - conf.recentfiles[wx.NewId()]=fil + g.fileHistory = wx.FileHistory() + g.fileHistory.Load(conf) + if not conf.embedPanel: conf.panelX = conf.ReadInt('panelX', -1) conf.panelY = conf.ReadInt('panelY', -1) @@ -1627,6 +1750,18 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion) conf.panelWidth = conf.ReadInt('panelWidth', 200) conf.panelHeight = conf.ReadInt('panelHeight', 200) conf.panic = not conf.HasEntry('nopanic') + # Preferences + conf.allowExec = conf.Read('Prefs/allowExec', 'ask') + p = 'Prefs/sizeritem_defaults_panel' + import xxx + if conf.HasEntry(p): + ##sys.modules['xxx'].xxxSizerItem.defaults_panel = ReadDictFromString(conf.Read(p)) + xxx.xxxSizerItem.defaults_panel = ReadDictFromString(conf.Read(p)) + p = 'Prefs/sizeritem_defaults_control' + if conf.HasEntry(p): + ##sys.modules['xxx'].xxxSizerItem.defaults_control = ReadDictFromString(conf.Read(p)) + xxx.xxxSizerItem.defaults_control = ReadDictFromString(conf.Read(p)) + # Add handlers wx.FileSystem.AddHandler(wx.MemoryFSHandler()) # Create main frame @@ -1654,7 +1789,7 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion) # Store important data frame.handlers = getHandlers()[:] frame.custom = g.pullDownMenu.custom[:] - frame.modules = set(sys.modules.keys()) + frame.modules = sys.modules.copy() # Initialize frame.Clear() @@ -1683,8 +1818,19 @@ Please upgrade wxWidgets to %d.%d.%d or higher.''' % MinWxVersion) wc.WriteInt('sashPos', conf.sashPos) wc.WriteInt('panelWidth', conf.panelWidth) wc.WriteInt('panelHeight', conf.panelHeight) - wc.WriteInt('nopanic', True) - wc.Write('recentFiles', '|'.join(conf.recentfiles.values()[-5:])) + wc.WriteInt('nopanic', 1) + g.fileHistory.Save(wc) + # Preferences + wc.DeleteGroup('Prefs') + wc.Write('Prefs/allowExec', conf.allowExec) + import xxx + ##v = sys.modules['xxx'].xxxSizerItem.defaults_panel + v = xxx.xxxSizerItem.defaults_panel + if v: wc.Write('Prefs/sizeritem_defaults_panel', DictToString(v)) + ###v = sys.modules['xxx'].xxxSizerItem.defaults_control + v = xxx.xxxSizerItem.defaults_control + if v: wc.Write('Prefs/sizeritem_defaults_control', DictToString(v)) + wc.Flush() def main():