Example #1
0
def OpenFile(parent, path):
    #FIXME: support: svg, sgvz, svg.gz with rsvg or batik (render to temporary
    #file /tmp/<PID><time()><atime(f.svg>.png and then open a frame)

    if not os.path.exists(path) or os.path.isdir(path): return
    frame = wxFrame(parent, -1, "File view: " + path, wxDefaultPosition,
                    wxSize(500, 400))

    handled = 0
    needFrame = 1
    lowerPath = string.lower(path)
    #for animations or to see if count is > 0:
    #wxImage_GetImageCount(path)
    if lowerPath[-3:] in ("ani", "bmp", "cur", "gif", "ico", "iff", "jpg", "pcx", "png", "pnm", \
                          "tif", "xpm") or lowerPath[-4:] in ("jpeg", "tiff"):
        #f = open(path, "rb"); data = f.read(); f.close()
        #stream = StringIO(data)
        #img = wxImageFromStream(stream)
        img = wxEmptyImage()
        img.LoadFile(path)
        bmp = wxBitmapFromImage(img)
        #wxStaticBitmap(frame, -1, bmp) #, (15, 45))

        width, height = img.GetWidth(), img.GetHeight()
        if width and height:
            sw = wxScrolledWindow(frame, -1, wxDefaultPosition, wxDefaultSize,
                                  wxHSCROLL | wxVSCROLL)
            #sw.SetScrollbars(20, 20, img.GetWidth()/20, img.GetHeight()/20)
            sw.SetVirtualSize(wxSize(width, height))
            sw.SetScrollRate(20, 20)
            wxStaticBitmap(sw, -1, bmp)  #, (15, 45))
            w, h = 800, 600  #frame.GetSize()
            w, h = min(w, width), min(h, height)
            minSize, b = 100, 10
            if w < minSize: w = minSize
            if h < minSize: h = minSize
            frame.SetSize(wxSize(w + b, h + b))
            handled = 1
    elif "html" == lowerPath[-4:] or "htm" == path[-3:]:
        htmlWin = wxHtmlWindow(frame)
        htmlWin.LoadPage(path)
        handled = 1
    elif "pdf" == lowerPath[-3:]:
        for cmd in ("xpdf", "acroread"):
            #FIXME: handle names that contain spaces etc.
            status, output = commands.getstatusoutput(cmd + " " + path)
            if 0 == status:
                handled = 1
                needFrame = 0
                break
    #FIXME: mplayer cannot run in background; same goes for Python calling mplayer externally - probably stdin dependence
    elif "mpeg" == lowerPath[-4:] or \
         lowerPath[-3:] in ("asf", "avi", "mov", "mpa", "mpg", "wmv"):
        for cmd in ("mplayer -quiet", ):
            #FIXME: handle names that contain spaces etc.
            status, output = commands.getstatusoutput(cmd + " " + path)
            if 0 == status:
                handled = 1
                needFrame = 0
                break

    elif "ps" == lowerPath[-2:] or "ps.gz" == lowerPath[-5:]:
        pid = os.fork()
        if 0 == pid:
            for cmd in ("ggv", "gv"):
                try:
                    os.execlp(cmd, cmd, path)
                except OSError:
                    pass
            os.exit(1)
        handled = 1
        needFrame = 0

    if not handled:
        minSize = 65536
        try:
            f = open(path, "rb")
            data = f.read(minSize)
            f.close()
        except IOError, ex:
            MsgOS(ex)
            return None
        txt = wxTextCtrl(frame,
                         -1,
                         data,
                         style=wxTE_READONLY | wxTE_MULTILINE | wxTE_DONTWRAP
                         | wxHSCROLL)
        if len(data) == minSize:
            sizer = wxBoxSizer(wxVERTICAL)
            frame.SetAutoLayout(true)
            frame.SetSizer(sizer)
            frame.sizer = sizer
            b = wxButton(frame, -1, "Show entire file")
            sizer.Add(txt, 1, wxEXPAND | wxALL, 0)
            sizer.Add(b, 0, wxALIGN_CENTRE, 0)
            sizer.Layout()
