[z3-checkins] r14801 - in z3/zopejam/trunk/src: zcmledit zopejam
hathawsh at codespeak.net
hathawsh at codespeak.net
Wed Jul 20 09:09:26 CEST 2005
Author: hathawsh
Date: Wed Jul 20 09:09:21 2005
New Revision: 14801
Modified:
z3/zopejam/trunk/src/zcmledit/configfile.py
z3/zopejam/trunk/src/zcmledit/directives.py
z3/zopejam/trunk/src/zcmledit/inspector.py
z3/zopejam/trunk/src/zcmledit/project.py
z3/zopejam/trunk/src/zopejam/columns.py
z3/zopejam/trunk/src/zopejam/main.py
z3/zopejam/trunk/src/zopejam/propbook.py
Log:
When multiple directives are selected, show an editable grid widget.
Also reformatted some code in the zcmledit package.
Modified: z3/zopejam/trunk/src/zcmledit/configfile.py
==============================================================================
--- z3/zopejam/trunk/src/zcmledit/configfile.py (original)
+++ z3/zopejam/trunk/src/zcmledit/configfile.py Wed Jul 20 09:09:21 2005
@@ -18,8 +18,8 @@
from zcmledit import interfaces
-ZCML_CONDITION = (u"http://namespaces.zope.org/zcml", u"condition")
-XMLNS_NS = u"http://www.w3.org/2000/xmlns/" # URI for XML NS declarations
+zcml_condition = (u"http://namespaces.zope.org/zcml", u"condition")
+xmlns_ns = u"http://www.w3.org/2000/xmlns/" # URI for XML NS declarations
class ConfigurationFile:
@@ -81,18 +81,19 @@
def createDirective(self, element):
"""Returns an IDirective to fit an XML element"""
ns, localname = element.name
- if localname == 'configure':
- return directives.ConfigureDirective(element, self.package_name)
-
- if localname in ('include', 'includeOverrides'):
- return directives.IncludeDirective(element, self.project)
- if ns == directives.META_NS and localname in (
+ if localname == 'configure':
+ t = directives.ConfigureDirective
+ elif localname in ('include', 'includeOverrides'):
+ t = directives.IncludeDirective
+ elif ns == directives.meta_ns and localname in (
'directive', 'groupingDirective',
'complexDirective', 'simpleDirective'):
- return directives.DefinitionDirective(element)
+ t = directives.DefinitionDirective
+ else:
+ t = directives.CommonDirective
- return directives.CommonDirective(element)
+ return t(element)
def generateXML(self):
@@ -140,35 +141,6 @@
self.directive = None
-## # Collect information from certain XML attributes
-## self._generic_ns = False
-## ns, localname = name
-## if localname == 'configure':
-## # This directive can modify the context package name
-## self._generic_ns = True
-## p = data.get('package')
-## if p:
-## p = p.strip()
-## else:
-## p = None
-## self._package_name = p
-
-## if localname in ('include', 'includeOverrides'):
-## self._generic_ns = True
-## self._is_include = True
-## else:
-## self._is_include = False
-
-## if ns == META_NS and localname in (
-## 'directive', 'groupingDirective',
-## 'complexDirective', 'simpleDirective'):
-## self._is_definition = True
-## else:
-## self._is_definition = False
-
-## def setPackageName(self, package_name):
-## self._package_name = package_name
-
def flattened(self):
"""Returns a list containing this directive and all descendants.
"""
@@ -177,47 +149,11 @@
res.extend(e.flattened())
return res
-## def getAbsolutePackageName(self):
-## """Returns the absolute package name in context of this directive.
-
-## Used for resolving relative package names.
-## """
-## my_pn = self._package_name
-## if not my_pn:
-## # inherit
-## elem = self.parent
-## while elem is not None:
-## if elem._package_name:
-## return elem.getAbsolutePackageName()
-## elem = elem.parent
-## raise NoPackageError("No absolute package has been set")
-## elif not my_pn.startswith('.'):
-## return my_pn
-
-## # my_pn is relative, so resolve it.
-## if self.parent is not None:
-## parent_pn = self.parent.getAbsolutePackageName()
-## else:
-## raise NoPackageError("No absolute package has been set")
-## return join_package(parent_pn, my_pn)
-
-## def isInGenericNamespace(self):
-## """Returns True if this directive is in the generic (*) namespace"""
-## return self._generic_ns
-
-## def isInclude(self):
-## """Returns True if this is an include directive"""
-## return self._is_include
-
-## def isDefinition(self):
-## """Returns True if this directive defines a directive type"""
-## return self._is_definition
-
def getXMLName(self, ns, localname):
"""Returns the tag or attribute for a given namespace and localname"""
if not ns:
return localname
- if ns == XMLNS_NS:
+ if ns == xmlns_ns:
if localname:
return u'xmlns:%s' % localname
else:
@@ -254,12 +190,12 @@
out_attrs[(u'', key)] = value
for prefix, uri in self.prefix_uri.items():
if not prefix:
- key = XMLNS_NS, ''
+ key = xmlns_ns, ''
else:
- key = XMLNS_NS, prefix
+ key = xmlns_ns, prefix
out_attrs[key] = uri
if self.condition:
- out_attrs[ZCML_CONDITION] = self.condition
+ out_attrs[zcml_condition] = self.condition
if not out_attrs:
line = u'%s<%s%s' % (indent, tag_name, tag_end)
@@ -359,7 +295,7 @@
items = pm.items()
items.sort()
for prefix, uri in items:
- attr_order.append((XMLNS_NS, prefix))
+ attr_order.append((xmlns_ns, prefix))
# attrs is a list of alternating names and values.
# gather its contents, preserving the attribute order.
@@ -373,7 +309,7 @@
attr_order.append(key)
ns, localname = key
- if key == ZCML_CONDITION:
+ if key == zcml_condition:
condition = value
elif not ns or ns == name[0]:
data[localname] = value
Modified: z3/zopejam/trunk/src/zcmledit/directives.py
==============================================================================
--- z3/zopejam/trunk/src/zcmledit/directives.py (original)
+++ z3/zopejam/trunk/src/zcmledit/directives.py Wed Jul 20 09:09:21 2005
@@ -1,4 +1,9 @@
+# (c) 2005 Shane Hathaway
+# License: ZPL 2.1
+
+"""Partially interpreted configuration directives"""
+
from glob import glob
import os
@@ -8,7 +13,7 @@
from zcmledit.exceptions import NameResolutionError, NoPackageError
from zcmledit.exceptions import InvalidRelativeNameError, MissingPackageError
-META_NS = u"http://namespaces.zope.org/meta"
+meta_ns = u"http://namespaces.zope.org/meta"
class Directive(object):
@@ -17,6 +22,10 @@
self.element = element
self.errors = []
self._abs_package = None
+ self.readElement()
+
+ def readElement(self):
+ pass
def getInheritedPackageName(self):
ancestor = self.element.parent
@@ -53,23 +62,27 @@
return self._abs_package
return self.getInheritedPackageName()
+ def getType(self):
+ """Returns an IDefinitionDirective or None"""
+ project = self.element.config_file.project
+ if interfaces.IGenericNamespaceDirective.providedBy(self):
+ ns, localname = self.element.name
+ return project.definitions.get(('*', localname))
+ else:
+ return project.definitions.get(self.element.name)
+
class ConfigureDirective(Directive):
implements(interfaces.IConfigureDirective)
- def __init__(self, element, config_file_package=None):
- Directive.__init__(self, element)
- self.config_file_package = config_file_package
- self.update()
-
- def update(self):
+ def readElement(self):
self.errors = []
self.package = self.element.data.get('package')
self.setAbsolutePackage(self.package)
def getInheritedPackageName(self):
if self.element.parent is None:
- return self.config_file_package
+ return self.element.config_file.package_name
else:
return Directive.getInheritedPackageName(self)
@@ -81,12 +94,7 @@
"""
implements(interfaces.IIncludeDirective)
- def __init__(self, element, project):
- Directive.__init__(self, element)
- self.project = project
- self.update()
-
- def update(self):
+ def readElement(self):
"""Read the directive element and prepare the filename pattern.
The constructor calls this method, but it can be called again
@@ -118,9 +126,9 @@
# convert to an absolute path
abs_package = self.getAbsolutePackageName()
if abs_package:
+ pythonpath = element.config_file.project.pythonpath
try:
- basepath = find_package(
- abs_package, self.project.pythonpath)
+ basepath = find_package(abs_package, pythonpath)
except NameResolutionError, e:
basepath = None
self.errors.append(
@@ -153,11 +161,7 @@
"""A directive that defines other directives"""
implements(interfaces.IDefinitionDirective)
- def __init__(self, element):
- Directive.__init__(self, element)
- self.update()
-
- def update(self):
+ def readElement(self):
self.errors = []
self.name = self.element.data.get('name')
self.schema = self.element.data.get('schema')
@@ -165,7 +169,7 @@
ns = None
parent = self.element.parent
while parent is not None:
- if parent.name == (META_NS, 'directives'):
+ if parent.name == (meta_ns, 'directives'):
# use the namespace inherited from a 'directives' directive
ns = parent.data['namespace']
break
@@ -189,6 +193,34 @@
self.errors.append("Missing 'schema' attribute")
self.abs_schema = abs_schema
+ def getSchemaInfo(self):
+ project = self.element.config_file.project
+ return project.interfaces[self.abs_schema]
+
+
+class BootstrapDirective(Directive):
+ """A bootstrap definition directive.
+
+ Not defined in any configuration file.
+ """
+ implements(interfaces.IDefinitionDirective)
+
+ def __init__(self, project, ns, name, abs_schema):
+ self.project = project
+ self.element = None
+ self.errors = ()
+
+ self.name = name
+ self.fullname = (ns, name)
+ self.schema = abs_schema
+ self.abs_schema = abs_schema
+
+ def getAbsolutePackageName(self):
+ return None
+
+ def getSchemaInfo(self):
+ return self.project.interfaces[self.abs_schema]
+
class CommonDirective(Directive):
implements(interfaces.IDirective)
@@ -253,49 +285,3 @@
msg += (" (Directory '%s' is a candidate, but one "
"or more '__init__.py' files are required.)" % candidate)
raise MissingPackageError(msg)
-
-
-class BootstrapDirective(Directive):
- """A bootstrap definition directive.
-
- Not defined in any configuration file.
- """
- implements(interfaces.IDefinitionDirective)
-
- def __init__(self, ns, name, abs_schema):
- self.element = None
- self.errors = ()
-
- self.name = name
- self.fullname = (ns, name)
- self.schema = abs_schema
- self.abs_schema = abs_schema
-
- def getAbsolutePackageName(self):
- return None
-
-
-def createBootstrapDirectives():
- """Returns a dictionary containing the bootstrap directive definitions"""
- res = {}
- for ns, name, schema in [
- ('*', 'configure', "zope.configuration.zopeconfigure.IZopeConfigure"),
- ('*', 'include', "zope.configuration.xmlconfig.IInclude"),
- ('*', 'includeOverride', "zope.configuration.xmlconfig.IInclude"),
- (META_NS, 'directive',
- "zope.configuration.config.IFullInfo"),
- (META_NS, 'groupingDirective',
- "zope.configuration.config.IFullInfo"),
- (META_NS, 'directives',
- "zope.configuration.config.IDirectivesInfo"),
- (META_NS, 'complexDirective',
- "zope.configuration.config.IFullInfo"),
- (META_NS, 'subdirective',
- "zope.configuration.config.IDirectiveInfo"),
- (META_NS, 'provides',
- "zope.configuration.config.IProvidesDirectiveInfo"),
- ]:
- res[(ns, name)] = BootstrapDirective(ns, name, schema)
- return res
-
-
Modified: z3/zopejam/trunk/src/zcmledit/inspector.py
==============================================================================
--- z3/zopejam/trunk/src/zcmledit/inspector.py (original)
+++ z3/zopejam/trunk/src/zcmledit/inspector.py Wed Jul 20 09:09:21 2005
@@ -20,7 +20,7 @@
def inspect_interfaces(names):
- """Returns {name: {'doc', 'bases', 'attrs' | 'error'}}"""
+ """Returns {name: {'doc', 'bases', 'sro', 'attrs' | 'error'}}"""
res = {}
# the names are absolute.
todo = list(names)
@@ -48,6 +48,8 @@
if IInterface.providedBy(obj):
info['doc'] = getattr(obj, '__doc__', None)
+
+ # report base interfaces
bases = []
for base in getattr(obj, '__bases__', ()):
m = getattr(base, '__module__', None)
@@ -58,6 +60,17 @@
if not res.has_key(fullname):
todo.append(fullname)
info['bases'] = bases
+
+ # report specification resolution order
+ sro = []
+ for base in getattr(obj, '__sro__', ()):
+ m = getattr(base, '__module__', None)
+ n = getattr(base, '__name__', None)
+ if m and n:
+ fullname = '%s.%s' % (m, n)
+ sro.append(fullname)
+ info['sro'] = sro
+
attrs = {}
for n in obj.names(False):
attrs[n] = obj[n]
Modified: z3/zopejam/trunk/src/zcmledit/project.py
==============================================================================
--- z3/zopejam/trunk/src/zcmledit/project.py (original)
+++ z3/zopejam/trunk/src/zcmledit/project.py Wed Jul 20 09:09:21 2005
@@ -11,6 +11,7 @@
import sys
from zope.interface import implements
+from zope.schema.interfaces import IField
from zcmledit import interfaces
from zcmledit.configfile import ConfigurationFile
@@ -32,11 +33,37 @@
pythonpath = [os.path.join(self.base, 'src')] + sys.path
self.pythonpath = pythonpath
+ def createBootstrapDirectives(self):
+ """Returns a dictionary containing the bootstrap definitions"""
+ res = {}
+ meta_ns = directives.meta_ns
+ for ns, name, schema in [
+ ('*', 'configure',
+ "zope.configuration.zopeconfigure.IZopeConfigure"),
+ ('*', 'include', "zope.configuration.xmlconfig.IInclude"),
+ ('*', 'includeOverride', "zope.configuration.xmlconfig.IInclude"),
+ (meta_ns, 'directive',
+ "zope.configuration.config.IFullInfo"),
+ (meta_ns, 'groupingDirective',
+ "zope.configuration.config.IFullInfo"),
+ (meta_ns, 'directives',
+ "zope.configuration.config.IDirectivesInfo"),
+ (meta_ns, 'complexDirective',
+ "zope.configuration.config.IFullInfo"),
+ (meta_ns, 'subdirective',
+ "zope.configuration.config.IDirectiveInfo"),
+ (meta_ns, 'provides',
+ "zope.configuration.config.IProvidesDirectiveInfo"),
+ ]:
+ res[(ns, name)] = directives.BootstrapDirective(
+ self, ns, name, schema)
+ return res
+
def load(self):
self.packages = {} # {package name: [filename]}
self.files = {} # {filename: config_file}
# self.definitions contains {(ns, localname): IDirectiveDefinition}
- self.definitions = directives.createBootstrapDirectives()
+ self.definitions = self.createBootstrapDirectives()
self.root_config = ConfigurationFile(self, self.root_filename)
self.files[self.root_filename] = self.root_config
@@ -68,9 +95,16 @@
"directive %s" % repr(dfn.fullname))
self.definitions[dfn.fullname] = dfn
- # load schemas
+ self.load_schemas()
+
+ def load_schemas(self):
names = [dfn.abs_schema for dfn in self.definitions.values()]
- self.schemas = self.call_inspector('inspect_interfaces', names)
+ d = self.call_inspector('inspect_interfaces', names)
+ self.interfaces = {}
+ for name, info in d.items():
+ self.interfaces[name] = InterfaceInfo(name, info)
+ for info in self.interfaces.values():
+ info.initBases(self.interfaces)
def call_inspector(self, funcname, *args, **kw):
inspector_py = os.path.join(here, 'inspector.py')
@@ -93,10 +127,8 @@
def print_fields(self):
"""Shows reuse of fields by different directive types."""
fields = {} # {(field_name, field_type) -> [schema_name]}
- for schema_name, info in self.schemas.items():
- if not info.has_key('attributes'):
- continue
- for attr_name, obj in info['attributes'].items():
+ for schema_name, info in self.interfaces.items():
+ for attr_name, obj in info.attributes.items():
if not IField.providedBy(obj):
continue
key = (attr_name, type(obj))
@@ -114,3 +146,37 @@
if len(p) > len_base and p[len_base] == os.sep:
return p[len_base + 1:]
return p
+
+
+class InterfaceInfo:
+ """Contains info received from inspector.inspect_interfaces()."""
+
+ def __init__(self, name, info):
+ self.name = name
+ self.error = info.get('error', '')
+ self.doc = info.get('doc', '')
+ self.base_names = info.get('bases', ())
+ self.sro_names = info.get('sro', ())
+ self.attributes = info.get('attributes')
+ if self.attributes is None:
+ self.attributes = {}
+ self.fields = {}
+ for k, v in self.attributes.items():
+ if IField.providedBy(v):
+ self.fields[k] = v
+
+ def initBases(self, all_interfaces):
+ """As part of construction, link with base InterfaceInfo objects."""
+ self.bases = [all_interfaces[name] for name in self.base_names]
+ self.sro = [all_interfaces[name] for name in self.sro_names]
+
+ def getField(self, k):
+ v = self.fields.get(k)
+ if v is not None:
+ return v
+ for info in self.sro:
+ v = info.fields.get(k)
+ if v is not None:
+ return v
+ return None
+
Modified: z3/zopejam/trunk/src/zopejam/columns.py
==============================================================================
--- z3/zopejam/trunk/src/zopejam/columns.py (original)
+++ z3/zopejam/trunk/src/zopejam/columns.py Wed Jul 20 09:09:21 2005
@@ -18,8 +18,11 @@
default_width = 100
indent = False
- def setProject(self, project):
- self.project = project
+ def getLabel(self):
+ return self.label
+
+ def getDefaultWidth(self):
+ return self.default_width
def getText(self, d):
return ''
@@ -27,6 +30,10 @@
def getSortKey(self, d):
return self.getText(d)
+ def getFlags(self, d):
+ """Returns (valid, editable, has_error)."""
+ return (True, False, False)
+
def resolve(self, d, name):
"""Tries to resolve a package name,
@@ -58,8 +65,8 @@
text = cfg.package_name
else:
text = '%s "%s"' % (cfg.package_name, basename)
- elif self.project is not None:
- text = '"%s"' % self.project.shortenPath(cfg.filename)
+ elif cfg.project is not None:
+ text = '"%s"' % cfg.project.shortenPath(cfg.filename)
else:
text = '"%s"' % cfg.filename
return text
@@ -94,23 +101,6 @@
def getText(self, d):
data = d.element.data
-
-## if interfaces.IIncludeDirective.providedBy(d):
-## fn = data.get('files') or data.get('file') or 'configure.zcml'
-## package = data.get('package') or '.'
-## if package:
-## abs_package, error = self.resolve(d, package)
-## if error:
-## abs_package = '??? %s' % package
-## if abs_package:
-## if fn == 'configure.zcml':
-## label = abs_package
-## else:
-## label = '%s "%s"' % (abs_package, fn)
-## else:
-## label = '"%s"' % fn
-## return label
-
res = data.get('name')
if res is None:
res = data.get('id', '')
@@ -145,18 +135,33 @@
return self.getText(d, mark_inherited=False)
-class File(Column):
- label = 'File'
- default_width = 80
+class SchemaAttribute(Column):
+ default_width = 100
+
+ def __init__(self, schema_attr):
+ self.schema_attr = schema_attr
+ if self.schema_attr.endswith('_'):
+ self.xml_attr = self.schema_attr[:-1]
+ else:
+ self.xml_attr = self.schema_attr
+
+ def getLabel(self):
+ return self.xml_attr
def getText(self, d):
data = d.element.data
- name = data.get('file')
- if name is None:
- name = data.get('template')
- if name is None:
- name = data.get('page')
- return name or ''
+ return data.get(self.xml_attr, '')
+
+ def getFlags(self, d):
+ """Returns (valid, editable, has_error)."""
+ t = d.getType()
+ valid = False
+ if t is not None:
+ info = t.getSchemaInfo()
+ f = info.getField(self.schema_attr)
+ if f is not None:
+ valid = True
+ return (valid, valid, False)
def create_default_columns():
@@ -166,9 +171,3 @@
NameOrId(),
FactoryClassOrObject(),
]
-## For(),
-## Provides(),
-## Permission(),
-## InterfaceColumn(),
-## File(),
-## ]
Modified: z3/zopejam/trunk/src/zopejam/main.py
==============================================================================
--- z3/zopejam/trunk/src/zopejam/main.py (original)
+++ z3/zopejam/trunk/src/zopejam/main.py Wed Jul 20 09:09:21 2005
@@ -362,13 +362,13 @@
return
dfn = self.project.definitions[fullname]
- schema_info = self.project.schemas.get(dfn.abs_schema)
- if schema_info.get('error'):
+ info = dfn.getSchemaInfo()
+ if info.error:
doc = ('An error occurred while loading the '
- 'schema for this directive: %s' % schema_info['error'])
+ 'schema for this directive: %s' % info.error)
body_color = wx.RED
else:
- doc = self.join_lines(schema_info.get('doc', ''))
+ doc = self.join_lines(info.doc)
body_color = wx.BLACK
if not doc:
doc = 'No documentation available.'
@@ -441,8 +441,8 @@
wx.ListCtrl.__init__(
self, parent, id, style=wx.LC_REPORT | wx.LC_VIRTUAL)
self.gui = gui
- self.elements = []
- self.indexes = [] # list of element indexes (shuffled by sorting)
+ self.directives = [] # list of directives, not reordered by sorting
+ self.indexes = [] # list of directive indexes, reordered by sorting
self.filter = Filter(gui, xrc.XRCCTRL(self.gui.frame, 'filter_panel'))
self.columns = columns.create_default_columns()
@@ -452,7 +452,7 @@
self.initColumnSorter(len(self.columns))
for i, c in enumerate(self.columns):
- self.InsertColumn(i, c.label, width=c.default_width)
+ self.InsertColumn(i, c.getLabel(), width=c.getDefaultWidth())
self.SortListItems(0, 1)
@@ -474,23 +474,22 @@
selected = []
item = self.GetFirstSelected()
while item >= 0:
- selected.append(self.elements[item])
+ index = self.indexes[item]
+ selected.append(self.directives[index])
item = self.GetNextSelected(item)
self.gui.book.onSelect(selected)
def populate(self):
self.itemDataMap = {}
- for c in self.columns:
- c.setProject(self.gui.project)
if self.gui.project is None:
self.SetItemCount(0)
return
- self.elements = []
+ self.directives = []
files = []
- # Order the elements by filename. The original order is not
- # used directly for display order, but when two elements have
+ # Order the directives by filename. The original order is not
+ # used directly for display order, but when two directives have
# the same sort key, sorting will fall back to the original
# order.
for cfg in self.gui.project.files.values():
@@ -498,8 +497,9 @@
files.sort()
for sort_key, cfg in files:
if cfg.root is not None:
- self.elements.extend(cfg.root.flattened())
- self.SetItemCount(len(self.elements))
+ self.directives.extend(
+ [e.directive for e in cfg.root.flattened()])
+ self.SetItemCount(len(self.directives))
self._doResize()
try:
self.SortItems()
@@ -510,7 +510,7 @@
def OnGetItemText(self, item, col):
index = self.indexes[item]
- d = self.elements[index].directive
+ d = self.directives[index]
col_obj = self.columns[col]
text = col_obj.getText(d)
if col == self._col and col_obj.indent and d.element.depth:
@@ -537,10 +537,10 @@
# gather the focus and selection flags
flags = {}
mask = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED
- for i, element_index in enumerate(self.indexes):
+ for i, directive_index in enumerate(self.indexes):
state = self.GetItemState(i, mask)
if state:
- flags[element_index] = state
+ flags[directive_index] = state
# _col and _colSortFlag are defined in ColumnSorterMixin.
# col is the column which was clicked on and
@@ -550,34 +550,34 @@
col = self._col
sf = self._colSortFlag[col]
- # create pairs [(element_sort_key, element_index)]
+ # create pairs [(directive_sort_key, directive_index)]
items = []
col_obj = self.columns[col]
- for i, e in enumerate(self.elements):
- sort_key = col_obj.getSortKey(e.directive)
+ for i, d in enumerate(self.directives):
+ sort_key = col_obj.getSortKey(d)
items.append((sort_key, i))
- # sort the pairs by value (first element), then by original
- # order (second element). Multiple same values are okay,
+ # sort the pairs by value (first sort key), then by original
+ # order (second sort key). Multiple same values are okay,
# because the keys are unique.
items.sort()
- # get the element index for each sorted item
+ # get the directive index for each sorted item
k = [key for value, key in items]
# False is descending (starting from last)
if sf == False:
k.reverse()
- # store the element indexes as self.indexes.
+ # store the directive indexes as self.indexes.
self.indexes = k
# clear state for all rows (undocumented API?)
self.SetItemState(-1, 0, mask)
# reapply the selection and focus flags
- for i, element_index in enumerate(self.indexes):
- state = flags.get(element_index)
+ for i, directive_index in enumerate(self.indexes):
+ state = flags.get(directive_index)
if state:
self.SetItemState(i, state, mask)
if state & wx.LIST_STATE_FOCUSED:
Modified: z3/zopejam/trunk/src/zopejam/propbook.py
==============================================================================
--- z3/zopejam/trunk/src/zopejam/propbook.py (original)
+++ z3/zopejam/trunk/src/zopejam/propbook.py Wed Jul 20 09:09:21 2005
@@ -6,6 +6,9 @@
"""
import wx
+import wx.grid
+
+from zopejam import columns
class PropertiesNotebook:
@@ -13,11 +16,88 @@
def __init__(self, gui, notebook):
self.gui = gui
self.notebook = notebook
+## self.props_page = wx.ScrolledWindow(self.notebook)
+## self.props_page.SetSizer(wx.BoxSizer(wx.VERTICAL))
+## self.props_page.SetScrollRate(0, 20)
self.props_page = wx.Panel(self.notebook)
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ self.props_page.SetSizer(sizer)
self.notebook.AddPage(self.props_page, "Properties")
self.source_page = wx.Panel(self.notebook)
self.notebook.AddPage(self.source_page, "Source")
- def onSelect(self, elements):
- pass
-
+ def onSelect(self, directives):
+ self.props_page.DestroyChildren()
+ sizer = self.props_page.GetSizer()
+ if not directives:
+ return
+ if len(directives) > 1:
+ grid = wx.grid.Grid(self.props_page, -1)
+ sizer = self.props_page.GetSizer()
+ sizer.Add(grid, proportion=1, flag=wx.EXPAND)
+ grid.SetTable(PropertyTable(directives))
+ self.props_page.Layout()
+ # else show a friendly property editor with documentation
+
+
+class PropertyTable(wx.grid.PyGridTableBase):
+
+ def __init__(self, directives):
+ wx.grid.PyGridTableBase.__init__(self)
+ self.directives = directives
+ attrs = {}
+ for d in directives:
+ t = d.getType()
+ if t is not None:
+ info = t.getSchemaInfo()
+ attrs.update(info.attributes)
+ attrs = attrs.keys()
+ attrs.sort()
+ self.columns = [
+ columns.SourceFile(),
+ columns.DirectiveType(),
+ ]
+ for a in attrs:
+ self.columns.append(columns.SchemaAttribute(a))
+
+ # prepare self.cell_attrs
+ self.cell_attrs = {} # {(valid, editable, has_error): GridCellAttr}
+ for valid in (False, True):
+ for editable in (False, True):
+ for has_error in (False, True):
+ gca = wx.grid.GridCellAttr()
+ if not valid:
+ gca.SetBackgroundColour(wx.Colour(127, 127, 127))
+ elif has_error:
+ gca.SetBackgroundColour(wx.Colour(255, 127, 127))
+ gca.SetReadOnly(not valid or not editable)
+ self.cell_attrs[(valid, editable, has_error)] = gca
+
+ def GetNumberCols(self):
+ return len(self.columns)
+
+ def GetNumberRows(self):
+ return len(self.directives)
+
+ def GetColLabelValue(self, col):
+ return self.columns[col].getLabel()
+
+ def GetRowLabelValue(self, row):
+ return '%d' % (row + 1)
+
+ def GetValue(self, row, col):
+ d = self.directives[row]
+ return self.columns[col].getText(d)
+
+ def GetRawValue(self, row, col):
+ return self.GetValue(row, col)
+
+ def SetValue(self, row, col, value):
+ raise NotImplementedError
+
+ def GetAttr(self, row, col, kind):
+ d = self.directives[row]
+ flags = self.columns[col].getFlags(d)
+ a = self.cell_attrs[flags]
+ a.IncRef()
+ return a
More information about the z3-checkins
mailing list