[Checkins] SVN: z3c.zodbbrowser/ initial upload of ZODBbrowser

Adam Groszer adamg at fw.hu
Sat Oct 28 05:54:05 EDT 2006


Log message for revision 70937:
  initial upload of ZODBbrowser

Changed:
  A   z3c.zodbbrowser/branches/
  A   z3c.zodbbrowser/sandbox/
  A   z3c.zodbbrowser/sandbox/src/
  A   z3c.zodbbrowser/sandbox/src/z3c/
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/MDIDemo.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/__init__.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/bases.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/main.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin1.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_fs.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_objdisp.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_tree.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/registry.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/treehandler.py
  A   z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/utils.py
  A   z3c.zodbbrowser/tags/

-=-
Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/MDIDemo.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/MDIDemo.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/MDIDemo.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,91 @@
+
+import  wx
+
+# Importing ScrolledWindow demo to make use of the MyCanvas 
+# class defined within.
+import  ScrolledWindow 
+import  images
+
+SHOW_BACKGROUND = 1
+
+#----------------------------------------------------------------------
+ID_New  = wx.NewId()
+ID_Exit = wx.NewId()
+#----------------------------------------------------------------------
+
+class MyParentFrame(wx.MDIParentFrame):
+    def __init__(self):
+        wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size=(600,400))
+
+        self.winCount = 0
+        menu = wx.Menu()
+        menu.Append(ID_New, "&New Window")
+        menu.AppendSeparator()
+        menu.Append(ID_Exit, "E&xit")
+
+        menubar = wx.MenuBar()
+        menubar.Append(menu, "&File")
+        self.SetMenuBar(menubar)
+
+        self.CreateStatusBar()
+
+        self.Bind(wx.EVT_MENU, self.OnNewWindow, id=ID_New)
+        self.Bind(wx.EVT_MENU, self.OnExit, id=ID_Exit)
+
+        if SHOW_BACKGROUND:
+            self.bg_bmp = images.getGridBGBitmap()
+            self.GetClientWindow().Bind(
+                wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground
+                )
+
+
+    def OnExit(self, evt):
+        self.Close(True)
+
+
+    def OnNewWindow(self, evt):
+        self.winCount = self.winCount + 1
+        win = wx.MDIChildFrame(self, -1, "Child Window: %d" % self.winCount)
+        canvas = ScrolledWindow.MyCanvas(win)
+        win.Show(True)
+
+
+    def OnEraseBackground(self, evt):
+        dc = evt.GetDC()
+
+        if not dc:
+            dc = wx.ClientDC(self.GetClientWindow())
+
+        # tile the background bitmap
+        sz = self.GetClientSize()
+        w = self.bg_bmp.GetWidth()
+        h = self.bg_bmp.GetHeight()
+        x = 0
+        
+        while x < sz.width:
+            y = 0
+
+            while y < sz.height:
+                dc.DrawBitmap(self.bg_bmp, x, y)
+                y = y + h
+
+            x = x + w
+
+
+#----------------------------------------------------------------------
+
+if __name__ == '__main__':
+    class MyApp(wx.App):
+        def OnInit(self):
+            wx.InitAllImageHandlers()
+            frame = MyParentFrame()
+            frame.Show(True)
+            self.SetTopWindow(frame)
+            return True
+
+
+    app = MyApp(False)
+    app.MainLoop()
+
+
+


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/MDIDemo.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/__init__.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/__init__.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/__init__.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+#
+# This file is necessary to make this directory a package.
+
+__version__ = "0.0.1"
+__license__ = "ZPL"
+__title__ = u"ZODB browser"
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/bases.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/bases.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/bases.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,145 @@
+# -*- coding: UTF-8 -*-
+
+from wax import *
+from z3c.zodbbrowser.registry import getObjectPlugin
+
+class oneProperty(object):
+    u"""Data holder for one object property
+    """
+    text = ''
+    type = None
+    expandable = False
+    data = None
+    
+    def __init__(self, **kw):
+        self.__dict__.update(kw)
+
+class dataCollector(object):
+    u"""Data holder for object properties
+    Kind of property bag
+    """
+    def __init__(self):
+        self._data=[]
+    
+    def add(self, text='', property=None):
+        u"""add one property of an object
+        the property will be inspected if it's expandable
+        """
+        plg = getObjectPlugin(text, property)
+        expandable = plg.getExpandable()
+        type = plg.getType()
+        
+        self.addLL(oneProperty(text = text,
+                    expandable = expandable,
+                    data=property,
+                    type=type))
+    
+    def addLL(self, obj):
+        u"""add one property of an object
+        no inspection done, just appended to the list
+        """
+        self._data.append(obj)
+    
+    def getAll(self):
+        u"""get all property data
+        """
+        return self._data
+
+class BaseObjectPlugin(object):
+    u"""Plugin base for object inspection
+    """
+    def __init__(self, context):
+        self.context = context
+    
+    def match(self, title):
+        u"""return True if the context object can
+        be handled by the current plugin
+        """
+        return False
+    
+    def getChildren(self):
+        u"""Get child objects of the context object
+        """
+        return dataCollector()
+    
+    def getProps(self):
+        u"""Get properties of the context object
+        """
+        return dataCollector()
+    
+    def getExpandable(self):
+        u"""Return if the object is expandable, has child somethings
+        """
+        return False
+    
+    def getType(self):
+        u"""return a type identifying the context object
+        """
+        return ''
+
+class BaseSourcePlugin(object):
+    u"""Plugin base for data source
+    """
+    def __init__(self, mainframe):
+        self.mainframe = mainframe
+    
+    def open(self, parent):
+        u"""open data source
+        the user should select what to open e.g. with a dialog
+        """
+        pass
+    
+    def close(self):
+        u"""close the opened data source
+        """
+        pass
+    
+    def getSupportedDisplays(self):
+        u"""get preferred/supported display modes of the data source
+        this/these will be looked up in the db_display registry for plugins
+        """
+        return []
+    
+    def getDataForDisplay(self, mode):
+        u"""get the data to be displayed
+        called by the display plugin
+        by the nature of the ZODB this is usually the root object
+        """
+        return None
+    
+    def getTitle(self):
+        u"""return a user-readable title for the display window
+        """
+        return ""
+
+class BaseDisplayPlugin(MDIChildFrame):
+    u"""Plugin base for data source display
+    """
+    
+    #window and plugin title
+    title = u''
+    
+    #def __init__(self, opener):
+    #gets the data source passed
+    #    pass
+
+class BaseObjDisplayPlugin(object):
+    u"""Plugin base for object display, used for right-click
+    """
+    
+    #shortcut menu title
+    title = u''
+    
+    def __init__(self, context, form):
+        self.context = context
+        self.form = form
+    
+    def getTitle(self):
+        u"""get the text that should be displayed on the context menu
+        """
+        return self.title
+    
+    def onClick(self):
+        u"""start processing
+        """
+        pass
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/bases.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/main.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/main.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/main.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,123 @@
+# -*- coding: UTF-8 -*-
+
+import os
+import sys
+import glob
+import wx
+
+try:
+    from wax import *
+    from wax.tools.choicedialog import ChoiceDialog
+except ImportError:
+    print "You do not have `wax` installed, please download it from http://sourceforge.net/projects/waxgui"
+
+twist_buttons=1
+
+from z3c.zodbbrowser import __title__
+from z3c.zodbbrowser.utils import *
+from z3c.zodbbrowser.registry import getSourcePlugins, getDBDisplayPlugins, installplugins
+from z3c.zodbbrowser.treehandler import rootHandler, baseHandler
+
+class ZODBFrame(MDIParentFrame):
+    
+    #def __init__(self):
+    #    super(ZODBFrame, self).__init__(size=(640,480))
+    #    self.SetSize((800, 600))
+    
+    def Body(self):
+        self.SetTitle(__title__)
+        
+        if WAX_VERSION_TUPLE < (0,3,33):
+            ShowMessage(__title__,
+                        "WARNING: wax version 0.3.33 required!")
+        
+        self.CreateStatusBar()
+        self.SetStatusText("This is the statusbar")
+        
+        menubar = MenuBar(self)
+
+        menu1 = Menu(self)
+        
+        opts = getSourcePlugins()
+        for title, ext, klass in opts:
+            menu1.Append("Open %s" % title,
+                         curry(self.menuOpen, klass),
+                         "This the text in the statusbar")
+            
+        #menu1.Append("&Open\tCTRL+O", self.menuOpen, "This the text in the statusbar")
+        menu1.Append("&Close", self.menuClose)
+        menu1.AppendSeparator()
+        menu1.Append("E&xit\tALT+X", self.menuExit, "Exit")
+        
+        menubar.Append(menu1, "&File")
+        
+        self.SetMenuBar(menubar)
+        
+        #self.Pack()
+        
+        #self.SetSize((800, 600))
+        #self.CenterOnScreen()
+    
+    def menuOpen(self, openerklass, event):
+        opener = openerklass(self)
+        if opener.open(self):
+            viewopts = opener.getSupportedDisplays()
+            
+            frameklasses = getDBDisplayPlugins(viewopts)
+            
+            klassindex = None
+            if len(frameklasses) == 0:
+                ShowMessage(__title__,
+                            "Happens that there is no display plugin for %s" % viewopts)
+            elif len(frameklasses) == 1:
+                klassindex = 0
+            else:
+                opts = [ii.title for ii in frameklasses]
+                dlg = ChoiceDialog(self,
+                                   title=__title__,
+                                   prompt="Choose an display method",
+                                   choices=opts)
+                try:
+                    result = dlg.ShowModal()
+                    if result == 'ok':
+                        klassindex = dlg.choice
+                finally:
+                    dlg.Destroy()
+            
+            if klassindex is not None:
+                frame = frameklasses[klassindex](parent=self,
+                                                 opener = opener)
+                frame.Show()
+    
+    def menuClose(self, event):
+        #self.Close()
+        while True:
+            chld = self.GetActiveChild()
+            brk()
+            if chld:
+                print 'close1'
+                chld.Close()
+            else:
+                break
+        pass
+    
+    def menuExit(self, event):
+        self.Destroy()
+
+class MyApp(wx.App):
+    def OnInit(self):
+        wx.InitAllImageHandlers()
+        frame = ZODBFrame()
+        frame.Show(True)
+        self.SetTopWindow(frame)
+        return True
+
+def main():
+    installplugins()
+    
+    app = Application(ZODBFrame)
+    #app = MyApp(False)
+    app.MainLoop()
+
+if __name__ == '__main__':
+    main()


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/main.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin1.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin1.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin1.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,141 @@
+# -*- coding: UTF-8 -*-
+
+#plugins for object inspection
+#object type determination may not be 100%
+
+import sys
+import copy
+from z3c.zodbbrowser.bases import dataCollector, BaseObjectPlugin
+from z3c.zodbbrowser.utils import *
+
+from ZODB.utils import oid_repr, serial_repr
+#force these attributes to be displayed
+forceAttr = [('_p_oid', oid_repr),('_p_serial',serial_repr)]
+
+class AnyObjectTypePlugin(BaseObjectPlugin):
+    u"""Plugin for any object type
+    this is the least specific plugin
+    also implements some base methods for more specific plugins
+    """
+    def match(self, title):
+        return True
+    
+    def getChildren(self):
+        return dataCollector()
+    
+    def getProps(self):
+        retval = dataCollector()
+        
+        try:
+            itemz = copy.copy(self.context.__dict__)
+            
+            for attr, formatter in forceAttr:
+                try:
+                    kdata = getattr(self.context, attr)
+                    
+                    if formatter:
+                        kdata=formatter(kdata)
+                        
+                    itemz[attr]=kdata
+                except:
+                    pass
+            
+            try:
+                keyz=itemz.keys()
+                keyz.sort()
+                for key in keyz:
+                    #if key.startswith('_'):
+                    #    continue
+                    #if key.startswith('__'):
+                    #    continue
+                    if key=='__parent__':
+                        continue
+                    kdata=itemz[key]
+                    
+                    retval.add(text = key, property=kdata)
+            except:
+                raise
+        except AttributeError:
+            pass
+        
+        return retval
+    
+    def getExpandable(self):
+        return False
+    
+    def getType(self):
+        try:
+            return self.context.__class__.__name__
+        except:
+            return str(type(self.context))
+
+class dictPlugin(AnyObjectTypePlugin):
+    u"""Plugin for dict or dict-alike object type
+    """
+    def match(self, title):
+        return isdict(self.context)
+    
+    def getChildren(self):
+        retval = dataCollector()
+        
+        keyz = self.context.keys()
+        try:
+            keyz.sort()
+        except:
+            try:
+                keyz=list(keyz)
+                keyz.sort()
+            except:
+                pass
+        
+        for key in keyz:
+            retval.add(text=safe_str(key), property=self.context[key])
+        
+        return retval
+    
+    def getExpandable(self):
+        return True
+    
+    def getType(self):
+        return 'dict'
+
+class listPlugin(AnyObjectTypePlugin):
+    u"""Plugin for list or list-alike object type
+    """
+    def match(self, title):
+        return islist(self.context)
+    
+    def getChildren(self):
+        retval = dataCollector()
+        
+        for d in self.context:
+            retval.add(text = safe_str(d), property=d)
+        
+        return retval
+    
+    def getExpandable(self):
+        return True
+    
+    def getType(self):
+        return 'list'
+
+class objectPlugin(AnyObjectTypePlugin):
+    u"""Plugin for `user-defined` object types
+    """
+    def match(self, title):
+        typ = str(type(self.context))
+        return '.' in typ
+    
+    def getExpandable(self):
+        return True
+    
+    def getType(self):
+        return 'obj'
+
+
+def main(PluginRegistry):
+    PluginRegistry['object'].extend([
+        (100,dictPlugin),
+        (200,listPlugin),
+        (sys.maxint-1, objectPlugin),
+        (sys.maxint, AnyObjectTypePlugin)])
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin1.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_fs.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_fs.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_fs.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,71 @@
+# -*- coding: UTF-8 -*-
+
+#plugin for ZODB FileStorage data source
+
+import transaction
+from ZODB import FileStorage, DB
+
+from wax import *
+from z3c.zodbbrowser.bases import BaseSourcePlugin
+
+class ZODBFSPlugin(BaseSourcePlugin):
+    storage = None
+    db = None
+    connection = None
+    root = None
+    filename = ""
+    
+    def open_direct(self, Path):
+        """Open ZODB.
+    
+        Returns a tuple consisting of:(root,connection,db,storage)
+        The same tuple must be passed to close_zodb() in order to close the DB.
+        """
+        # Connect to DB
+        self.storage     = FileStorage.FileStorage(Path)
+        self.db          = DB(self.storage)
+        self.connection  = self.db.open()
+        self.root        = self.connection.root()
+        
+        return True
+    
+    def open(self, parent):
+        dlg = FileDialog(parent, open=1)
+        try:
+            result = dlg.ShowModal()
+            if result == 'ok':
+                self.filename = dlg.GetPaths()[0]
+                return self.open_direct(self.filename)
+        finally:
+            dlg.Destroy()
+        
+        return False
+
+    def close(self):
+        """Closes the ZODB.
+    
+        This function MUST be called at the end of each program !!!
+        """
+        print "closed"
+        
+        transaction.abort()
+        
+        self.connection.close()
+        self.db.close()
+        self.storage.close()
+        self.filename = ""
+        
+        return True
+    
+    def getSupportedDisplays(self):
+        return ['tree']
+    
+    def getDataForDisplay(self, mode):
+        return self.root
+    
+    def getTitle(self):
+        return self.filename
+
+def main(PluginRegistry):
+    PluginRegistry['source'].extend([
+        ('FileStorage','fs',ZODBFSPlugin)])
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_fs.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_objdisp.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_objdisp.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_objdisp.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,19 @@
+# -*- coding: UTF-8 -*-
+
+#plugin for object display
+#currently this is just for fun
+
+from wax import *
+
+from z3c.zodbbrowser.bases import BaseObjDisplayPlugin
+
+class dictDispPlugin(BaseObjDisplayPlugin):
+    title = u'dict details'
+    
+    def onClick(self):
+        dlg = MessageDialog(self.form, "A message", "dict details")
+        dlg.ShowModal()
+        dlg.Destroy()
+
+def main(PluginRegistry):
+    PluginRegistry['obj_display'].append(('dict',dictDispPlugin))
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_objdisp.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_tree.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_tree.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_tree.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,114 @@
+# -*- coding: UTF-8 -*-
+
+#plugin for object source display
+
+import wx
+from wax import *
+from z3c.zodbbrowser.bases import BaseDisplayPlugin
+twist_buttons=1
+
+from treehandler import rootHandler, baseHandler
+
+class TreeDisplay(BaseDisplayPlugin):
+    """
+    MDIChildFrame - MDI parent formba helyezhető
+    """
+    
+    #window title
+    title = u"tree"
+    
+    def __init__(self, *arg, **kw):
+        kw['direction'] = 'v'
+        self.opener = kw.pop('opener')
+        self.root = self.opener.getDataForDisplay('tree')
+        
+        super(TreeDisplay, self).__init__(*arg, **kw)
+
+    def Body(self):
+        """form layout setup
+        tree on the left side
+        one big textbox on the right side
+        """
+        self.SetTitle(self.title+" - "+self.opener.getTitle())
+        
+        splitter = Splitter(self, size=(500, 300))
+        self.tree = TreeView(splitter, twist_buttons=twist_buttons, has_buttons=1)
+        self.tree.OnItemExpanded = self.OnItemExpanded
+        self.tree.OnSelectionChanged = self.OnTreeSelectionChanged
+        self.tree.OnRightDown = self.OnItemRightClick
+        
+        self.textbox = TextBox(splitter, readonly=1, multiline=1)
+        splitter.Split(self.tree, self.textbox, direction='v')
+        self.AddComponent(splitter, expand='both')
+        
+        self.filltree()
+        self.Pack()
+        
+        #w=-1
+        #h=self.GetParent().GetClientSizeTuple()[1]
+        #self.SetSizeWH(-1,h)
+        
+        self.SetSize(self.GetParent().GetClientSizeTuple())
+        
+    def addItem(self, text, data, item = None):
+        if item:
+            child = self.tree.AppendItem(item, text)
+        else:
+            child = self.tree.AddRoot(text)
+        
+        data.loadedChild = False
+        self.tree.SetPyData(child, data)
+        if data.expandable:
+            dummy = self.tree.AppendItem(child, "##expand##")
+    
+    def filltree(self):
+        zz = rootHandler(self.root, 'root', self)
+        self.addItem("root", zz)
+    
+    def OnItemExpanded(self, event):
+        item = event.GetItem()
+        if item:
+            idata = self.tree.GetPyData(item)
+            if isinstance(idata, baseHandler):
+                if not idata.loadedChild:
+                    idata.loadedChild = True
+                    self.tree.DeleteChildren(item)
+                    children = idata.getChildren()
+                    for key, data in children:
+                        self.addItem(key, data, item)
+                idata.onExpanded()
+    
+    def OnTreeSelectionChanged(self, event):
+        item = event.GetItem()
+        if item:
+            data = self.tree.GetPyData(item)
+            if isinstance(data, baseHandler):
+                data.onSelected()
+            if data is None:
+                data = self.tree.GetItemText(item)
+        
+        #print str(data)
+        #event.Skip()
+    
+    def OnItemRightClick(self, event):
+        #item = event.GetItem()
+        item, flags = self.tree.HitTest(event.GetPosition())
+        if flags in [wx.TREE_HITTEST_ONITEMBUTTON, wx.TREE_HITTEST_ONITEMLABEL]:
+            data = self.tree.GetPyData(item)
+            if isinstance(data, baseHandler):
+                self.tree.SelectItem(item)
+                data.onRightClick()
+        
+    def setProps(self, data):
+        u"""Write the data--information into the textbox"""
+        self.textbox.SetValue(data['text'])
+    
+    def closeDB(self):
+        self.opener.close()
+    
+    def OnClose(self, event):
+        self.closeDB()
+        event.Skip()
+
+def main(PluginRegistry):
+    PluginRegistry['db_display']['tree']=TreeDisplay


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/plugin_tree.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/registry.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/registry.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/registry.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,125 @@
+# -*- coding: UTF-8 -*-
+
+#plugin registry and support methods
+
+import imp
+import sys
+import os
+import glob
+
+#plugin registry
+PluginRegistry = {}
+
+#object inspector plugin registry
+#format is: [(importance or specificity, pluginClass)]
+#importance is an integer, plugins get checked in the order of this
+#so AnyObjectTypePlugin should be sys.maxint
+#the more specific the plugin is the less this number should be
+PluginRegistry['object']=[]
+
+#data source plugin registry
+#format is: [("plugin title", "extension", pluginClass)]
+#contents will be put on the menu File/Open <plugin title>
+PluginRegistry['source']=[]
+
+#data source display plugin registry
+#format is: {"plugin name":pluginClass}
+#the data source plugin can define which displays it 'likes'
+PluginRegistry['db_display']={}
+
+#object display plugin registry
+#these plugins are checked when the user right-clicks in the tree? on any object
+#plugins matching by type will be displayed in a shortcut menu
+#format is: [("object type", pluginClass)]
+#object type can be "*", then the plugin applies for all types
+#with the "*" a kind of 'open new window from here...' could be implemented
+PluginRegistry['obj_display']=[]
+
+def getObjectPlugin(text, obj):
+    u"""get one matching plugin for the object
+    checks lowest priority first"""
+    for prio, plugin in PluginRegistry['object']:
+        plg = plugin(obj)
+        if plg.match(text):
+            return plg
+    
+    return None
+
+def getSourcePlugins():
+    u"""return source plugin list"""
+    return PluginRegistry['source']
+
+def getDBDisplayPlugins(types):
+    u"""get display plugins according to types list"""
+    matches = []
+    for type in types:
+        try:
+            matches.append(PluginRegistry['db_display'][type])
+        except KeyError:
+            print "No plugin found for display '%s'" % type
+    return matches
+
+def getDisplayPlugins(objtype):
+    u"""get object display plugins for an object type"""
+    matches = [pluginklass
+               for type, pluginklass in PluginRegistry['obj_display']
+               if (type == objtype) or (type == '*')]
+    return matches
+
+def impmain(fname):
+    u"""import main from a given .py file"""
+    mname = os.path.splitext(fname)[0]
+    mpath, mname = os.path.split(mname)
+    oname = 'main'
+        
+    try:
+        x=imp.find_module(mname, [mpath])
+        try:
+            mod=imp.load_module('plugin1',x[0],x[1],x[2])
+        finally:
+            x[0].close()
+    except ImportError, v:
+        raise ValueError(
+            "Couldn't import %s, %s" % (mname, v)), None, sys.exc_info()[2]
+    
+    try:
+        obj = getattr(mod, oname)
+        return obj
+    except AttributeError:
+        # No such name, maybe it's a module that we still need to import
+        #try:
+        #    return __import__(mname+'.'+oname, *_import_chickens)
+        #except ImportError:
+        #
+        # We need to try to figure out what module the import
+        # error is complaining about.  If the import failed
+        # due to a failure to import some other module
+        # imported by the module we are importing, we want to
+        # know it. Unfortunately, the value of the import
+        # error is just a string error message. :( We can't
+        # pull it apart directly to see what module couldn't
+        # be imported. The only thing we can really do is to
+        # try to "screen scrape" the error message:
+
+        if str(sys.exc_info()[1]).find(oname) < 0:
+            # There seems to have been an error further down,
+            # so reraise the exception so as not to hide it.
+            raise
+
+        raise ValueError(
+            "ImportError: Module %s has no global %s" % (mname, oname)) 
+
+def installplugins():
+    u"""import and start the main() of each plugin_*.py
+    in the folder of our source
+    these should register/can register any plugin
+    through the passed PluginRegistry parameter"""
+    
+    here = os.path.abspath(os.path.dirname(sys.argv[0]))
+    plugins = glob.glob(os.path.join(here, "plugin*.py"))
+    
+    for plg in plugins:
+        plgmain = impmain(plg)
+        plgmain(PluginRegistry)
+    
+    PluginRegistry['object'].sort()
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/registry.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/treehandler.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/treehandler.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/treehandler.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,141 @@
+# -*- coding: UTF-8 -*-
+
+#tree handler for plugin_tree
+
+from wax import *
+
+from z3c.zodbbrowser.registry import getObjectPlugin, getDisplayPlugins
+from z3c.zodbbrowser.utils import *
+
+class baseHandler(object):
+    """ """
+    
+    expandable = False
+    
+    def __init__(self, context, text, form):
+        self.context = context
+        self.form = form
+        self.text = text
+        self.plugin = getObjectPlugin(text, context)
+    
+    def onRightClick(self):
+        type = self.plugin.getType()
+        plugins = getDisplayPlugins(type)
+        
+        if plugins:
+            menu = Menu(self.form)
+            
+            for pluginklass in plugins:
+                plugin = pluginklass(self.context, self.form)
+                # these entries are always present
+                menu.Append(plugin.getTitle(), curry(self.onPopupMenu, plugin))
+    
+            self.form.PopupMenu(menu)
+            #menu.Destroy()  # ...why?
+            #core.wx.GetApp().ProcessIdle()   # ...?
+    
+    def onPopupMenu(self, itemplugin, event):
+        print itemplugin.getTitle()
+        itemplugin.onClick()
+
+class leafHandler(baseHandler):
+    #def __init__(self, context):
+    #    self.context = context
+    
+    def onSelected(self):
+        #print "leaf selected"
+        props = self.plugin.getProps()
+        out = ["%s (%s) = %s" % (prop.text, prop.type, safe_str(prop.data))
+               for prop in props.getAll()]
+        
+        typ = safe_str(type(self.context))
+        id = safe_str(self.context)
+        doc=''
+        try:
+            doc = self.context.__doc__
+        except:
+            pass
+        head = """Type: %s
+-------------
+ID: %s
+-------------
+__doc__: %s
+=============
+""" % (typ, id, doc)
+        
+        data={'text':head+'\n'.join(out)}
+        self.form.setProps(data)
+    
+    #def onRightClick(self):
+    #    print "leaf onRightClick"
+    
+    def onExpanded(self):
+        #print "leaf expanded"
+        pass
+    
+    def getChildren(self):
+        return None
+
+class containerHandler(leafHandler):
+    expandable = True
+    
+    #def __init__(self, context):
+    #    self.context = context
+    
+    #def onSelected(self):
+    #    print "container selected"
+    #    props = self.plugin.getProps(self.context)
+    #    out = ["%s (%s) = %s" % (prop.text, prop.type, safe_str(prop.data)) for prop in props.getAll()]
+    #        
+    #    data={'text':'\n'.join(out)}
+    #    self.form.setProps(data)
+    
+    #def onRightClick(self):
+    #    print "container onRightClick"
+    
+    def onExpanded(self):
+        #print "container expanded"
+        pass
+    
+    def getChildren(self):
+        items = []
+        kids = self.plugin.getChildren()
+        
+        props = self.plugin.getProps()
+        for prop in props.getAll():
+            if prop.expandable:
+                kids.addLL(prop)
+        
+        for kid in kids.getAll():
+            if kid.expandable:
+                #expandable
+                handler = containerHandler(kid.data, kid.text, self.form)
+            else:
+                handler = leafHandler(kid.data, kid.text, self.form)
+            
+            items.append(("%s (%s)" %(kid.text, kid.type), handler))
+                
+        return items
+
+class rootHandler(containerHandler):
+    expandable = True
+    
+    #def __init__(self, context, form):
+    #    self.context = context
+    #    self.form = form
+    
+    def onSelected(self):
+        #print "root selected"
+        data={'text':''}
+        self.form.setProps(data)
+    
+    #def onRightClick(self):
+    #    print "root onRightClick"
+    
+    def onExpanded(self):
+        #print "root expanded"
+        pass
+    
+    #def getChildren(self):
+    #    items = [(key, containerHandler(obj)) for key,obj in LogicRegistry().items()]
+    #    return items


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/treehandler.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/utils.py
===================================================================
--- z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/utils.py	2006-10-28 09:45:20 UTC (rev 70936)
+++ z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/utils.py	2006-10-28 09:54:02 UTC (rev 70937)
@@ -0,0 +1,70 @@
+# -*- coding: UTF-8 -*-
+
+#support functions
+
+import string
+
+def islist(data):
+    u"""is the parameter list-like?"""
+    try:
+        data[0]
+        return not isinstance(data, basestring)
+    except:
+        return False
+
+
+def isdict(data):
+    u"""is the parameter dict-like?"""
+    try:
+        data.keys()
+        #BTree miatt nem kene isinstance
+        return True
+    except:
+        return False
+
+class Translator:
+    u"""character translator"""
+    
+    allchars = string.maketrans('','')
+    def __init__(self, frm='', to='', delete='', keep=None):
+        if len(to) == 1:
+            to = to * len(frm)
+        self.trans = string.maketrans(frm, to)
+        if keep is None:
+            self.delete = delete
+        else:
+            self.delete = self.allchars.translate(self.allchars, keep.translate(self.allchars, delete))
+    def __call__(self, s):
+        return s.translate(self.trans, self.delete)
+
+keepPrintableTrans = Translator(keep=string.printable)
+
+def safe_str(uncode):
+    u"""unicode and any-character safe str()"""
+    
+    if not isinstance(uncode, basestring):
+        uncode = unicode(uncode)
+    try:
+        x=uncode.encode('ascii','replace')
+    except UnicodeDecodeError:
+        uncode = keepPrintableTrans(uncode)
+        x=uncode.encode('ascii','replace')
+    return x
+
+class curry:
+    """Taken from the Python Cookbook, this class provides an easy way to
+    tie up a function with some default parameters and call it later.
+    See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 for more.
+    """
+    def __init__(self, func, *args, **kwargs):
+        self.func = func
+        self.pending = args[:]
+        self.kwargs = kwargs
+
+    def __call__(self, *args, **kwargs):
+        if kwargs and self.kwargs:
+            kw = self.kwargs.copy()
+            kw.update(kwargs)
+        else:
+            kw = kwargs or self.kwargs
+        return self.func(*(self.pending + args), **kw)
\ No newline at end of file


Property changes on: z3c.zodbbrowser/sandbox/src/z3c/zodbbrowser/utils.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native



More information about the Checkins mailing list