Example #2
0
def OpenFile(parent, path):
    #FIXME: support: svg, sgvz, svg.gz with rsvg or batik (render to temporary
    #file /tmp/<PID><time()><atime(f.svg>.png and then open a frame)

    if not os.path.exists(path) or os.path.isdir(path): return
    frame = wxFrame(parent, -1, "File view: " + path, wxDefaultPosition, wxSize(500, 400))

    handled = 0
    needFrame = 1
    lowerPath = string.lower(path)
    #for animations or to see if count is > 0:
    #wxImage_GetImageCount(path)
    if lowerPath[-3:] in ("ani", "bmp", "cur", "gif", "ico", "iff", "jpg", "pcx", "png", "pnm", \
                          "tif", "xpm") or lowerPath[-4:] in ("jpeg", "tiff"):
        #f = open(path, "rb"); data = f.read(); f.close()
        #stream = StringIO(data)
        #img = wxImageFromStream(stream)
        img = wxEmptyImage()
        img.LoadFile(path)
        bmp = wxBitmapFromImage(img)
        #wxStaticBitmap(frame, -1, bmp) #, (15, 45))

        width, height = img.GetWidth(), img.GetHeight()
        if width and height:
            sw = wxScrolledWindow(frame, -1, wxDefaultPosition, wxDefaultSize,
                                  wxHSCROLL | wxVSCROLL)
            #sw.SetScrollbars(20, 20, img.GetWidth()/20, img.GetHeight()/20)
            sw.SetVirtualSize(wxSize(width, height))
            sw.SetScrollRate(20, 20)
            wxStaticBitmap(sw, -1, bmp) #, (15, 45))
            w, h = 800, 600 #frame.GetSize()
            w, h = min(w, width), min(h, height)
            minSize, b = 100, 10
            if w < minSize: w = minSize
            if h < minSize: h = minSize
            frame.SetSize(wxSize(w+b, h+b))
            handled = 1
    elif "html" == lowerPath[-4:] or "htm" == path[-3:]:
        htmlWin = wxHtmlWindow(frame)
        htmlWin.LoadPage(path)
        handled = 1
    elif "pdf" == lowerPath[-3:]:
        for cmd in ("xpdf", "acroread"):
            #FIXME: handle names that contain spaces etc.
            status, output = commands.getstatusoutput(cmd + " " + path)
            if 0 == status:
                handled = 1
                needFrame = 0
                break
    #FIXME: mplayer cannot run in background; same goes for Python calling mplayer externally - probably stdin dependence
    elif "mpeg" == lowerPath[-4:] or \
         lowerPath[-3:] in ("asf", "avi", "mov", "mpa", "mpg", "wmv"):
        for cmd in ("mplayer -quiet",):
            #FIXME: handle names that contain spaces etc.
            status, output = commands.getstatusoutput(cmd + " " + path)
            if 0 == status:
                handled = 1
                needFrame = 0
                break

    elif "ps" == lowerPath[-2:] or "ps.gz" == lowerPath[-5:]:
        pid = os.fork()
        if 0 == pid:
            for cmd in ("ggv", "gv"):
                try:
                    os.execlp(cmd, cmd, path)
                except OSError:
                    pass
            os.exit(1)
        handled = 1
        needFrame = 0

    if not handled:
        minSize = 65536
        try:
            f = open(path, "rb"); data = f.read(minSize); f.close()
        except IOError, ex:
            MsgOS(ex)
            return None
        txt = wxTextCtrl(frame, -1, data,
                         style=wxTE_READONLY|wxTE_MULTILINE|wxTE_DONTWRAP|wxHSCROLL)
        if len(data) == minSize:
            sizer = wxBoxSizer(wxVERTICAL)
            frame.SetAutoLayout(true)
            frame.SetSizer(sizer)
            frame.sizer = sizer
            b = wxButton(frame, -1, "Show entire file")
            sizer.Add(txt, 1, wxEXPAND|wxALL, 0)
            sizer.Add(b, 0, wxALIGN_CENTRE, 0)
            sizer.Layout()
