[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