X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ec873c943d71f0d5f13e3398557071448cda6c23..a4027e74873007e3430af3bd77019bcab76f6c04:/wxPython/wx/tools/XRCed/tree.py diff --git a/wxPython/wx/tools/XRCed/tree.py b/wxPython/wx/tools/XRCed/tree.py deleted file mode 100644 index 363093ef49..0000000000 --- a/wxPython/wx/tools/XRCed/tree.py +++ /dev/null @@ -1,1389 +0,0 @@ -# Name: tree.py -# Purpose: XRC editor, XML_tree class -# Author: Roman Rolinsky -# Created: 02.12.2002 -# RCS-ID: $Id$ - -from xxx import * # xxx imports globals and params -import types -import traceback - -# Constant to define standart window name -STD_NAME = '_XRCED_T_W' - -# Icons -import images - -class MemoryFile: - def __init__(self, name): - self.name = name - self.buffer = '' - def write(self, data): - if g.currentEncoding: - encoding = g.currentEncoding - else: - encoding = wx.GetDefaultPyEncoding() - try: - self.buffer += data.encode(encoding) - except UnicodeEncodeError: - self.buffer += data.encode(encoding, 'xmlcharrefreplace') - - def close(self): - wx.MemoryFSHandler.AddFile(self.name, self.buffer) - -################################################################################ - -# Redefine writing to include encoding -class MyDocument(minidom.Document): - def __init__(self): - minidom.Document.__init__(self) - self.encoding = '' - def writexml(self, writer, indent="", addindent="", newl="", encoding=""): - if encoding: encdstr = 'encoding="%s"' % encoding - else: encdstr = '' - writer.write('\n' % encdstr) - for node in self.childNodes: - node.writexml(writer, indent, addindent, newl) - -################################################################################ - -# Ids for menu commands -class ID_NEW: - PANEL = wx.NewId() - DIALOG = wx.NewId() - FRAME = wx.NewId() - TOOL_BAR = wx.NewId() - TOOL = wx.NewId() - MENU_BAR = wx.NewId() - MENU = wx.NewId() - STATUS_BAR = wx.NewId() - - STATIC_TEXT = wx.NewId() - TEXT_CTRL = wx.NewId() - - BUTTON = wx.NewId() - BITMAP_BUTTON = wx.NewId() - RADIO_BUTTON = wx.NewId() - SPIN_BUTTON = wx.NewId() - TOGGLE_BUTTON = wx.NewId() - - STATIC_BOX = wx.NewId() - CHECK_BOX = wx.NewId() - RADIO_BOX = wx.NewId() - COMBO_BOX = wx.NewId() - LIST_BOX = wx.NewId() - - STATIC_LINE = wx.NewId() - STATIC_BITMAP = wx.NewId() - CHOICE = wx.NewId() - SLIDER = wx.NewId() - GAUGE = wx.NewId() - SCROLL_BAR = wx.NewId() - TREE_CTRL = wx.NewId() - LIST_CTRL = wx.NewId() - CHECK_LIST = wx.NewId() - NOTEBOOK = wx.NewId() - CHOICEBOOK = wx.NewId() - LISTBOOK = wx.NewId() - SPLITTER_WINDOW = wx.NewId() - GRID = wx.NewId() - SCROLLED_WINDOW = wx.NewId() - HTML_WINDOW = wx.NewId() - CALENDAR_CTRL = wx.NewId() - DATE_CTRL = wx.NewId() - FILE_PICKER_CTRL = wx.NewId() - GENERIC_DIR_CTRL = wx.NewId() - SPIN_CTRL = wx.NewId() - UNKNOWN = wx.NewId() - WIZARD = wx.NewId() - WIZARD_PAGE = wx.NewId() - WIZARD_PAGE_SIMPLE = wx.NewId() - BITMAP = wx.NewId() - ICON = wx.NewId() - STATUS_BAR = wx.NewId() - - BOX_SIZER = wx.NewId() - STATIC_BOX_SIZER = wx.NewId() - GRID_SIZER = wx.NewId() - FLEX_GRID_SIZER = wx.NewId() - GRID_BAG_SIZER = wx.NewId() - STD_DIALOG_BUTTON_SIZER = wx.NewId() - SPACER = wx.NewId() - - TOOL_BAR = wx.NewId() - TOOL = wx.NewId() - MENU = wx.NewId() - MENU_ITEM = wx.NewId() - SEPARATOR = wx.NewId() - - OK_BUTTON = wx.NewId() - YES_BUTTON = wx.NewId() - SAVE_BUTTON = wx.NewId() - APPLY_BUTTON = wx.NewId() - NO_BUTTON = wx.NewId() - CANCEL_BUTTON = wx.NewId() - HELP_BUTTON = wx.NewId() - CONTEXT_HELP_BUTTON = wx.NewId() - - REF = wx.NewId() - COMMENT = wx.NewId() - - CUSTOM = wx.NewId() - for i in range(99): wx.NewId() # reserve IDs for custom controls - - LAST = wx.NewId() - - - -class PullDownMenu: - ID_EXPAND = wx.NewId() - ID_COLLAPSE = wx.NewId() - ID_PASTE_SIBLING = wx.NewId() - ID_TOOL_PASTE = wx.NewId() - ID_SUBCLASS = wx.NewId() - - def __init__(self, parent): - self.ID_DELETE = parent.ID_DELETE - wx.EVT_MENU_RANGE(parent, ID_NEW.PANEL, ID_NEW.LAST, parent.OnCreate) - wx.EVT_MENU_RANGE(parent, 1000 + ID_NEW.PANEL, 1000 + ID_NEW.LAST, parent.OnReplace) - wx.EVT_MENU(parent, self.ID_COLLAPSE, parent.OnCollapse) - wx.EVT_MENU(parent, self.ID_EXPAND, parent.OnExpand) - wx.EVT_MENU(parent, self.ID_PASTE_SIBLING, parent.OnPaste) - wx.EVT_MENU(parent, self.ID_SUBCLASS, parent.OnSubclass) - # We connect to tree, but process in frame - wx.EVT_MENU_HIGHLIGHT_ALL(g.tree, parent.OnPullDownHighlight) - - # Mapping from IDs to element names - self.createMap = { - ID_NEW.PANEL: 'wxPanel', - ID_NEW.DIALOG: 'wxDialog', - ID_NEW.FRAME: 'wxFrame', - ID_NEW.WIZARD: 'wxWizard', - ID_NEW.WIZARD_PAGE: 'wxWizardPage', - ID_NEW.WIZARD_PAGE_SIMPLE: 'wxWizardPageSimple', - ID_NEW.TOOL_BAR: 'wxToolBar', - ID_NEW.TOOL: 'tool', - ID_NEW.STATUS_BAR: 'wxStatusBar', - ID_NEW.MENU_BAR: 'wxMenuBar', - ID_NEW.MENU: 'wxMenu', - ID_NEW.MENU_ITEM: 'wxMenuItem', - ID_NEW.BITMAP: 'wxBitmap', - ID_NEW.ICON: 'wxIcon', - ID_NEW.SEPARATOR: 'separator', - - ID_NEW.STATIC_TEXT: 'wxStaticText', - ID_NEW.TEXT_CTRL: 'wxTextCtrl', - - ID_NEW.BUTTON: 'wxButton', - ID_NEW.BITMAP_BUTTON: 'wxBitmapButton', - ID_NEW.RADIO_BUTTON: 'wxRadioButton', - ID_NEW.SPIN_BUTTON: 'wxSpinButton', - ID_NEW.TOGGLE_BUTTON: 'wxToggleButton', - - ID_NEW.STATIC_BOX: 'wxStaticBox', - ID_NEW.CHECK_BOX: 'wxCheckBox', - ID_NEW.RADIO_BOX: 'wxRadioBox', - ID_NEW.COMBO_BOX: 'wxComboBox', - ID_NEW.LIST_BOX: 'wxListBox', - ID_NEW.CHECK_LIST: 'wxCheckListBox', - - ID_NEW.STATIC_LINE: 'wxStaticLine', - ID_NEW.STATIC_BITMAP: 'wxStaticBitmap', - ID_NEW.CHOICE: 'wxChoice', - ID_NEW.SLIDER: 'wxSlider', - ID_NEW.GAUGE: 'wxGauge', - ID_NEW.SCROLL_BAR: 'wxScrollBar', - ID_NEW.TREE_CTRL: 'wxTreeCtrl', - ID_NEW.LIST_CTRL: 'wxListCtrl', - ID_NEW.NOTEBOOK: 'wxNotebook', - ID_NEW.CHOICEBOOK: 'wxChoicebook', - ID_NEW.LISTBOOK: 'wxListbook', - ID_NEW.SPLITTER_WINDOW: 'wxSplitterWindow', - ID_NEW.GRID: 'wxGrid', - ID_NEW.SCROLLED_WINDOW: 'wxScrolledWindow', - ID_NEW.HTML_WINDOW: 'wxHtmlWindow', - ID_NEW.CALENDAR_CTRL: 'wxCalendarCtrl', - ID_NEW.DATE_CTRL: 'wxDatePickerCtrl', - ID_NEW.FILE_PICKER_CTRL: 'wxFilePickerCtrl', - ID_NEW.GENERIC_DIR_CTRL: 'wxGenericDirCtrl', - ID_NEW.SPIN_CTRL: 'wxSpinCtrl', - - ID_NEW.BOX_SIZER: 'wxBoxSizer', - ID_NEW.STATIC_BOX_SIZER: 'wxStaticBoxSizer', - ID_NEW.GRID_SIZER: 'wxGridSizer', - ID_NEW.FLEX_GRID_SIZER: 'wxFlexGridSizer', - ID_NEW.GRID_BAG_SIZER: 'wxGridBagSizer', - ID_NEW.STD_DIALOG_BUTTON_SIZER: 'wxStdDialogButtonSizer', - ID_NEW.SPACER: 'spacer', - ID_NEW.UNKNOWN: 'unknown', - - ID_NEW.OK_BUTTON: 'wxButton', - ID_NEW.YES_BUTTON: 'wxButton', - ID_NEW.SAVE_BUTTON: 'wxButton', - ID_NEW.APPLY_BUTTON: 'wxButton', - ID_NEW.NO_BUTTON: 'wxButton', - ID_NEW.CANCEL_BUTTON: 'wxButton', - ID_NEW.HELP_BUTTON: 'wxButton', - ID_NEW.CONTEXT_HELP_BUTTON: 'wxButton', - } - self.topLevel = [ - (ID_NEW.PANEL, 'Panel', 'Create panel'), - (ID_NEW.DIALOG, 'Dialog', 'Create dialog'), - (ID_NEW.FRAME, 'Frame', 'Create frame'), - (ID_NEW.WIZARD, 'Wizard', 'Create wizard'), - None, - (ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar'), - (ID_NEW.MENU_BAR, 'MenuBar', 'Create menubar'), - (ID_NEW.MENU, 'Menu', 'Create menu'), - None, - (ID_NEW.BITMAP, 'Bitmap', 'Create bitmap'), - (ID_NEW.ICON, 'Icon', 'Create icon'), - ] - self.containers = [ - (ID_NEW.PANEL, 'Panel', 'Create panel'), - (ID_NEW.NOTEBOOK, 'Notebook', 'Create notebook control'), - (ID_NEW.CHOICEBOOK, 'Choicebook', 'Create choicebook control'), - (ID_NEW.LISTBOOK, 'Listbook', 'Create listbook control'), - (ID_NEW.SPLITTER_WINDOW, 'SplitterWindow', 'Create splitter window'), - (ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar'), - (ID_NEW.STATUS_BAR, 'StatusBar', 'Create status bar'), -# (ID_NEW.WIZARD_PAGE, 'WizardPage', 'Create wizard page'), - (ID_NEW.WIZARD_PAGE_SIMPLE, 'WizardPageSimple', 'Create simple wizard page'), - ] - self.sizers = [ - (ID_NEW.BOX_SIZER, 'BoxSizer', 'Create box sizer'), - (ID_NEW.STATIC_BOX_SIZER, 'StaticBoxSizer', - 'Create static box sizer'), - (ID_NEW.GRID_SIZER, 'GridSizer', 'Create grid sizer'), - (ID_NEW.FLEX_GRID_SIZER, 'FlexGridSizer', - 'Create flexgrid sizer'), - (ID_NEW.GRID_BAG_SIZER, 'GridBagSizer', - 'Create gridbag sizer'), -# (ID_NEW.STD_DIALOG_BUTTON_SIZER, 'StdDialogButtonSizer', -# 'Create standard button sizer'), - (ID_NEW.SPACER, 'Spacer', 'Create spacer'), - ] - self.controls = [ - ['control', 'Various controls', - (ID_NEW.STATIC_TEXT, 'Label', 'Create label'), - (ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'), - (ID_NEW.STATIC_LINE, 'Line', 'Create line'), - (ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'), - (ID_NEW.CHOICE, 'Choice', 'Create choice'), - (ID_NEW.SLIDER, 'Slider', 'Create slider'), - (ID_NEW.GAUGE, 'Gauge', 'Create gauge'), - (ID_NEW.SPIN_CTRL, 'SpinCtrl', 'Create spin'), - (ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), - (ID_NEW.TREE_CTRL, 'TreeCtrl', 'Create tree'), - (ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list'), -# (ID_NEW.GRID, 'Grid', 'Create grid'), - (ID_NEW.SCROLLED_WINDOW, 'ScrolledWindow', 'Create scrolled window'), - (ID_NEW.HTML_WINDOW, 'HtmlWindow', 'Create HTML window'), - (ID_NEW.CALENDAR_CTRL, 'CalendarCtrl', 'Create calendar control'), - (ID_NEW.DATE_CTRL, 'DatePickerCtrl', 'Create date picker control'), -# (ID_NEW.FILE_PICKER_CTRL, 'FilePickerCtrl', 'Create file picker control'), - (ID_NEW.GENERIC_DIR_CTRL, 'GenericDirCtrl', 'Create generic dir control'), - (ID_NEW.UNKNOWN, 'Unknown', 'Create custom control placeholder'), - ], - ['button', 'Buttons', - (ID_NEW.BUTTON, 'Button', 'Create button'), - (ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), - (ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'), - (ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'), - (ID_NEW.TOGGLE_BUTTON, 'ToggleButton', 'Create toggle button'), - ], - ['box', 'Boxes', - (ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'), - (ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'), - (ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'), - (ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'), - (ID_NEW.LIST_BOX, 'ListBox', 'Create list box'), - (ID_NEW.CHECK_LIST, 'CheckListBox', 'Create checklist box'), - ], - ['container', 'Containers', - (ID_NEW.PANEL, 'Panel', 'Create panel'), - (ID_NEW.NOTEBOOK, 'Notebook', 'Create notebook control'), - (ID_NEW.CHOICEBOOK, 'Choicebook', 'Create choicebook control'), - (ID_NEW.LISTBOOK, 'Listbook', 'Create listbook control'), - (ID_NEW.SPLITTER_WINDOW, 'SplitterWindow', 'Create splitter window'), - (ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar'), - (ID_NEW.STATUS_BAR, 'StatusBar', 'Create status bar'), - (ID_NEW.MENU_BAR, 'MenuBar', 'Create menubar'), -# (ID_NEW.WIZARD_PAGE, 'Wizard Page', 'Create wizard page'), - (ID_NEW.WIZARD_PAGE_SIMPLE, 'WizardPageSimple', 'Create simple wizard page'), - ], - ['sizer', 'Sizers', - (ID_NEW.BOX_SIZER, 'BoxSizer', 'Create box sizer'), - (ID_NEW.STATIC_BOX_SIZER, 'StaticBoxSizer', - 'Create static box sizer'), - (ID_NEW.GRID_SIZER, 'GridSizer', 'Create grid sizer'), - (ID_NEW.FLEX_GRID_SIZER, 'FlexGridSizer', - 'Create flexgrid sizer'), - (ID_NEW.GRID_BAG_SIZER, 'GridBagSizer', - 'Create gridbag sizer'), - (ID_NEW.SPACER, 'Spacer', 'Create spacer'), - (ID_NEW.STD_DIALOG_BUTTON_SIZER, 'StdDialogButtonSizer', - 'Create standard button sizer'), - ] - ] - self.menuControls = [ - (ID_NEW.MENU, 'Menu', 'Create menu'), - (ID_NEW.MENU_ITEM, 'MenuItem', 'Create menu item'), - (ID_NEW.SEPARATOR, 'Separator', 'Create separator'), - ] - self.toolBarControls = [ - (ID_NEW.TOOL, 'Tool', 'Create tool'), - (ID_NEW.SEPARATOR, 'Separator', 'Create separator'), - ['control', 'Various controls', - (ID_NEW.STATIC_TEXT, 'Label', 'Create label'), - (ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'), - (ID_NEW.STATIC_LINE, 'Line', 'Create line'), - (ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'), - (ID_NEW.CHOICE, 'Choice', 'Create choice'), - (ID_NEW.SLIDER, 'Slider', 'Create slider'), - (ID_NEW.GAUGE, 'Gauge', 'Create gauge'), - (ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'), - (ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list control'), - ], - ['button', 'Buttons', - (ID_NEW.BUTTON, 'Button', 'Create button'), - (ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'), - (ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'), - (ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'), - ], - ['box', 'Boxes', - (ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'), - (ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'), - (ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'), - (ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'), - (ID_NEW.LIST_BOX, 'ListBox', 'Create list box'), - (ID_NEW.CHECK_LIST, 'CheckListBox', 'Create checklist box'), - ], - ] - self.stdButtons = [ - (ID_NEW.OK_BUTTON, 'OK Button', 'Create standard button'), - (ID_NEW.YES_BUTTON, 'YES Button', 'Create standard button'), - (ID_NEW.SAVE_BUTTON, 'SAVE Button', 'Create standard button'), - (ID_NEW.APPLY_BUTTON, 'APPLY Button', 'Create standard button'), - (ID_NEW.NO_BUTTON, 'NO Button', 'Create standard button'), - (ID_NEW.CANCEL_BUTTON, 'CANCEL Button', 'Create standard button'), - (ID_NEW.HELP_BUTTON, 'HELP Button', 'Create standard button'), - (ID_NEW.CONTEXT_HELP_BUTTON, 'CONTEXT HELP Button', 'Create standard button'), - ] - self.stdButtonIDs = { - ID_NEW.OK_BUTTON: ('wxID_OK', '&Ok'), - ID_NEW.YES_BUTTON: ('wxID_YES', '&Yes'), - ID_NEW.SAVE_BUTTON: ('wxID_SAVE', '&Save'), - ID_NEW.APPLY_BUTTON: ('wxID_APPLY', '&Apply'), - ID_NEW.NO_BUTTON: ('wxID_NO', '&No'), - ID_NEW.CANCEL_BUTTON: ('wxID_CANCEL', '&Cancel'), - ID_NEW.HELP_BUTTON: ('wxID_HELP', '&Help'), - ID_NEW.CONTEXT_HELP_BUTTON: ('wxID_CONTEXT_HELP', '&Help'), - } - self.custom = ['custom', 'User-defined controls'] - self.customMap = {} - - def addCustom(self, klass): - n = len(self.custom)-2 - self.custom.append((ID_NEW.CUSTOM + n, klass)) - self.customMap[ID_NEW.CUSTOM + n] = klass - - -################################################################################ - -# Set menu to list items. -# Each menu command is a tuple (id, label, help) -# submenus are lists [id, label, help, submenu] -# and separators are any other type. Shift is for making -# alternative sets of IDs. (+1000). -def SetMenu(m, list, shift=False): - for l in list: - if type(l) == types.TupleType: - # Shift ID - if shift: l = (1000 + l[0],) + l[1:] - apply(m.Append, l) - elif type(l) == types.ListType: - subMenu = wx.Menu() - SetMenu(subMenu, l[2:], shift) - m.AppendMenu(wx.NewId(), l[0], subMenu, l[1]) - else: # separator - m.AppendSeparator() - -################################################################################ - -class HighLightBox: - colour = None - def __init__(self, pos, size): - colour = g.tree.COLOUR_HL - if size.width == -1: size.width = 0 - if size.height == -1: size.height = 0 - w = g.testWin.panel - l1 = wx.Window(w, -1, pos, wx.Size(size.width, 2)) - l1.SetBackgroundColour(colour) - l2 = wx.Window(w, -1, pos, wx.Size(2, size.height)) - l2.SetBackgroundColour(colour) - l3 = wx.Window(w, -1, wx.Point(pos.x + size.width - 2, pos.y), wx.Size(2, size.height)) - l3.SetBackgroundColour(colour) - l4 = wx.Window(w, -1, wx.Point(pos.x, pos.y + size.height - 2), wx.Size(size.width, 2)) - l4.SetBackgroundColour(colour) - self.lines = [l1, l2, l3, l4] - if wx.Platform == '__WXMSW__': - for l in self.lines: - l.Bind(wx.EVT_PAINT, self.OnPaint) - g.testWin.highLight = self - self.size = size - # Repainting is not always done for these windows on Windows - def OnPaint(self, evt): - w = evt.GetEventObject() - dc = wx.PaintDC(w) - w.ClearBackground() - dc.Destroy() - # Move highlight to a new position - def Replace(self, pos, size): - if size.width == -1: size.width = 0 - if size.height == -1: size.height = 0 - self.lines[0].SetDimensions(pos.x, pos.y, size.width, 2) - self.lines[1].SetDimensions(pos.x, pos.y, 2, size.height) - self.lines[2].SetDimensions(pos.x + size.width - 2, pos.y, 2, size.height) - self.lines[3].SetDimensions(pos.x, pos.y + size.height - 2, size.width, 2) - self.size = size - def Remove(self): - map(wx.Window.Destroy, self.lines) - g.testWin.highLight = None - def Refresh(self): - map(wx.Window.Refresh, self.lines) - -# Same for drop target -class HighLightDTBox(HighLightBox): - colour = None - def __init__(self, pos, size): - colour = g.tree.COLOUR_DT - if size.width == -1: size.width = 0 - if size.height == -1: size.height = 0 - w = g.testWin.panel - l1 = wx.Window(w, -1, pos, wx.Size(size.width, 2)) - l1.SetBackgroundColour(colour) - l2 = wx.Window(w, -1, pos, wx.Size(2, size.height)) - l2.SetBackgroundColour(colour) - l3 = wx.Window(w, -1, wx.Point(pos.x + size.width - 2, pos.y), wx.Size(2, size.height)) - l3.SetBackgroundColour(colour) - l4 = wx.Window(w, -1, wx.Point(pos.x, pos.y + size.height - 2), wx.Size(size.width, 2)) - l4.SetBackgroundColour(colour) - self.lines = [l1, l2, l3, l4] - self.item = None - self.size = size - # Remove it - def Remove(self): - map(wx.Window.Destroy, self.lines) - g.testWin.highLightDT = None - -def updateHL(hl, hlClass, pos, size): - # Need to recreate window if size did not change to force update - if hl and hl.size == size: - hl.Remove() - hl = None - if hl: - hl.Replace(pos, size) - else: - hl = hlClass(pos, size) - hl.Refresh() - return hl - -################################################################################ - -class XML_Tree(wx.TreeCtrl): - def __init__(self, parent, id): - # Item colour - self.COLOUR_COMMENT = wx.Colour(0, 0, 255) - self.COLOUR_REF = wx.Colour(0, 0, 128) - self.COLOUR_HIDDEN = wx.Colour(128, 128, 128) - self.COLOUR_HL = wx.Colour(255, 0, 0) - self.COLOUR_DT = wx.Colour(0, 64, 0) - - wx.TreeCtrl.__init__(self, parent, id, - style = wx.TR_HAS_BUTTONS | wx.TR_MULTIPLE | wx.TR_EDIT_LABELS) - self.SetBackgroundColour(wx.Colour(224, 248, 224)) - self.fontComment = wx.FFont(self.GetFont().GetPointSize(), - self.GetFont().GetFamily(), - wx.FONTFLAG_ITALIC) - # Register events - wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) - # One works on Linux, another on Windows - if wx.Platform == '__WXGTK__': # !!! MAC too? - wx.EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated) - else: - wx.EVT_LEFT_DCLICK(self, self.OnDClick) - wx.EVT_RIGHT_DOWN(self, self.OnRightDown) - wx.EVT_TREE_ITEM_EXPANDED(self, self.GetId(), self.OnItemExpandedCollapsed) - wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemExpandedCollapsed) - self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit) - self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndLabelEdit) - - self.selection = None - self.selectionChanging = False - self.needUpdate = False - self.pendingHighLight = None - self.ctrl = self.shift = False - self.dom = None - # Create image list - il = wx.ImageList(16, 16, True) - self.rootImage = il.Add(images.getTreeRootImage().Scale(16,16).ConvertToBitmap()) - xxxComment.image = il.Add(images.getTreeCommentImage().Scale(16,16).ConvertToBitmap()) - xxxObject.image = il.Add(images.getTreeDefaultImage().Scale(16,16).ConvertToBitmap()) - xxxPanel.image = il.Add(images.getTreePanelImage().Scale(16,16).ConvertToBitmap()) - xxxDialog.image = il.Add(images.getTreeDialogImage().Scale(16,16).ConvertToBitmap()) - xxxFrame.image = il.Add(images.getTreeFrameImage().Scale(16,16).ConvertToBitmap()) - xxxMenuBar.image = il.Add(images.getTreeMenuBarImage().Scale(16,16).ConvertToBitmap()) - xxxMenu.image = il.Add(images.getTreeMenuImage().Scale(16,16).ConvertToBitmap()) - xxxMenuItem.image = il.Add(images.getTreeMenuItemImage().Scale(16,16).ConvertToBitmap()) - xxxToolBar.image = il.Add(images.getTreeToolBarImage().Scale(16,16).ConvertToBitmap()) - xxxTool.image = il.Add(images.getTreeToolImage().Scale(16,16).ConvertToBitmap()) - xxxSeparator.image = il.Add(images.getTreeSeparatorImage().Scale(16,16).ConvertToBitmap()) - xxxSizer.imageH = il.Add(images.getTreeSizerHImage().Scale(16,16).ConvertToBitmap()) - xxxSizer.imageV = il.Add(images.getTreeSizerVImage().Scale(16,16).ConvertToBitmap()) - xxxStaticBoxSizer.imageH = il.Add(images.getTreeStaticBoxSizerHImage().Scale(16,16).ConvertToBitmap()) - xxxStaticBoxSizer.imageV = il.Add(images.getTreeStaticBoxSizerVImage().Scale(16,16).ConvertToBitmap()) - xxxGridSizer.image = il.Add(images.getTreeSizerGridImage().Scale(16,16).ConvertToBitmap()) - xxxFlexGridSizer.image = il.Add(images.getTreeSizerFlexGridImage().Scale(16,16).ConvertToBitmap()) - self.il = il - self.SetImageList(il) - - def RegisterKeyEvents(self): - wx.EVT_KEY_DOWN(self, g.tools.OnKeyDown) - wx.EVT_KEY_UP(self, g.tools.OnKeyUp) - wx.EVT_ENTER_WINDOW(self, g.tools.OnMouse) - wx.EVT_LEAVE_WINDOW(self, g.tools.OnMouse) - - def ExpandAll(self, item): - if self.ItemHasChildren(item): - self.Expand(item) - i, cookie = self.GetFirstChild(item) - children = [] - while i.IsOk(): - children.append(i) - i, cookie = self.GetNextChild(item, cookie) - for i in children: - self.ExpandAll(i) - def CollapseAll(self, item): - if self.ItemHasChildren(item): - i, cookie = self.GetFirstChild(item) - children = [] - while i.IsOk(): - children.append(i) - i, cookie = self.GetNextChild(item, cookie) - for i in children: - self.CollapseAll(i) - self.Collapse(item) - - # Clear tree - def Clear(self): - self.UnselectAll() - self.DeleteAllItems() - # Add minimal structure - if self.dom: self.dom.unlink() - self.dom = MyDocument() - self.dummyNode = self.dom.createComment('dummy node') - # Create main node - self.mainNode = self.dom.createElement('resource') - self.dom.appendChild(self.mainNode) - self.rootObj = xxxMainNode(self.dom) - self.root = self.AddRoot('XML tree', self.rootImage, - data=wx.TreeItemData(self.rootObj)) - self.itemColour = self.GetItemTextColour(self.root) - self.SetItemHasChildren(self.root) - self.testElem = self.dom.createElement('dummy') - self.mainNode.appendChild(self.testElem) - self.Expand(self.root) - - # Clear old data and set new - def SetData(self, dom): - self.UnselectAll() - self.DeleteAllItems() - # Add minimal structure - if self.dom: self.dom.unlink() - self.dom = dom - self.dummyNode = self.dom.createComment('dummy node') - # Find 'resource' child, add it's children - self.mainNode = dom.documentElement - self.rootObj = xxxMainNode(self.dom) - self.root = self.AddRoot('XML tree', self.rootImage, - data=wx.TreeItemData(self.rootObj)) - self.SetItemHasChildren(self.root) - nodes = self.mainNode.childNodes[:] - for node in nodes: - if IsObject(node): - self.AddNode(self.root, None, node) - else: - self.mainNode.removeChild(node) - node.unlink() - if self.mainNode.firstChild: - self.testElem = self.dom.createElement('dummy') - self.mainNode.insertBefore(self.testElem, self.mainNode.firstChild) - else: - self.testElem = self.dom.createElement('dummy') - self.mainNode.appendChild(self.testElem) - self.Expand(self.root) - - # Add tree item for given parent item if node is DOM element node with - # object/object_ref tag. xxxParent is parent xxx object - def AddNode(self, itemParent, xxxParent, node): - # Set item data to current node - try: - xxx = MakeXXXFromDOM(xxxParent, node) - except: - print 'ERROR: MakeXXXFromDom(%s, %s)' % (xxxParent, node) - raise - treeObj = xxx.treeObject() - # Append tree item - item = self.AppendItem(itemParent, treeObj.treeName(), - image=treeObj.treeImage(), - data=wx.TreeItemData(xxx)) - # Different color for comments and references - if xxx.className == 'comment': - self.SetItemTextColour(item, self.COLOUR_COMMENT) - self.SetItemFont(item, self.fontComment) - elif treeObj.ref: - self.SetItemTextColour(item, self.COLOUR_REF) - elif treeObj.hasStyle and treeObj.params.get('hidden', False): - self.SetItemTextColour(item, self.COLOUR_HIDDEN) - # Try to find children objects - if treeObj.hasChildren: - nodes = treeObj.node.childNodes[:] - for n in nodes: - if IsObject(n): - self.AddNode(item, treeObj, n) - elif n.nodeType != minidom.Node.ELEMENT_NODE: - treeObj.node.removeChild(n) - n.unlink() - - # Insert new item at specific position - def InsertNode(self, itemParent, parent, elem, nextItem): - # Insert in XML tree and wxWin - xxx = MakeXXXFromDOM(parent, elem) - # If nextItem is None, we append to parent, otherwise insert before it - if nextItem.IsOk(): - node = self.GetPyData(nextItem).node - parent.node.insertBefore(elem, node) - # Inserting before is difficult, se we insert after or first child - index = self.ItemIndex(nextItem) - newItem = self.InsertItemBefore(itemParent, index, - xxx.treeName(), image=xxx.treeImage()) - self.SetPyData(newItem, xxx) - else: - parent.node.appendChild(elem) - newItem = self.AppendItem(itemParent, xxx.treeName(), image=xxx.treeImage(), - data=wx.TreeItemData(xxx)) - treeObj = xxx.treeObject() - # Different color for references and comments - if xxx.className == 'comment': - self.SetItemTextColour(newItem, self.COLOUR_COMMENT) - self.SetItemFont(newItem, self.fontComment) - elif treeObj.ref: - self.SetItemTextColour(newItem, self.COLOUR_REF) - elif treeObj.hasStyle and treeObj.params.get('hidden', False): - self.SetItemTextColour(newItem, self.COLOUR_HIDDEN) - # Add children items - if xxx.hasChildren: - treeObj = xxx.treeObject() - for n in treeObj.node.childNodes: - if IsObject(n): - self.AddNode(newItem, treeObj, n) - return newItem - - # Remove leaf of tree, return it's data object - def RemoveLeaf(self, leaf): - xxx = self.GetPyData(leaf) - node = xxx.node - parent = node.parentNode - parent.removeChild(node) - self.Delete(leaf) - return node - - # Find position relative to the top-level window - def FindNodePos(self, item, obj=None): - # Root at (0,0) - if item == g.testWin.item: return wx.Point(0, 0) - itemParent = self.GetItemParent(item) - # Select book page - if not obj: obj = self.FindNodeObject(item) - if self.GetPyData(itemParent).treeObject().__class__ in \ - [xxxNotebook, xxxChoicebook, xxxListbook]: - book = self.FindNodeObject(itemParent) - # Find position - for i in range(book.GetPageCount()): - if book.GetPage(i) == obj: - if book.GetSelection() != i: - book.SetSelection(i) - # Remove highlight - otherwise highlight window won't be visible - if g.testWin.highLight: - g.testWin.highLight.Remove() - break - # For sizers and notebooks we must select the first window-like parent - winParent = itemParent - while self.GetPyData(winParent).isSizer: - winParent = self.GetItemParent(winParent) - # Notebook children are layed out in a little strange way - # wxGTK places NB panels relative to the NB parent - if wx.Platform == '__WXGTK__': - if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook: - winParent = self.GetItemParent(winParent) - parentPos = self.FindNodePos(winParent) - pos = obj.GetPosition() - # Position (-1,-1) is really (0,0) - if pos == (-1,-1): pos = (0,0) - return parentPos + pos - - # Find window (or sizer) corresponding to a tree item. - def FindNodeObject(self, item): - testWin = g.testWin - # If top-level, return testWin (or panel its panel) - if item == testWin.item: return testWin.panel - itemParent = self.GetItemParent(item) - xxx = self.GetPyData(item).treeObject() - parentWin = self.FindNodeObject(itemParent) - # Top-level sizer? return window's sizer - if xxx.isSizer and isinstance(parentWin, wx.Window): - return parentWin.GetSizer() - elif xxx.__class__ in [xxxMenu, xxxMenuItem, xxxSeparator]: return None - elif xxx.__class__ in [xxxToolBar, xxxMenuBar]: - # If it's the main toolbar or menubar, we can't really select it - if xxx.parent.__class__ == xxxFrame: return None - elif isinstance(xxx.parent, xxxToolBar): - # Select complete toolbar - return parentWin - elif isinstance(xxx.parent, xxxStdDialogButtonSizer): - # This sizer returns non-existing children - for ch in parentWin.GetChildren(): - if ch.GetWindow() and ch.GetWindow().GetName() == xxx.name: - return ch.GetWindow() - return None - elif xxx.parent.__class__ in [xxxChoicebook, xxxListbook]: - # First window is controld - return parentWin.GetChildren()[self.ItemIndex(item)+1] - # Otherwise get parent's object and it's child - child = parentWin.GetChildren()[self.WindowIndex(item)] - # Return window or sizer for sizer items - if child.GetClassName() == 'wxSizerItem': - if child.IsWindow(): child = child.GetWindow() - elif child.IsSizer(): - child = child.GetSizer() - return child - - def OnSelChanged(self, evt): - if self.selectionChanging: return - self.selectionChanging = True - wx.TreeCtrl.UnselectAll(self) - self.ChangeSelection(evt.GetItem()) - wx.TreeCtrl.SelectItem(self, evt.GetItem()) - self.selectionChanging = False - g.frame.SetStatusText('') - evt.Skip() - - # Override to use like single-selection tree - def GetSelection(self): - return self.selection - - def SelectItem(self, item): - self.UnselectAll() - self.ChangeSelection(item) - wx.TreeCtrl.SelectItem(self, item) - - def UnselectAll(self): - self.selection = None - g.tools.UpdateUI() - wx.TreeCtrl.UnselectAll(self) - #wx.Yield() - - def ChangeSelection(self, item): - # Apply changes - # !!! problem with wxGTK - GetOldItem is Ok if nothing selected - #oldItem = evt.GetOldItem() - status = '' - oldItem = self.selection - if oldItem: - xxx = self.GetPyData(oldItem) - # If some data was modified, apply changes - if g.panel.IsModified(): - self.Apply(xxx, oldItem) - if g.testWin: - if g.testWin.highLight: - g.testWin.highLight.Remove() - self.needUpdate = True - status = 'Changes were applied' - if status: g.frame.SetStatusText(status) - # Generate view - if not item: - self.selection = None - return - else: - self.selection = item - xxx = self.GetPyData(item) - # Update panel - g.panel.SetData(xxx) - # Update tools - g.tools.UpdateUI() - # Highlighting is done in OnIdle - self.pendingHighLight = self.selection - - # Check if item is in testWin subtree - def IsHighlatable(self, item): - if item == g.testWin.item: return False - while item != self.root: - item = self.GetItemParent(item) - if item == g.testWin.item: - return True - return False - - # Highlight selected item - def HighLight(self, item): - self.pendingHighLight = None - # Can highlight only with some top-level windows - if not g.testWin or self.GetPyData(g.testWin.item).treeObject().__class__ \ - not in [xxxDialog, xxxPanel, xxxFrame]: - return - # If a control from another window is selected, remove highlight - if not self.IsHighlatable(item): - if g.testWin.highLight: g.testWin.highLight.Remove() - return - # Get window/sizer object - obj = self.FindNodeObject(item) - xxx = self.GetPyData(item).treeObject() - # Remove existing HL if item not found or is hidden - if not obj or xxx.hasStyle and xxx.params.get('hidden', False): - if g.testWin.highLight: g.testWin.highLight.Remove() - return - pos = self.FindNodePos(item, obj) - size = obj.GetSize() - # Highlight - # Negative positions are not working quite well - # If highlight object has the same size SetDimension does not repaint it - # so we must remove the old HL window - g.testWin.highLight = updateHL(g.testWin.highLight, HighLightBox, pos, size) - g.testWin.highLight.item = item - g.testWin.highLight.obj = obj - - def ShowTestWindow(self, item): - xxx = self.GetPyData(item) - if g.panel.IsModified(): - self.Apply(xxx, item) # apply changes - availableViews = ['wxFrame', 'wxPanel', 'wxDialog', - 'wxMenuBar', 'wxToolBar', 'wxWizard', - 'wxWizardPageSimple'] - originalItem = item - # Walk up the tree until we find an item that has a view - while item and self.GetPyData(item).treeObject().className not in availableViews: - item = self.GetItemParent(item) - if not item or not item.IsOk(): - wx.LogMessage('No view for this element (yet)') - return - # Show item in bold - if g.testWin: # Reset old - self.UnselectAll() - self.SetItemBold(g.testWin.item, False) - try: - wx.BeginBusyCursor() - self.CreateTestWin(item) - finally: - wx.EndBusyCursor() - # Maybe an error occurred, so we need to test - if g.testWin: - self.SetItemBold(g.testWin.item) - # Select original item - self.ChangeSelection(originalItem) - - # Double-click on Linux - def OnItemActivated(self, evt): - if evt.GetItem() != self.root: - self.ShowTestWindow(evt.GetItem()) - - # Double-click on Windows - def OnDClick(self, evt): - item, flags = self.HitTest(evt.GetPosition()) - if flags in [wx.TREE_HITTEST_ONITEMBUTTON, wx.TREE_HITTEST_ONITEMLABEL]: - if item != self.root: self.ShowTestWindow(item) - else: - evt.Skip() - - def OnItemExpandedCollapsed(self, evt): - # Update tool palette - g.tools.UpdateUI() - evt.Skip() - - # (re)create test window - def CreateTestWin(self, item): - testWin = g.testWin - # Create a window with this resource - xxx = self.GetPyData(item).treeObject() - # Close old window, remember where it was - highLight = None - if testWin: - pos = testWin.GetPosition() - if item == testWin.item: - # Remember highlight if same top-level window - if testWin.highLight: - highLight = testWin.highLight.item - if xxx.className == 'wxPanel': - if testWin.highLight: - testWin.pendingHighLight = highLight - testWin.highLight.Remove() - testWin.panel.Destroy() - testWin.panel = None - else: - testWin.Destroy() - testWin = g.testWin = None - else: - testWin.Destroy() - testWin = g.testWin = None - else: - pos = g.testWinPos - # Save in memory FS - memFile = MemoryFile('xxx.xrc') - # Create memory XML file - elem = xxx.node.cloneNode(True) - if not xxx.name: - name = 'noname' - else: - name = xxx.name - elem.setAttribute('name', STD_NAME) - oldTestNode = self.testElem - self.testElem = elem - self.mainNode.replaceChild(elem, oldTestNode) - oldTestNode.unlink() - # Replace wizard page class temporarily - if xxx.__class__ in [xxxWizardPage, xxxWizardPageSimple]: - oldCl = elem.getAttribute('class') - elem.setAttribute('class', 'wxPanel') - parent = elem.parentNode - encd = self.rootObj.params['encoding'].value() - if not encd: encd = None - try: - self.dom.writexml(memFile, encoding=encd) - except: - inf = sys.exc_info() - wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1]) - wx.LogError('Error writing temporary file') - memFile.close() # write to wxMemoryFS - xmlFlags = xrc.XRC_NO_SUBCLASSING - # Use translations if encoding is not specified - if not g.currentEncoding: - xmlFlags != xrc.XRC_USE_LOCALE - res = xrc.XmlResource('', xmlFlags) - res.InitAllHandlers() - xrc.XmlResource.Set(res) # set as global - # Register handlers - addHandlers() - # Same module list - res.Load('memory:xxx.xrc') - try: - if xxx.__class__ == xxxFrame: - # Frame can't have many children, - # but it's first child possibly can... - # child = self.GetFirstChild(item)[0] - # if child.IsOk() and self.GetPyData(child).__class__ == xxxPanel: - # # Clean-up before recursive call or error - # wx.MemoryFSHandler.RemoveFile('xxx.xrc') - # wx.EndBusyCursor() - # self.CreateTestWin(child) - # return - # This currently works under GTK, but not under MSW - testWin = g.testWin = wx.PreFrame() - res.LoadOnFrame(testWin, g.frame, STD_NAME) - # Create status bar - testWin.panel = testWin - #testWin.CreateStatusBar() - testWin.SetClientSize(testWin.GetBestSize()) - testWin.SetPosition(pos) - testWin.Show(True) - elif xxx.__class__ == xxxPanel: - # Create new frame - if not testWin: - testWin = g.testWin = wx.Frame(g.frame, -1, 'Panel: ' + name, - pos=pos, name=STD_NAME) - testWin.panel = res.LoadPanel(testWin, STD_NAME) - testWin.panel.SetSize(testWin.GetClientSize()) - #testWin.SetClientSize(testWin.GetSize()) - testWin.Show(True) - elif xxx.__class__ == xxxDialog: - testWin = g.testWin = res.LoadDialog(g.frame, STD_NAME) - testWin.panel = testWin - testWin.Layout() - testWin.SetPosition(pos) - testWin.Show(True) - # Dialog's default code does not produce wx.EVT_CLOSE - wx.EVT_BUTTON(testWin, wx.ID_OK, self.OnCloseTestWin) - wx.EVT_BUTTON(testWin, wx.ID_CANCEL, self.OnCloseTestWin) - elif xxx.__class__ == xxxWizard: - wiz = wx.wizard.PreWizard() - res.LoadOnObject(wiz, g.frame, STD_NAME, 'wxWizard') - # Find first page (don't know better way) - firstPage = None - for w in wiz.GetChildren(): - if isinstance(w, wx.wizard.WizardPage): - firstPage = w - break - if not firstPage: - wx.LogError('Wizard is empty') - else: - # Wizard should be modal - self.SetItemBold(item) - wiz.RunWizard(w) - self.SetItemBold(item, False) - wiz.Destroy() - elif xxx.__class__ in [xxxWizardPage, xxxWizardPageSimple]: - # Create new frame - if not testWin: - testWin = g.testWin = wx.Frame(g.frame, -1, 'Wizard page: ' + name, - pos=pos, name=STD_NAME) - testWin.panel = wx.PrePanel() - res.LoadOnObject(testWin.panel, testWin, STD_NAME, 'wxPanel') - testWin.SetClientSize(testWin.GetBestSize()) - testWin.Show(True) - elif xxx.__class__ == xxxMenuBar: - testWin = g.testWin = wx.Frame(g.frame, -1, 'MenuBar: ' + name, - pos=pos, name=STD_NAME) - testWin.panel = None - # Set status bar to display help - testWin.CreateStatusBar() - testWin.menuBar = res.LoadMenuBar(STD_NAME) - testWin.SetMenuBar(testWin.menuBar) - testWin.Show(True) - elif xxx.__class__ == xxxToolBar: - testWin = g.testWin = wx.Frame(g.frame, -1, 'ToolBar: ' + name, - pos=pos, name=STD_NAME) - testWin.panel = None - # Set status bar to display help - testWin.CreateStatusBar() - testWin.toolBar = res.LoadToolBar(testWin, STD_NAME) - testWin.SetToolBar(testWin.toolBar) - testWin.Show(True) - # Catch some events, set highlight - if testWin: - testWin.item = item - wx.EVT_CLOSE(testWin, self.OnCloseTestWin) - wx.EVT_SIZE(testWin, self.OnSizeTestWin) - # Add drop target - if testWin.panel: - testWin.panel.SetDropTarget(DropTarget()) - else: - testWin.SetDropTarget(DropTarget()) - # Reset highlights - testWin.highLight = testWin.highLightDT = None - if highLight and not self.pendingHighLight: - self.HighLight(highLight) - except: - if g.testWin: - self.SetItemBold(item, False) - g.testWinPos = g.testWin.GetPosition() - g.testWin.Destroy() - g.testWin = None - inf = sys.exc_info() - wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1]) - wx.LogError('Error loading resource') - # Cleanup - res.Unload('xxx.xrc') - xrc.XmlResource.Set(None) - wx.MemoryFSHandler.RemoveFile('xxx.xrc') - - def CloseTestWindow(self): - if not g.testWin: return - self.SetItemBold(g.testWin.item, False) - g.frame.tb.ToggleTool(g.frame.ID_TOOL_LOCATE, False) - g.testWinPos = g.testWin.GetPosition() - g.testWin.Destroy() - g.testWin = None - - def OnCloseTestWin(self, evt): - self.CloseTestWindow() - - def OnSizeTestWin(self, evt): - # Update highlight after size change - hl = g.testWin.highLight - if hl: - hl.Replace(self.FindNodePos(hl.item), hl.obj.GetSize()) - hl.Refresh() - #self.HighLight(g.testWin.highLight.item) - evt.Skip() - - # Return index in parent, for real window children - def WindowIndex(self, item): - n = 0 # index of sibling - prev = self.GetPrevSibling(item) - while prev.IsOk(): - # MenuBar and sizers are not real children (who else?) - if not isinstance(self.GetPyData(prev), xxxMenuBar) and not \ - isinstance(self.GetPyData(prev), xxxSizer): - n += 1 - prev = self.GetPrevSibling(prev) - return n - - # Return item index in parent - def ItemIndex(self, item): - n = 0 # index of sibling - prev = self.GetPrevSibling(item) - while prev.IsOk(): - prev = self.GetPrevSibling(prev) - n += 1 - return n - - # Full tree index of an item - list of positions - def ItemFullIndex(self, item): - if not item.IsOk(): return None - l = [] - while item != self.root: - l.insert(0, self.ItemIndex(item)) - item = self.GetItemParent(item) - return l - # Get item position from full index - def ItemAtFullIndex(self, index): - if index is None: return wx.TreeItemId() - item = self.root - for i in index: - item = self.GetFirstChild(item)[0] - for k in range(i): item = self.GetNextSibling(item) - return item - - # True if next item should be inserted after current (vs. appended to it) - def NeedInsert(self, item): - xxx = self.GetPyData(item) - if item == self.root: return False # root item - if xxx.hasChildren and not self.GetChildrenCount(item, False): - return False - return not (self.IsExpanded(item) and self.GetChildrenCount(item, False)) - - # Pull-down - def OnRightDown(self, evt): - pullDownMenu = g.pullDownMenu - # select this item - pt = evt.GetPosition(); - item, flags = self.HitTest(pt) - if item.Ok() and flags & wx.TREE_HITTEST_ONITEM: - self.SelectItem(item) - - # Setup menu - menu = wx.Menu() - - item = self.selection - if not item: - menu.Append(g.pullDownMenu.ID_EXPAND, 'Expand', 'Expand tree') - menu.Append(g.pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse tree') - else: -# self.ctrl = evt.ControlDown() # save Ctrl state -# self.shift = evt.ShiftDown() # and Shift too - m = wx.Menu() # create menu - if self.ctrl: - needInsert = True - else: - needInsert = self.NeedInsert(item) - if item == self.root or needInsert and self.GetItemParent(item) == self.root: - SetMenu(m, pullDownMenu.topLevel) - m.AppendSeparator() - m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node') - m.Append(ID_NEW.COMMENT, 'comment', 'Create comment node') - else: - xxx = self.GetPyData(item).treeObject() - # Check parent for possible child nodes if inserting sibling - if needInsert: xxx = xxx.parent - if xxx.__class__ == xxxMenuBar: - m.Append(ID_NEW.MENU, 'Menu', 'Create menu') - elif xxx.__class__ in [xxxToolBar, xxxTool] or \ - xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar: - SetMenu(m, pullDownMenu.toolBarControls) - elif xxx.__class__ in [xxxMenu, xxxMenuItem]: - SetMenu(m, pullDownMenu.menuControls) - elif xxx.__class__ == xxxStdDialogButtonSizer: - SetMenu(m, pullDownMenu.stdButtons) - else: - SetMenu(m, pullDownMenu.controls) - if xxx.__class__ in [xxxNotebook, xxxChoicebook, xxxListbook]: - m.Enable(m.FindItem('sizer'), False) - elif not (xxx.isSizer or xxx.parent and xxx.parent.isSizer): - m.Enable(ID_NEW.SPACER, False) - if xxx.__class__ is not xxxFrame: - m.Enable(ID_NEW.MENU_BAR, False) - # Add custom controls menu - if len(pullDownMenu.custom) > 2: - SetMenu(m, [pullDownMenu.custom]) - m.AppendSeparator() - m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node') - m.Append(ID_NEW.COMMENT, 'comment', 'Create comment node') - # Select correct label for create menu - if not needInsert: - if self.shift: - menu.AppendMenu(wx.NewId(), 'Insert Child', m, - 'Create child object as the first child') - else: - menu.AppendMenu(wx.NewId(), 'Append Child', m, - 'Create child object as the last child') - else: - if self.shift: - menu.AppendMenu(wx.NewId(), 'Create Sibling', m, - 'Create sibling before selected object') - else: - menu.AppendMenu(wx.NewId(), 'Create Sibling', m, - 'Create sibling after selected object') - # Build replace menu - if item != self.root: - xxx = self.GetPyData(item).treeObject() - m = wx.Menu() # create replace menu - if xxx.__class__ == xxxMenuBar: - m.Append(1000 + ID_NEW.MENU, 'Menu', 'Create menu') - elif xxx.__class__ in [xxxMenu, xxxMenuItem]: - SetMenu(m, pullDownMenu.menuControls, shift=True) - elif xxx.__class__ == xxxToolBar and \ - self.GetItemParent(item) == self.root: - SetMenu(m, [], shift=True) - elif xxx.__class__ in [xxxFrame, xxxDialog, xxxPanel]: - SetMenu(m, [ - (ID_NEW.PANEL, 'Panel', 'Create panel'), - (ID_NEW.DIALOG, 'Dialog', 'Create dialog'), - (ID_NEW.FRAME, 'Frame', 'Create frame')], shift=True) - elif xxx.isSizer and self.ItemHasChildren(item): - SetMenu(m, pullDownMenu.sizers, shift=True) - else: - SetMenu(m, pullDownMenu.controls, shift=True) - if xxx.isElement: - id = wx.NewId() - menu.AppendMenu(id, 'Replace With', m) - if not m.GetMenuItemCount(): menu.Enable(id, False) - menu.Append(pullDownMenu.ID_SUBCLASS, 'Subclass...', - 'Set "subclass" property') - menu.AppendSeparator() - # Not using standart IDs because we don't want to show shortcuts - menu.Append(wx.ID_CUT, 'Cut', 'Cut to the clipboard') - menu.Append(wx.ID_COPY, 'Copy', 'Copy to the clipboard') - if self.ctrl and item != self.root: - menu.Append(pullDownMenu.ID_PASTE_SIBLING, 'Paste Sibling', - 'Paste from the clipboard as a sibling') - else: - menu.Append(wx.ID_PASTE, 'Paste', 'Paste from the clipboard') - menu.Append(pullDownMenu.ID_DELETE, - 'Delete', 'Delete object') - if self.ItemHasChildren(item): - menu.AppendSeparator() - menu.Append(pullDownMenu.ID_EXPAND, 'Expand', 'Expand subtree') - menu.Append(pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse subtree') - self.PopupMenu(menu, evt.GetPosition()) - menu.Destroy() - - # Apply changes - def Apply(self, xxx, item): - g.panel.Apply() - # Update tree view - xxx = xxx.treeObject() - if xxx.hasName and self.GetItemText(item) != xxx.name: - self.SetItemText(item, xxx.treeName()) - # Item width may have changed - # !!! Tric to update tree width (wxGTK, ??) - self.SetIndent(self.GetIndent()) - elif xxx.className == 'comment': - self.SetItemText(item, xxx.treeName()) - # Change tree icon for sizers - if isinstance(xxx, xxxBoxSizer): - self.SetItemImage(item, xxx.treeImage()) - # Set global modified state - g.frame.SetModified() - - def OnBeginLabelEdit(self, evt): - xxx = self.GetPyData(evt.GetItem()) - if xxx.isElement: - evt.Veto() - else: - evt.Skip() - - def OnEndLabelEdit(self, evt): - xxx = self.GetPyData(evt.GetItem()) - node = xxx.node - if not xxx.isElement: - node.data = evt.GetLabel() - g.panel.SetData(xxx) - evt.Skip() - -################################################################################ - -# DragAndDrop - -class DropTarget(wx.PyDropTarget): - def __init__(self): - self.do = MyDataObject() - wx.DropTarget.__init__(self, self.do) - - # Find best object for dropping - def WhereToDrop(self, x, y, d): - # Find object by position - obj = wx.FindWindowAtPoint(g.testWin.ClientToScreen((x,y))) - if not obj: - return wx.DragNone, () - item = g.frame.FindObject(g.testWin.item, obj) - if not item: - return wx.DragNone, () - xxx = g.tree.GetPyData(item).treeObject() - parentItem = None - # Check if window has a XRC sizer, then use it as parent - if obj.GetSizer(): - sizer = obj.GetSizer() - sizerItem = g.frame.FindObject(g.testWin.item, sizer) - if sizerItem: - parentItem = sizerItem - obj = sizer - item = wx.TreeItemId() - # if not sizer but can have children, it is parent with free placement - elif xxx.hasChildren: - parentItem = item - item = wx.TreeItemId() - # Otherwise, try to add to item's parent - if not parentItem: - parentItem = g.tree.GetItemParent(item) - obj = g.tree.FindNodeObject(parentItem) - parent = g.tree.GetPyData(parentItem).treeObject() - return d,(obj,parent,parentItem,item) - - # Drop - def OnData(self, x, y, d): - self.GetData() - id = int(self.do.GetDataHere()) - d,other = self.WhereToDrop(x, y, d) - if d != wx.DragNone: - obj,parent,parentItem,item = other - g.tree.selection = parentItem - xxx = g.frame.CreateXXX(parent, parentItem, item, id) - # Set coordinates if parent is not sizer - if not parent.isSizer: - xxx.set('pos', '%d,%d' % (x, y)) - g.panel.SetData(xxx) - g.frame.SetStatusText('Object created') - self.RemoveHL() - return d - - def OnDragOver(self, x, y, d): - d,other = self.WhereToDrop(x, y, d) - if d != wx.DragNone: - obj,parent,parentItem,item = other - pos, size = g.tree.FindNodePos(parentItem, obj), obj.GetSize() - hl = g.testWin.highLightDT - # Set color of highlighted item back to normal - if hl and hl.item: - if hl.item != parentItem: - g.tree.SetItemTextColour(hl.item, g.tree.itemColour) - # Highlight future parent - g.tree.itemColour = g.tree.GetItemTextColour(parentItem) # save current - if not hl or hl.item != parentItem: - g.testWin.highLightDT = updateHL(hl, HighLightDTBox, pos, size) - g.testWin.highLightDT.item = parentItem - g.tree.SetItemTextColour(parentItem, g.tree.COLOUR_DT) - g.tree.EnsureVisible(parentItem) - g.frame.SetStatusText('Drop target: %s' % parent.treeName()) - else: - g.frame.SetStatusText('Inappropriate drop target') - self.RemoveHL() - return d - - def OnLeave(self): - self.RemoveHL() - - def RemoveHL(self): - hl = g.testWin.highLightDT - if hl: - if hl.item: - g.tree.SetItemTextColour(hl.item, g.tree.itemColour) - hl.Remove() -