Example #3
0
    def __init__(self, parent, id, title, initHeight=710, initPane=1):
        wxFrame.__init__(
            self, parent, -1, title, size=(800, initHeight), style=wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE
        )

        self.cwd = os.getcwd()
        self.curOverview = ""
        self.window = None
        self.initialPane = initPane
        self.nb = None
        self.log = None
        self.society = None  # for holding a society in Society Editor and Rule tabs
        self.agentSociety = None  # for holding a society that's just an agent list
        self.mappedSociety = None  # for holding a newly HNA-mapped society
        self.societyViewer = None  # wxTreeCtrl for displaying the society in Society Editor
        self.agentViewer = None  # wxTreeCtrl for displaying initial agent list in Agent Laydown tab
        self.laydownViewer = None  # wxTreeCtrl for displaying host-node-agent laydown
        self.societyOpen = false  # for the Society Editor
        self.agentSocietyOpen = false  # for the Agent List in Agent Laydown tab
        self.mappedSocietyOpen = false  # for the HNA Map in Agent Laydown tab
        self.societyFile = None  # string name of xml file for self.society
        self.agentSocietyFile = None  # string name of xml file for self.agentSociety
        self.societyHnaFile = None  # string name of xml file for self.mappedSociety
        self.controlFile = None  # string name of xml file for self.controlFile
        self.ruleOpen = false
        self.ruleApplied = false
        self.currentPage = AWB.RULE_EDITOR
        self.currentTree = None
        self.undoBuffer = []
        self.rulebookId = AWB.CLOSE_RULEBOOK * 10

        self.openRulebookCount = 0
        self.searchLabel = ""
        self.caseSearchDesired = False
        self.objCloset = {}  # for storing entity obj's during DnD ops
        self.dragSource = None  # for storing viewer that was source of a drag
        self.windowHeight = initHeight
        self.mappedSocietySaveCounter = 0
        icon = images.getCSMARTerIcon()
        self.SetIcon(icon)

        try:
            if wxPlatform == "__WXMSW__":
                # setup a taskbar icon, and catch some events from it
                self.tbicon = wxTaskBarIcon()
                self.tbicon.SetIcon(icon, "CS03")
                EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate)
                EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu)
                EVT_MENU(self.tbicon, self.TBMENU_RESTORE, self.OnTaskBarActivate)
                EVT_MENU(self.tbicon, self.TBMENU_CLOSE, self.OnTaskBarClose)

            wxCallAfter(self.ShowTip)

            self.otherWin = None
            EVT_IDLE(self, self.OnIdle)
            EVT_CLOSE(self, self.OnCloseWindow)
            EVT_ICONIZE(self, self.OnIconfiy)
            EVT_MAXIMIZE(self, self.OnMaximize)

            self.Centre(wxBOTH)
            self.CreateStatusBar(1, wxST_SIZEGRIP)

            splitterId = wxNewId()
            self.splitter2 = wxSplitterWindow(self, splitterId, style=wxNO_3D | wxSP_3D)
            EVT_SIZE(self, self.OnSplitterResize)

            def EmptyHandler(evt):
                pass

            EVT_ERASE_BACKGROUND(self.splitter2, EmptyHandler)

            # ---------------------------------------------------------------------------

            # Make a File menu
            self.mainmenu = wxMenuBar()
            fileMenu = wxMenu()

            fileMenu.Append(AWB.SAVE_RULE, "Save &Rule\tCtrl+R", "Save an existing rule")
            EVT_MENU(self, AWB.SAVE_RULE, self.OnRuleSave)

            fileMenu.Append(AWB.SAVE_AS_RULE, "Save R&ule As...\tAlt+R", "Save as a new rule")
            EVT_MENU(self, AWB.SAVE_AS_RULE, self.OnRuleSaveAs)

            fileMenu.Append(AWB.SAVE_SOCIETY, "&Save Society\tCtrl+S", "Save an existing society")
            EVT_MENU(self, AWB.SAVE_SOCIETY, self.OnSocietySave)

            fileMenu.Append(AWB.SAVE_AS_SOCIETY, "Save Society &As...\tAlt+S", "Save as a new society")
            EVT_MENU(self, AWB.SAVE_AS_SOCIETY, self.OnSocietySaveAs)

            fileMenu.Append(AWB.SAVE_AS_HNA_SOCIETY, "Save HNA &Map As...\tAlt+M", "Save as a new society")
            EVT_MENU(self, AWB.SAVE_AS_HNA_SOCIETY, self.OnHnaMapSaveAs)

            exitID = wxNewId()
            fileMenu.Append(exitID, "E&xit\tAlt+X", "Get the heck outta here!")
            EVT_MENU(self, exitID, self.OnFileExit)

            if not self.ruleOpen:
                fileMenu.Enable(AWB.SAVE_RULE, false)
                fileMenu.Enable(AWB.SAVE_AS_RULE, false)
            if not self.societyOpen:
                fileMenu.Enable(AWB.SAVE_SOCIETY, false)
                fileMenu.Enable(AWB.SAVE_AS_SOCIETY, false)
            if not self.mappedSocietyOpen:
                fileMenu.Enable(AWB.SAVE_AS_HNA_SOCIETY, false)

            self.mainmenu.Append(fileMenu, "&File")

            # ---------------------------------------------------------------------------

            # Make an Edit menu
            self.editMenu = wxMenu()

            self.editMenu.Append(AWB.UNDO, "&Undo\tCtrl+Z", "Undo last edit")
            EVT_MENU(self, AWB.UNDO, self.OnUndo)
            self.editMenu.Enable(AWB.UNDO, false)

            self.editMenu.Append(AWB.SORT, "&Sort selected item", "Sort entities in selected item")
            EVT_MENU(self, AWB.SORT, self.OnSort)
            self.editMenu.Enable(AWB.SORT, false)

            self.editMenu.Append(AWB.CHANGE_NAMESERVER, "Change &name server", "Specify a new name server")
            EVT_MENU(self, AWB.CHANGE_NAMESERVER, self.OnChangeNameServer)
            self.editMenu.Enable(AWB.CHANGE_NAMESERVER, false)

            self.editMenu.Append(AWB.FIND, "&Find\tCtrl+F", "Find a specific society entity by name")
            EVT_MENU(self, AWB.FIND, self.OnFind)
            self.editMenu.Enable(AWB.FIND, false)

            self.editMenu.Append(
                AWB.FIND_NEXT, "Find &Next\tF3", "Find the next occurrence of a specific society entity by name"
            )
            EVT_MENU(self, AWB.FIND_NEXT, self.OnFindNext)
            self.editMenu.Enable(AWB.FIND_NEXT, false)

            self.editMenu.Append(AWB.RENAME_RULE, "&Rename Rule\tCtrl+R", "Rename a society transformation rule")
            EVT_MENU(self, AWB.RENAME_RULE, self.OnRenameRule)
            self.editMenu.Enable(AWB.RENAME_RULE, false)

            self.editMenu.Append(AWB.DELETE_RULE, "&Delete Rule\tAlt+D", "Delete a society transformation rule")
            EVT_MENU(self, AWB.DELETE_RULE, self.OnDeleteRule)
            self.editMenu.Enable(AWB.DELETE_RULE, false)

            self.mainmenu.Append(self.editMenu, "&Edit")

            # ---------------------------------------------------------------------------

            # Make an View menu
            self.viewMenu = wxMenu()

            self.viewMenu.Append(AWB.SHOW_SOCIETY, "Show &Entire Society\tCtrl+E", "Expand entire Society tree")
            EVT_MENU(self, AWB.SHOW_SOCIETY, self.OnShowSociety)

            self.viewMenu.Append(AWB.SHOW_NODES, "Show All &Nodes\tCtrl+N", "Show All Nodes")
            EVT_MENU(self, AWB.SHOW_NODES, self.OnShowNodes)

            self.viewMenu.Append(AWB.SHOW_AGENTS, "Show All &Agents\tCtrl+A", "Show All Agents")
            EVT_MENU(self, AWB.SHOW_AGENTS, self.OnShowAgents)

            self.viewMenu.Append(AWB.SHOW_COMPONENTS, "Show All &Components\tCtrl+C", "Show All Components")
            EVT_MENU(self, AWB.SHOW_COMPONENTS, self.OnShowComponents)

            self.viewMenu.Append(AWB.COLLAPSE_HOSTS, "Collapse To &Hosts\tAlt+O", "Collapse To Hosts")
            EVT_MENU(self, AWB.COLLAPSE_HOSTS, self.OnCollapseHosts)

            self.viewMenu.Append(AWB.COLLAPSE_NODES, "Collapse To &Nodes\tAlt+N", "Collapse To Nodes")
            EVT_MENU(self, AWB.COLLAPSE_NODES, self.OnCollapseNodes)

            self.viewMenu.Append(AWB.COLLAPSE_AGENTS, "Collapse To &Agents\tAlt+A", "Collapse To Agents")
            EVT_MENU(self, AWB.COLLAPSE_AGENTS, self.OnCollapseAgents)

            self.viewMenu.Append(AWB.COLLAPSE_COMPONENTS, "Collapse To &Components\tAlt+C", "Collapse To Components")
            EVT_MENU(self, AWB.COLLAPSE_COMPONENTS, self.OnCollapseComponents)

            self.viewMenu.AppendSeparator()

            helpText = "Removes rules belonging to the chosen rulebook from the Rulebook window"
            self.viewMenu.Append(AWB.CLOSE_RULEBOOK, "Close RuleBook\tCtrl+B", helpText)
            EVT_MENU(self, AWB.CLOSE_RULEBOOK, self.OnCloseRulebook)

            self.viewMenu.Enable(AWB.SHOW_SOCIETY, false)
            self.viewMenu.Enable(AWB.SHOW_NODES, false)
            self.viewMenu.Enable(AWB.SHOW_AGENTS, false)
            self.viewMenu.Enable(AWB.SHOW_COMPONENTS, false)
            self.viewMenu.Enable(AWB.COLLAPSE_HOSTS, false)
            self.viewMenu.Enable(AWB.COLLAPSE_NODES, false)
            self.viewMenu.Enable(AWB.COLLAPSE_AGENTS, false)
            self.viewMenu.Enable(AWB.COLLAPSE_COMPONENTS, false)
            self.viewMenu.Enable(AWB.CLOSE_RULEBOOK, false)

            self.mainmenu.Append(self.viewMenu, "&View")

            # ---------------------------------------------------------------------------

            # Make a Help menu
            helpMenu = wxMenu()

            debugMenu = wxMenu()

            printSocModelId = wxNewId()
            debugMenu.Append(
                printSocModelId, "Print society model (plain text)\tF11", "Print plain text to console window."
            )
            EVT_MENU(self, printSocModelId, self.OnPrintSocietyModelPlain)

            printSocModelXmlId = wxNewId()
            debugMenu.Append(printSocModelXmlId, "Print society model (XML)\tF12", "Print XML text to console window.")
            EVT_MENU(self, printSocModelXmlId, self.OnPrintSocietyModelXML)

            debugId = wxNewId()
            helpMenu.AppendMenu(debugId, "Debug", debugMenu)

            helpId = wxNewId()
            helpMenu.Append(helpId, "&About\tF1", "wxPython RULES!!!")
            EVT_MENU(self, helpId, self.OnHelpAbout)

            self.mainmenu.Append(helpMenu, "&Help")

            # ---------------------------------------------------------------------------

            self.SetMenuBar(self.mainmenu)

            # set the menu accellerator table...
            aTable = wxAcceleratorTable([(wxACCEL_ALT, ord("X"), exitID), (wxACCEL_CTRL, ord("H"), helpId)])
            self.SetAcceleratorTable(aTable)

            # ---------------------------------------------------------------------------

            # Create a Notebook to go in top of wxSplitterWindow
            self.nb = wxNotebook(self.splitter2, -1, style=wxCLIP_CHILDREN)
            EVT_NOTEBOOK_PAGE_CHANGED(self, -1, self.OnPageChange)

            # Set up a log on the View Log Notebook page to go in bottom of wxSplitter Window
            self.log = wxTextCtrl(self.splitter2, -1, style=wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL)

            # Set the wxWindows log target to be this textctrl
            # wxLog_SetActiveTarget(wxLogTextCtrl(self.log))

            # But instead of the above we want to show how to use our own wxLog class
            self.logger = MyLog(self.log)
            wxLog_SetActiveTarget(self.logger)

            # ~ wxLogChain(wxLogStderr())
            # ~ wxLogChain(self.logger)

            # ~ wxLog_SetLogLevel(wxLOG_Warning)
            wxLog_SetLogLevel(wxLOG_Message)

            # for serious debugging
            # wxLog_SetActiveTarget(wxLogStderr())
            # wxLog_SetTraceMask(wxTraceMessages)

            # Notebook page 0:  AWB Overview
            if 0:  # the old way
                self.ovr = wxHtmlWindow(self.nb, -1, size=(400, 400))
                self.nb.AddPage(self.ovr, self.overviewText)

            else:  # hopefully I can remove this hacky code soon, see bug #216861
                panel = wxPanel(self.nb, -1, style=wxCLIP_CHILDREN)
                self.ovr = wxHtmlWindow(panel, -1, size=(400, 400))
                self.nb.AddPage(panel, self.overviewText)

                def OnOvrSize(evt, ovr=self.ovr):
                    ovr.SetSize(evt.GetSize())

                EVT_SIZE(panel, OnOvrSize)
                EVT_ERASE_BACKGROUND(panel, EmptyHandler)

            self.SetOverview(self.overviewText, overview)

            # Notebook page 1:  Rule Editor
            self.ruleEditor = SocietyBuilderPanel(self.nb, self, self.log)
            self.nb.AddPage(self.ruleEditor, "Rules")

            # Notebook page 2:  Society Editor
            self.societyEditor = SocietyEditorPanel(self.nb, self, self.log)
            self.nb.AddPage(self.societyEditor, "Society Editor")

            # Notebook page 3:  Agent Laydown
            self.agentLaydown = AgentLaydownPanel(self.nb, self, self.log)
            self.nb.AddPage(self.agentLaydown, "Agent Laydown")

            # Notebook page 4:  Society Controller
            self.societyController = SocietyController(self.nb, self, self.log)
            self.nb.AddPage(self.societyController, "Society Controller")

            self.Show(true)

            # add the windows to the splitter and split it.
            self.splitter2.SplitHorizontally(self.nb, self.log, 560)
            self.splitter2.SetMinimumPaneSize(20)

            # select initial items
            self.nb.SetSelection(self.initialPane)

            # wxLogMessage('window handle: %s' % self.GetHandle())
            wxLogMessage("CS03 initialized.")

        except Exception:
            import traceback

            traceback.print_exc()
