Author: jmorliaguet Date: Sun Jul 2 16:41:48 2006 New Revision: 3586 Modified: cpsskins/branches/paris-sprint-2006/elements/format.py cpsskins/branches/paris-sprint-2006/locations/interfaces.py cpsskins/branches/paris-sprint-2006/locations/location.py cpsskins/branches/paris-sprint-2006/locations/sources.py cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml cpsskins/branches/paris-sprint-2006/standard/formats/layout.py cpsskins/branches/paris-sprint-2006/storage/configure.zcml cpsskins/branches/paris-sprint-2006/storage/locations.py cpsskins/branches/paris-sprint-2006/ui/screens/pagedesigner/layout/themepage.pt cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt
Log: - saving work: - locations are reindexed when their path changes - bug fixes Modified: cpsskins/branches/paris-sprint-2006/elements/format.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/format.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/format.py Sun Jul 2 16:41:48 2006 @@ -42,7 +42,11 @@ implements(IFormat) def __init__(self, types=None): - self.types = types or [] + if types is None: + types = [] + if not isinstance(types, list): + types = [types] + self.types = types def getPredicate(self): return IType(self).getContentType().getTaggedValue('predicate') Modified: cpsskins/branches/paris-sprint-2006/locations/interfaces.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/interfaces.py (original) +++ cpsskins/branches/paris-sprint-2006/locations/interfaces.py Sun Jul 2 16:41:48 2006 @@ -17,6 +17,7 @@ """ __docformat__ = "reStructuredText" +from zope.component.interfaces import IObjectEvent from zope.interface import Interface, Attribute from zope.i18nmessageid import MessageFactory from zope.schema import TextLine, Choice @@ -57,3 +58,5 @@ def __str__(): """Return the location's path""" +class ILocationModifiedEvent(IObjectEvent): + """Event triggered when locations are modified""" Modified: cpsskins/branches/paris-sprint-2006/locations/location.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/location.py (original) +++ cpsskins/branches/paris-sprint-2006/locations/location.py Sun Jul 2 16:41:48 2006 @@ -20,8 +20,11 @@ from persistent import Persistent from zope.component.factory import Factory from zope.interface import implements +from zope.event import notify from cpsskins.locations.interfaces import ILocation +from cpsskins.locations.events import LocationModifiedEvent +from cpsskins.utils import cloneObject class Location(Persistent): """A location @@ -33,6 +36,7 @@ self.data = data self.scope = scope self.root = root + self._initialized = True def __repr__(self): path = self.path @@ -69,9 +73,17 @@ return u'/'.join(self._path_tuple + (self._method,)) def setPath(self, path): + initialized = getattr(self, '_initialized', False) + if initialized: + old_data = { + 'root': self.root, + 'path': self.path, + } parts = path.split(u'/') self._path_tuple = tuple(parts[:-1]) self._method = parts[-1] + if initialized: + notify(LocationModifiedEvent(self, old_data)) path = property(getPath, setPath) Modified: cpsskins/branches/paris-sprint-2006/locations/sources.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/sources.py (original) +++ cpsskins/branches/paris-sprint-2006/locations/sources.py Sun Jul 2 16:41:48 2006 @@ -64,6 +64,9 @@ root = context.root choices = {} + # allow for empty string values + choices[''] = u'(no value)' + if root == u'pages': for theme in tmutil.getThemes(): theme_name = theme.name Modified: cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/standard/formats/configure.zcml Sun Jul 2 16:41:48 2006 @@ -11,6 +11,12 @@ predicate=".layout.hasLayout" /> + <utility + provides="zope.schema.interfaces.IVocabularyFactory" + component=".layout.LayoutTypesVocabulary" + name="Layout types" + /> + <!-- Style --> <cpsskins:format name="style" Modified: cpsskins/branches/paris-sprint-2006/standard/formats/layout.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/standard/formats/layout.py (original) +++ cpsskins/branches/paris-sprint-2006/standard/formats/layout.py Sun Jul 2 16:41:48 2006 @@ -19,10 +19,12 @@ from BTrees.OOBTree import OOBTree from persistent import Persistent - -from zope.traversing.interfaces import ITraversable -from zope.interface import implements +from zope.interface import implements, alsoProvides from zope.interface.common.mapping import IMapping +from zope.schema import List, Choice +from zope.schema.interfaces import IVocabularyFactory +from zope.schema.vocabulary import SimpleVocabulary +from zope.traversing.interfaces import ITraversable from cpsskins.elements.format import Format from cpsskins.elements.interfaces import IFormat @@ -33,6 +35,12 @@ class ILayout(IFormat, IMapping): """A layout element""" + types = List( + title=_(u"Layout types"), + description=_(u"The list of layout types."), + value_type=Choice(vocabulary='Layout types'), + ) + def traverse(name, remaining): """Get a layout attribute by traversal.""" @@ -91,7 +99,8 @@ def __setitem__(self, k, v): if not isinstance(v, basestring): raise TypeError("Only strings can be stored in the layout objects.") - if not k in self: + # types may not have been initialized + if self.types and k not in self: raise KeyError("No such property: %s" % k) self.data[k] = v @@ -108,6 +117,8 @@ return k in self.keys() def keys(self): + if not self.types: + return [] return self._layout_types[self.types[0]] def items(self): @@ -119,3 +130,13 @@ has_key = __contains__ +def LayoutTypesVocabulary(context): + """A vocabulary that contains the list of widgets. + """ + layout_types = [ + (u('Container'), u'container'), + (u('Contained'), u'contained'), + ] + return SimpleVocabulary.fromItems(layout_types) + +alsoProvides(LayoutTypesVocabulary, IVocabularyFactory) Modified: cpsskins/branches/paris-sprint-2006/storage/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/storage/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/storage/configure.zcml Sun Jul 2 16:41:48 2006 @@ -57,5 +57,10 @@ contains="cpsskins.locations.interfaces.ILocation" /> + <subscriber + for="cpsskins.locations.interfaces.ILocationModifiedEvent" + handler=".locations.modifiedSubscriber" + /> + </configure> Modified: cpsskins/branches/paris-sprint-2006/storage/locations.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/storage/locations.py (original) +++ cpsskins/branches/paris-sprint-2006/storage/locations.py Sun Jul 2 16:41:48 2006 @@ -19,10 +19,11 @@ from sets import Set from zope.app.container.constraints import contains +from zope.app.container.contained import ObjectAddedEvent from zope.event import notify from zope.interface import implements -from zope.app.container.contained import ObjectAddedEvent from zope.location.location import locate +from zope.traversing.api import getParent from cpsskins.locations.location import ILocation from cpsskins.storage import Storage @@ -78,11 +79,16 @@ self.remove(key) def remove(self, ids): - if not isinstance(ids, (list, tuple)): + if not isinstance(ids, list): ids = [ids] for id in ids: del self[id] + def computeKey(self, root, path): + path = tuple(path.split(u'/')) + path, method = path[:-1], path[-1] + return (root, method) + path + def find(self, path, root=u''): if isinstance(path, basestring): path = tuple(path.split(u'/')) @@ -145,8 +151,15 @@ return locations def getLocation(self, root=u'', path=u''): - path = tuple(path.split(u'/')) - path, method = path[:-1], path[-1] - key = (root, method) + path + key = self.computeKey(root, path) return self[key] +def modifiedSubscriber(event): + location = event.object + old_data = event.old_data + storage = getParent(location) + + old_key = storage.computeKey(**old_data) + storage.remove([old_key]) + storage.add(location) + Modified: cpsskins/branches/paris-sprint-2006/ui/screens/pagedesigner/layout/themepage.pt ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/screens/pagedesigner/layout/themepage.pt (original) +++ cpsskins/branches/paris-sprint-2006/ui/screens/pagedesigner/layout/themepage.pt Sun Jul 2 16:41:48 2006 @@ -3,22 +3,11 @@ len python: len(children)" tal:attributes="id id"> - <div class="pageBlockAddButton"> - <a title="Insert a page block" + <a class="pageBlockAddButton" title="Insert a page block" tal:attributes="href string:@@addPageBlock?id=$id&order=0"> <img style="width: 46px; height: 18px" - src="++resource++add-pageblock.png" /> - insert a block</a> - </div> + src="++resource++add-pageblock.png" /></a> <div tal:content="structure options/markup" /> - <div class="pageBlockAddButton"> - <a title="Insert a page block" - tal:attributes="href string:@@addPageBlock?id=$id&order=$len"> - <img style="width: 46px; height: 18px" - src="++resource++add-pageblock.png" /> - insert a block</a> - </div> - </div> Modified: cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt (original) +++ cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/negotiation_section.pt Sun Jul 2 16:41:48 2006 @@ -51,7 +51,6 @@ <input class="submit" type="submit" value="[add]" /> </tal:block> - <tal:block condition="edited"> <input type="hidden" name="action" value="edit" /> <input type="hidden" name="root" tal:attributes="value section" /> -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins