diff --git a/.gitignore b/.gitignore index 2bc518a..9e64739 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.pydevproject *.sublime-project *.sublime-workspace +.settings diff --git a/browser/common.py b/browser/common.py index 6a977dd..00ec412 100755 --- a/browser/common.py +++ b/browser/common.py @@ -52,6 +52,7 @@ from zope.traversing.browser import absoluteURL from zope.traversing.api import getName, getParent, traverse from cybertools.ajax.dojo import dojoMacroTemplate +from cybertools.browser.action import actions from cybertools.browser.view import GenericView from cybertools.meta.interfaces import IOptions from cybertools.meta.element import Element @@ -617,7 +618,6 @@ class BaseView(GenericView, I18NView): for opt in (self.options, self.typeOptions, self.globalOptions): if isinstance(opt, DummyOptions): continue - #import pdb; pdb.set_trace() v = opt for key in keys.split('.'): if isinstance(v, list): @@ -706,22 +706,37 @@ class BaseView(GenericView, I18NView): @Lazy def states(self): + return self.getStates() + + @Lazy + def allStates(self): + return self.getStates(False) + + def getStates(self, forDisplay=True): result = [] - if not checkPermission(self.viewStatesPermission, self.context): + if forDisplay and not checkPermission(self.viewStatesPermission, self.context): + # do not display state information return result if IResource.providedBy(self.target): - statesDefs = self.globalOptions('organize.stateful.resource', ()) + statesDefs = (self.globalOptions('organize.stateful.resource') or []) else: - typeOptions = self.typeOptions('organize.stateful') - if typeOptions is None: - typeOptions = [] - statesDefs = (self.globalOptions('organize.stateful.concept', []) + - typeOptions) + statesDefs = (self.globalOptions('organize.stateful.concept') or []) + statesDefs += (self.typeOptions('organize.stateful') or []) for std in statesDefs: stf = component.getAdapter(self.target, IStateful, name=std) result.append(stf) return result + def checkState(self): + if not self.allStates: + return True + for stf in self.allStates: + option = self.globalOptions( + 'organize.stateful.restrict.' + stf.statesDefinition) + if option: + return stf.state in option + return True + # controlling actions and editing @Lazy @@ -732,10 +747,21 @@ class BaseView(GenericView, I18NView): """ Return a list of actions that provide the view and edit actions available for the context object. """ - actions = [] + acts = [] + optKey = 'action.' + category + actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or []) + if actNames: + acts = list(actions.get(category, actNames, + view=self, page=page, target=target)) if category in self.actions: - actions.extend(self.actions[category](self, page=page, target=target)) - return actions + acts.extend(self.actions[category](self, page, target)) + optKey = 'append_action.' + category + actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or []) + if actNames: + acts.extend(list(actions.get(category, actNames, + view=self, page=page, target=target))) + return acts + def getAdditionalActions(self, category='object', page=None, target=None): """ Provide additional actions; override by subclass. diff --git a/browser/concept.py b/browser/concept.py index f06c419..cb2027a 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -535,17 +535,6 @@ class ConceptView(BaseView): for node in self.context.getClients(): yield NodeView(node, self.request) - def getActions(self, category='object', page=None, target=None): - acts = [] - optKey = 'action.' + category - actNames = (self.options(optKey) or []) + (self.typeOptions(optKey) or []) - if actNames: - acts = list(actions.get(category, actNames, - view=self, page=page, target=target)) - if category in self.actions: - acts.extend(self.actions[category](self, page, target)) - return acts - def getPortletActions(self, page=None, target=None): if self.portlet_actions: return actions.get('portlet', self.portlet_actions, diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index 3cf4d5f..7bbea5a 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -64,10 +64,12 @@ -

- Description

+
Description
+ @@ -130,7 +132,8 @@

Children

@@ -163,7 +166,7 @@ - Resource Title + Concept Title + + + + + + @@ -321,6 +332,20 @@ + +
+ + + + + + +
+
+ + diff --git a/browser/form.py b/browser/form.py old mode 100644 new mode 100755 diff --git a/browser/form_macros.pt b/browser/form_macros.pt index ccf274c..b4b1fcf 100755 --- a/browser/form_macros.pt +++ b/browser/form_macros.pt @@ -318,7 +318,8 @@
- +

 
diff --git a/browser/node_macros.pt b/browser/node_macros.pt index 640f9a1..41d8a10 100644 --- a/browser/node_macros.pt +++ b/browser/node_macros.pt @@ -319,7 +319,8 @@ i18n:translate="">Log in
- Register new member
diff --git a/browser/resource.py b/browser/resource.py index 0960cb2..2b7a7ec 100644 --- a/browser/resource.py +++ b/browser/resource.py @@ -47,7 +47,7 @@ from loops.browser.common import EditForm, BaseView from loops.browser.concept import BaseRelationView, ConceptRelationView from loops.browser.concept import ConceptConfigureView from loops.browser.node import NodeView, node_macros -from loops.common import adapted, NameChooser +from loops.common import adapted, NameChooser, normalizeName from loops.interfaces import IBaseResource, IDocument, ITextDocument from loops.interfaces import IMediaAsset as legacy_IMediaAsset from loops.interfaces import ITypeConcept @@ -214,7 +214,8 @@ class ResourceView(BaseView): if self.typeOptions('no_normalize_download_filename'): filename = '"%s"' % filename else: - filename = NameChooser(getParent(self.context)).normalizeName(filename) + #filename = NameChooser(getParent(self.context)).normalizeName(filename) + filename = normalizeName(filename) response.setHeader('Content-Disposition', 'attachment; filename=%s' % filename) response.setHeader('Content-Length', len(data)) diff --git a/browser/resource_macros.pt b/browser/resource_macros.pt index 406e519..8a70e4f 100644 --- a/browser/resource_macros.pt +++ b/browser/resource_macros.pt @@ -12,9 +12,11 @@

Title

-

- Description

+ +
Description
+
Title
-

Description

+
Description
@@ -63,8 +66,10 @@

Title

-

Description 

-

+

