diff --git a/browser/common.py b/browser/common.py
index 6cb9f55..4967379 100644
--- a/browser/common.py
+++ b/browser/common.py
@@ -513,6 +513,8 @@ class BaseView(GenericView, I18NView):
def registerDojoFormAll(self):
self.registerDojo()
jsCall = ('dojo.require("dijit.form.Form"); '
+ 'dojo.require("dijit.form.DateTextBox"); '
+ 'dojo.require("dijit.form.TimeTextBox");'
'dojo.require("dijit.form.FilteringSelect"); '
'dojo.require("dojox.data.QueryReadStore");')
self.controller.macros.register('js-execute', 'dojo.form.all', jsCall=jsCall)
@@ -520,6 +522,26 @@ class BaseView(GenericView, I18NView):
# vocabulary stuff
+class SimpleTerms(object):
+ """ Provide the ITerms interface, e.g. for usage in selection
+ lists.
+ """
+
+ implements(ITerms)
+
+ def __init__(self, source, request):
+ # the source parameter is a list of tuples (token, title).
+ self.source = source
+ self.terms = dict(source)
+
+ def getTerm(self, value):
+ token, title = value
+ return SimpleTerm(token, token, title)
+
+ def getValue(self, token):
+ return (token, self.terms[token])
+
+
class LoopsTerms(object):
""" Provide the ITerms interface, e.g. for usage in selection
lists.
diff --git a/browser/configure.zcml b/browser/configure.zcml
index 748c7e0..729893d 100644
--- a/browser/configure.zcml
+++ b/browser/configure.zcml
@@ -722,6 +722,10 @@
for="loops.resource.ResourceTypeSourceList
zope.publisher.interfaces.browser.IBrowserRequest" />
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/layout/node.py b/browser/layout/node.py
new file mode 100644
index 0000000..a0e04bd
--- /dev/null
+++ b/browser/layout/node.py
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""
+Layout management and controlling via view space nodes.
+
+$Id$
+"""
+
+from zope.cachedescriptors.property import Lazy
+from zope.component import adapts
+from zope.interface import implements
+
+from cybertools.composer.layout.interfaces import ILayout
+from loops.interfaces import INode
+from loops.view import nodeTypes, NodeAdapter
+
+
+nodeTypes.append(('layout', 'Layout'))
+
+
+class NodeLayoutProvider(NodeAdapter):
+
+ pass
+
+
+class NodeLayout(object):
+
+ implements(ILayout)
+ adapts(INode)
+
+ def __init__(self, context):
+ self.context = context
+
diff --git a/configure.zcml b/configure.zcml
index dbad615..a778f5c 100644
--- a/configure.zcml
+++ b/configure.zcml
@@ -419,8 +419,14 @@
component="loops.predicate.PredicateInterfaceSourceList"
name="loops.PredicateInterfaceSource" />
+
+
+
diff --git a/interfaces.py b/interfaces.py
index dc644db..b4fdeda 100644
--- a/interfaces.py
+++ b/interfaces.py
@@ -433,12 +433,7 @@ class INodeSchema(IView):
nodeType = schema.Choice(
title=_(u'Node Type'),
description=_(u'Type of the node'),
- source=util.KeywordVocabulary((
- ('text', _(u'Text')),
- ('page', _(u'Page')),
- ('menu', _(u'Menu')),
- ('info', _(u'Info')),
- )),
+ source='loops.nodeTypeSource',
default='info',
required=True)
diff --git a/util.py b/util.py
index 3cceecd..6d6ab31 100644
--- a/util.py
+++ b/util.py
@@ -33,7 +33,6 @@ import cybertools
from loops.browser.util import html_quote
_ = MessageFactory('loops')
-#_ = MessageFactory('zope') # it's easier not use a special i18n domain?
renderingFactories = {
diff --git a/view.py b/view.py
index b9139c5..f0a9e36 100644
--- a/view.py
+++ b/view.py
@@ -23,7 +23,6 @@ $Id$
"""
from zope import component
-from zope.app import zapi
from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained
from zope.app.container.ordered import OrderedContainer
@@ -33,13 +32,15 @@ from zope.component import adapts
from zope.interface import implements
from zope.interface import alsoProvides, directlyProvides, directlyProvidedBy
from zope.publisher.browser import applySkin
+from zope import schema
from zope.security.proxy import removeSecurityProxy
+from zope.traversing.api import getName, getParent
from persistent import Persistent
+
from cybertools.relation import DyadicRelation
from cybertools.relation.registry import getRelations
from cybertools.relation.interfaces import IRelationRegistry, IRelatable
from cybertools.util.jeep import Jeep
-
from loops.base import ParentInfo
from loops.common import AdapterBase
from loops.interfaces import IView, INode, INodeSchema, INodeAdapter
@@ -49,12 +50,18 @@ from loops.interfaces import ITargetRelation
from loops.interfaces import IConcept
from loops.versioning.util import getVersion
from loops import util
+from loops.util import _
class View(object):
implements(IView, INodeContained, IRelatable)
+ def __init__(self, title=u'', description=u''):
+ self.title = title
+ self.description = description
+ super(View, self).__init__()
+
_title = u''
def getTitle(self): return self._title
def setTitle(self, title): self._title = title
@@ -66,10 +73,10 @@ class View(object):
description = property(getDescription, setDescription)
_viewName = u''
- def getViewName(self): return self._viewName #or getattr(self, '_viewer', u'')
+ def getViewName(self):
+ return self._viewName
def setViewName(self, viewName):
self._viewName = viewName
- #self._viewer = u'' # BBB
viewName = property(getViewName, setViewName)
def getTarget(self):
@@ -78,11 +85,11 @@ class View(object):
return None
if len(rels) > 1:
raise ValueError('There may be only one target for a View object: %s - %s'
- % (zapi.getName(self), `[zapi.getName(r.second) for r in rels]`))
+ % (getName(self), `[getName(r.second) for r in rels]`))
return list(rels)[0].second
def setTarget(self, target):
- registry = zapi.getUtility(IRelationRegistry)
+ registry = component.getUtility(IRelationRegistry)
rels = list(registry.query(first=self, relationship=TargetRelation))
if len(rels) > 0:
oldRel = rels[0]
@@ -98,13 +105,8 @@ class View(object):
target = property(getTarget, setTarget)
- def __init__(self, title=u'', description=u''):
- self.title = title
- self.description = description
- super(View, self).__init__()
-
def getLoopsRoot(self):
- return zapi.getParent(self).getLoopsRoot()
+ return getParent(self).getLoopsRoot()
def getAllParents(self, collectGrants=False):
return Jeep()
@@ -127,11 +129,11 @@ class Node(View, OrderedContainer):
contentType = u'zope.source.rest'
def getParentNode(self, nodeTypes=None):
- parent = zapi.getParent(self)
+ parent = getParent(self)
while INode.providedBy(parent):
if not nodeTypes or parent.nodeType in nodeTypes:
return parent
- parent = zapi.getParent(parent)
+ parent = getParent(parent)
return None
def getAllParents(self, collectGrants=False):
@@ -179,7 +181,7 @@ class ViewManager(OrderedContainer):
implements(IViewManager, ILoopsContained)
def getLoopsRoot(self):
- return zapi.getParent(self)
+ return getParent(self)
def getViewManager(self):
return self
@@ -206,3 +208,27 @@ class NodeAdapter(AdapterBase):
adapts(INode)
_contextAttributes = ('title', 'description', 'body',)
+
+
+nodeTypes = [
+ ('text', _(u'Text')), # shown as part of an enclosing page
+ ('page', _(u'Page')), # standalone page with a menu item
+ ('menu', _(u'Menu')), # top-level menu (also a page)
+ ('info', _(u'Info')), # not shown automatically, but may be a link target
+]
+
+class NodeTypeSourceList(object):
+
+ implements(schema.interfaces.IIterableSource)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __contains__(self, token):
+ return token in [t[0] for t in nodeTypes]
+
+ def __iter__(self):
+ return iter(nodeTypes)
+
+ def __len__(self):
+ return len(nodeTypes)