Example #4
0
    def SetData(self, xxx):
        self.pages = []
        # First page
        # Remove current objects and sizer
        sizer = self.ResetPage(self.page1)
        if not xxx or (not xxx.allParams and not xxx.hasName and not xxx.hasChild):
            if g.tree.selection:
                sizer.Add(wxStaticText(self.page1, -1, 'This item has no properties.'))
            else:                       # nothing selected
                # If first time, show some help
                if g.conf.panic:
                    html = wxHtmlWindow(self.page1, -1, wxDefaultPosition,
                                        wxDefaultSize, wxSUNKEN_BORDER)
                    html.SetPage(g.helpText)
                    sizer.Add(html, 1, wxEXPAND)
                    g.conf.panic = False
                else:
                    sizer.Add(wxStaticText(self.page1, -1, 'Select a tree item.'))
        else:
            g.currentXXX = xxx.treeObject()
            # Normal or SizerItem page
            isGBSizerItem = isinstance(xxx.parent, xxxGridBagSizer)
            cacheID = (xxx.__class__, isGBSizerItem)            
            try:
                page = self.pageCache[cacheID]
                page.box.SetLabel(xxx.panelName())
                page.Show()
            except KeyError:
                page = PropPage(self.page1, xxx.panelName(), xxx)
                self.pageCache[cacheID] = page
            page.SetValues(xxx)
            self.pages.append(page)
            sizer.Add(page, 1, wxEXPAND)
            if xxx.hasChild:
                # Special label for child objects - they may have different GUI
                cacheID = (xxx.child.__class__, xxx.__class__)
                try:
                    page = self.pageCache[cacheID]
                    page.box.SetLabel(xxx.child.panelName())
                    page.Show()
                except KeyError:
                    page = PropPage(self.page1, xxx.child.panelName(), xxx.child)
                    self.pageCache[cacheID] = page
                page.SetValues(xxx.child)
                self.pages.append(page)
                sizer.Add(page, 0, wxEXPAND | wxTOP, 5)
        self.page1.Layout()
        size = self.page1.GetSizer().GetMinSize()
        self.page1.SetScrollbars(1, 1, size.width, size.height, 0, 0, True)

        # Second page
        # Create if does not exist
        if xxx and xxx.treeObject().hasStyle:
            xxx = xxx.treeObject()
            # Simplest case: set data if class is the same
            sizer = self.ResetPage(self.page2)
            try:
                page = self.stylePageCache[xxx.__class__]
                page.Show()
            except KeyError:
                page = StylePage(self.page2, xxx.className + ' style', xxx)
                self.stylePageCache[xxx.__class__] = page
            page.SetValues(xxx)
            self.pages.append(page)
            sizer.Add(page, 0, wxEXPAND)
            # Add page if not exists
            if not self.GetPageCount() == 2:
                self.AddPage(self.page2, 'Style')
            self.page2.Layout()
            if 'wxGTK' in wx.PlatformInfo:
                self.page2.Show(True)
            size = self.page2.GetSizer().GetMinSize()
            self.page2.SetScrollbars(1, 1, size.width, size.height, 0, 0, True)
        else:
            # Remove page if exists
            if self.GetPageCount() == 2:
                self.SetSelection(0)
                self.page1.Refresh()
                self.RemovePage(1)
        self.modified = False