Description
+
+
diff --git a/browser/skin/lobo/lobo.css b/browser/skin/lobo/lobo.css index 4fbcbd3..30fdd1a 100644 --- a/browser/skin/lobo/lobo.css +++ b/browser/skin/lobo/lobo.css @@ -22,10 +22,6 @@ body { margin-top: 1em; } -.head-description, .legend { - font-style: italic; -} - ul.view-modes { padding: 0 0 0 2em; margin: 0.7em 0 0 0; @@ -118,12 +114,23 @@ thead th { padding-left: 0; } +.head-description{ + /* font-style: italic; */ + font-size: 110%; +} + .description { - font-style: italic; + /* font-style: italic; */ /* margin-top: 0.5em;*/ + font-size: 110%; margin-bottom: 0.3em; } +.legend { + /* font-style: italic; */ + font-size: 95%; +} + .infotext { font-size: 90%; } @@ -302,6 +309,10 @@ fieldset.box td { margin-top: -1px; } +.nested { + margin-left: 2em; +} + .content-1 h1, h1 { padding-top: 0.5em; font-size: 180%; diff --git a/common.py b/common.py index 73668a3..0a8b9c1 100644 --- a/common.py +++ b/common.py @@ -257,7 +257,7 @@ def normalizeName(baseName): except UnicodeDecodeError: result.append('_') continue - if c in '._': + if c in '._-': # separator and special characters to keep result.append(c) continue diff --git a/compound/book/browser.py b/compound/book/browser.py index dd4df91..fb6fcf6 100644 --- a/compound/book/browser.py +++ b/compound/book/browser.py @@ -95,6 +95,11 @@ class Base(object): if self.editable: return 'index.html' + def children(self): + for c in self.getChildren(): + if c.checkState(): + yield c + def getResources(self): relViews = super(Base, self).getResources() return relViews @@ -106,9 +111,10 @@ class Base(object): idx = 0 for rv in self.getResources(): if rv.context.contentType.startswith('text/'): - idx += 1 - result.append(rv) - self.images.append([]) + if rv.checkState(): + idx += 1 + result.append(rv) + self.images.append([]) else: self.registerDojoLightbox() url = self.nodeView.getUrlForTarget(rv.context) @@ -130,7 +136,8 @@ class Base(object): return IOptions(adapted(dt))(name) def getTitleForResource(self, r): - if self.getOptionsForResource(r, 'showtitle'): + if (IOptions(adapted(r.context.resourceType))('show_title_in_section') or + self.getOptionsForResource(r, 'show_title_in_section')): return r.title def getIconForResource(self, r): @@ -152,7 +159,9 @@ class Base(object): def getParentsForResource(self, r): for c in r.context.getConcepts([self.defaultPredicate]): - if c != self.context and c.conceptType != self.documentTypeType: + if (c != self.context and + c.conceptType != self.documentTypeType and + self.getViewForObject(c).checkState()): yield c diff --git a/compound/book/view_macros.pt b/compound/book/view_macros.pt index 43be71b..c85a69c 100644 --- a/compound/book/view_macros.pt +++ b/compound/book/view_macros.pt @@ -1,19 +1,43 @@ - -
-

- -

-
- -
+ + +
+

+

+
+ + + +
+ + + + +
+

+ +

+
+
+ + + + @@ -30,12 +54,13 @@ tal:attributes="href pred/targetUrl; title pred/title">
- + - +
@@ -103,15 +128,17 @@ - +

Children

+ tal:condition="children">Children

Text Elements

+ tal:condition="textResources">Text Elements
-

diff --git a/expert/browser/search.py b/expert/browser/search.py index 7fd6cb0..d235d4d 100644 --- a/expert/browser/search.py +++ b/expert/browser/search.py @@ -70,7 +70,9 @@ class QuickSearchResults(NodeView): fv = FilterView(self.context, self.request) result = fv.apply(result) result.sort(key=lambda x: x.title.lower()) - return self.viewIterator(result) + for v in self.viewIterator(result): + if v.checkState(): + yield v class Search(ConceptView): @@ -257,8 +259,6 @@ class Search(ConceptView): return self.viewIterator(result) def checkStates(self, obj): - if not IResource.providedBy(obj): - return True for std, states in self.selectedStates.items(): if std.startswith('state.resource.'): std = std[len('state.resource.'):] diff --git a/knowledge/survey/configure.zcml b/knowledge/survey/configure.zcml index 423889d..a205abd 100644 --- a/knowledge/survey/configure.zcml +++ b/knowledge/survey/configure.zcml @@ -12,6 +12,8 @@ + @@ -23,6 +25,8 @@ + @@ -34,6 +38,8 @@ + @@ -45,6 +51,8 @@ + diff --git a/layout/browser/base.py b/layout/browser/base.py index a6494d2..b5039b8 100644 --- a/layout/browser/base.py +++ b/layout/browser/base.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2009 Helmut Merz helmutm@cy55.de +# Copyright (c) 2013 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 @@ -18,8 +18,6 @@ """ Base classes for layout-based views. - -$Id$ """ from zope.app.security.interfaces import IUnauthenticatedPrincipal @@ -29,9 +27,11 @@ from zope.proxy import removeAllProxies from zope.security.proxy import removeSecurityProxy from zope.traversing.browser import absoluteURL +from cybertools.meta.interfaces import IOptions from cybertools.util import format -from loops.common import adapted +from loops.common import adapted, baseObject from loops.i18n.browser import LanguageInfo +from loops.browser.concept import ConceptView as BaseConceptView from loops.browser.util import normalizeForUrl as normalize from loops import util @@ -74,6 +74,10 @@ class BaseView(object): def virtualTargetView(self): return self.viewAnnotations.get('targetView') + @Lazy + def baseConceptView(self): + return BaseConceptView(baseObject(self.context), self.request) + @Lazy def node(self): return self.viewAnnotations.get('node') @@ -170,3 +174,7 @@ class BaseView(object): def getMetaDescription(self): return self.context.title + @Lazy + def globalOptions(self): + return IOptions(self.loopsRoot) + diff --git a/layout/browser/node.py b/layout/browser/node.py index e2a7167..6e1bb44 100644 --- a/layout/browser/node.py +++ b/layout/browser/node.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2013 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 @@ -18,8 +18,6 @@ """ Layout node views. - -$Id$ """ from zope.app.security.interfaces import IUnauthenticatedPrincipal @@ -63,9 +61,12 @@ class LayoutNodeView(Page, BaseView): @Lazy def headTitle(self): + parts = [self.context.title] if self.target is not None: targetView = component.getMultiAdapter((self.target, self.request), name='layout') - return ' - '.join((self.context.title, targetView.title)) - else: - return self.context.title + if targetView.title not in parts: + parts.append(targetView.title) + if self.globalOptions('reverseHeadTitle'): + parts.reverse() + return ' - '.join(parts) diff --git a/media/browser/asset.pt b/media/browser/asset.pt index 2eb0d8d..24f0524 100644 --- a/media/browser/asset.pt +++ b/media/browser/asset.pt @@ -11,7 +11,8 @@ tal:attributes="src string:${url}/@@mediaasset.html?version=this&v=medium" />

-

Description

+
Description

diff --git a/media/browser/asset.py b/media/browser/asset.py index 630a1c8..a18deda 100644 --- a/media/browser/asset.py +++ b/media/browser/asset.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2013 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 @@ -20,17 +20,16 @@ Views for displaying media assets. Authors: Johann Schimpf, Erich Seifert. - -$Id$ """ from zope.app.pagetemplate import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.security.interfaces import Unauthorized +from zope.traversing.api import getParent from loops.browser.node import NodeView from loops.browser.resource import ResourceView, resource_macros -from loops.common import adapted +from loops.common import adapted, normalizeName from loops.util import _ from loops import util @@ -62,7 +61,7 @@ class MediaAssetView(ResourceView): if useAttachment: filename = obj.localFilename or getName(self.context) #filename = urllib.quote(filename) - filename = NameChooser(getParent(self.context)).normalizeName(filename) + filename = normalizeName(filename) response.setHeader('Content-Disposition', 'attachment; filename=%s' % filename) return data diff --git a/organize/browser/member.py b/organize/browser/member.py index 5916929..738b521 100644 --- a/organize/browser/member.py +++ b/organize/browser/member.py @@ -112,7 +112,8 @@ class BaseMemberRegistration(NodeView): @Lazy def macro(self): - return schema_macros.macros['form'] + #return schema_macros.macros['form'] + return organize_macros.macros['register'] def checkPermissions(self): personType = adapted(self.conceptManager['person']) diff --git a/organize/work/browser.py b/organize/work/browser.py index 3a78a10..8975aba 100644 --- a/organize/work/browser.py +++ b/organize/work/browser.py @@ -253,7 +253,8 @@ class BaseWorkItemsView(object): tsTo += 3600 * 24 - 1 # include full end date if tsFrom or tsTo: result['timeFromTo'] = (tsFrom, tsTo) - state = form.get('wi_state') or self.options.wi_state + state = (form.get('wi_state') or + self.options.wi_state or self.typeOptions.wi_state) if not state: result['state'] = ['planned', 'accepted', 'running', 'done', 'done_x', 'finished', 'delegated', 'moved', 'cancelled'] diff --git a/system/site/view_macros.pt b/system/site/view_macros.pt index e542cca..2a0bc47 100644 --- a/system/site/view_macros.pt +++ b/system/site/view_macros.pt @@ -11,7 +11,8 @@
  • My Site
    - +