merge branch master
This commit is contained in:
commit
54c3a9e8aa
20 changed files with 913 additions and 43 deletions
|
@ -130,6 +130,7 @@ class EditForm(form.EditForm):
|
|||
class BaseView(GenericView, I18NView):
|
||||
|
||||
actions = {}
|
||||
portlet_actions = []
|
||||
icon = None
|
||||
modeName = 'view'
|
||||
isToplevel = False
|
||||
|
|
|
@ -243,9 +243,13 @@ class ConceptView(BaseView):
|
|||
if self.breadcrumbsParent is not None:
|
||||
data.extend(self.breadcrumbsParent.breadcrumbs())
|
||||
if self.context != self.nodeView.targetObject:
|
||||
data.append(dict(label=self.title, url=self.targetUrl))
|
||||
data.append(dict(label=self.breadcrumbsTitle, url=self.targetUrl))
|
||||
return data
|
||||
|
||||
@Lazy
|
||||
def breadcrumbsTitle(self):
|
||||
return self.title
|
||||
|
||||
@Lazy
|
||||
def breadcrumbsParent(self):
|
||||
return None
|
||||
|
@ -503,6 +507,12 @@ class ConceptView(BaseView):
|
|||
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,
|
||||
view=self, page=page, target=target)
|
||||
return []
|
||||
|
||||
def getObjectActions(self, page=None, target=None):
|
||||
acts = ['info']
|
||||
if self.globalOptions('organize.allowSendEmail'):
|
||||
|
@ -510,7 +520,7 @@ class ConceptView(BaseView):
|
|||
acts.extend('state.' + st.statesDefinition for st in self.states)
|
||||
return actions.get('object', acts, view=self, page=page, target=target)
|
||||
|
||||
actions = dict(object=getObjectActions)
|
||||
actions = dict(object=getObjectActions, portlet=getPortletActions)
|
||||
|
||||
def checkAction(self, name, category, target):
|
||||
if name in (self.typeOptions('hide_action.' + category) or []):
|
||||
|
|
|
@ -27,10 +27,19 @@
|
|||
<tal:actions condition="view/showObjectActions">
|
||||
<div metal:use-macro="views/node_macros/object_actions" />
|
||||
</tal:actions>
|
||||
<h1 tal:attributes="ondblclick item/openEditWindow">
|
||||
<h1 tal:define="tabview item/tabview|nothing"
|
||||
tal:attributes="ondblclick item/openEditWindow">
|
||||
<a tal:omit-tag="python: level > 1"
|
||||
tal:attributes="href request/URL"
|
||||
tal:content="item/title">Title</a>
|
||||
<a title="Show tabular view"
|
||||
i18n:attributes="title"
|
||||
tal:condition="tabview"
|
||||
tal:attributes="href
|
||||
string:${item/targetUrl}?loops.viewName=$tabview">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/table.png" />
|
||||
</a>
|
||||
</h1>
|
||||
</metal:title>
|
||||
<p tal:define="description description|item/renderedDescription"
|
||||
|
|
|
@ -501,6 +501,9 @@ class EditObject(FormController, I18NView):
|
|||
|
||||
@Lazy
|
||||
def target(self):
|
||||
targetUid = self.request.form.get('targetUid')
|
||||
if targetUid:
|
||||
return self.view.getObjectForUid(targetUid)
|
||||
return self.view.virtualTargetObject or self.context
|
||||
|
||||
@Lazy
|
||||
|
@ -706,8 +709,7 @@ class CreateObject(EditObject):
|
|||
obj.setType(self.objectType)
|
||||
notify(ObjectCreatedEvent(obj))
|
||||
#notify(ObjectAddedEvent(obj))
|
||||
self.object = obj
|
||||
# TODO: validate fields
|
||||
self.object = self.view.object = obj
|
||||
formState = self.updateFields() # TODO: suppress validation
|
||||
self.view.formState = formState
|
||||
# TODO: error handling
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
<input type="hidden" name="form.action" value="edit"
|
||||
tal:attributes="value view/form_action" />
|
||||
<input type="hidden" name="version"
|
||||
tal:attributes="value request/version | nothing" />
|
||||
tal:attributes="value request/version|nothing" />
|
||||
<input type="hidden" name="targetUid"
|
||||
tal:attributes="value request/targetUid|nothing" />
|
||||
<tal:title condition="not:view/isInnerHtml">
|
||||
<h1 tal:content="request/view_title|view/title"
|
||||
i18n:translate="">Edit Information Object</h1>
|
||||
|
|
|
@ -240,6 +240,27 @@
|
|||
</metal:actions>
|
||||
|
||||
|
||||
<metal:breadcrumbs define-macro="breadcrumbs">
|
||||
<table class="breadcrumbs"
|
||||
tal:define="crumbs view/breadcrumbs"
|
||||
tal:condition="crumbs">
|
||||
<tr>
|
||||
<td style="white-space: nowrap; vertical-align: top; width: 10%"
|
||||
i18n:translate="">You are here:</td>
|
||||
<td>
|
||||
<span>
|
||||
<span style="white-space: nowrap"
|
||||
tal:repeat="crumb crumbs">
|
||||
<a tal:attributes="href crumb/url"
|
||||
tal:content="crumb/label" />
|
||||
<tal:delimiter
|
||||
condition="not:repeat/crumb/end"> ></tal:delimiter></span> </span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</metal:breadcrumbs>
|
||||
|
||||
|
||||
<metal:actions define-macro="view_modes">
|
||||
<ul class="view-modes"
|
||||
tal:define="viewModes view/viewModes"
|
||||
|
|
|
@ -227,6 +227,15 @@ class ResourceView(BaseView):
|
|||
response.setHeader('Last-Modified', modified.strftime(format))
|
||||
return data
|
||||
|
||||
def render(self):
|
||||
""" Return the rendered content (data) of the context object.
|
||||
"""
|
||||
self.recordAccess('render', target=self.uniqueId)
|
||||
ctx = adapted(self.context)
|
||||
text = ctx.data
|
||||
contentType = ctx.contentType
|
||||
return self.renderText(ctx.data, ctx.contentType)
|
||||
|
||||
def renderText(self, text, contentType):
|
||||
if contentType == 'text/restructured' and wikiLinksActive(self.loopsRoot):
|
||||
# TODO: make this more flexible/configurable
|
||||
|
@ -400,15 +409,6 @@ class DocumentView(ResourceView):
|
|||
@Lazy
|
||||
def view(self): return self
|
||||
|
||||
def render(self):
|
||||
""" Return the rendered content (data) of the context object.
|
||||
"""
|
||||
self.recordAccess('render', target=self.uniqueId)
|
||||
ctx = adapted(self.context)
|
||||
text = ctx.data
|
||||
contentType = ctx.contentType
|
||||
return self.renderText(ctx.data, ctx.contentType)
|
||||
|
||||
@Lazy
|
||||
def inlineEditable(self):
|
||||
return (self.inlineEditingActive
|
||||
|
|
|
@ -83,8 +83,8 @@
|
|||
</span>
|
||||
<span class="button"
|
||||
tal:condition="item/xeditable">
|
||||
<a title="Edit with External Editor"
|
||||
i18n:translate=""
|
||||
<a title="Edit with external editor"
|
||||
i18n:translate="" i18n:attributes="title"
|
||||
tal:define="url view/virtualTargetUrl"
|
||||
tal:attributes="href string:$url/external_edit?version=this">
|
||||
Open for editing
|
||||
|
|
|
@ -6,6 +6,10 @@ from cybertools.browser.liquid import Liquid
|
|||
from cybertools.browser.blue import Blue
|
||||
|
||||
|
||||
class Loopy(Liquid):
|
||||
""" The Loopy (neutral enduser) skin with all portlets on the
|
||||
left-hand side """
|
||||
|
||||
class Loopz(Liquid):
|
||||
""" The Loopz (neutral enduser) skin """
|
||||
|
||||
|
|
|
@ -5,6 +5,28 @@
|
|||
xmlns="http://namespaces.zope.org/browser"
|
||||
i18n_domain="loops">
|
||||
|
||||
<!-- Loopy skin -->
|
||||
|
||||
<zope:interface
|
||||
interface="loops.browser.skin.Loopy"
|
||||
type="zope.publisher.interfaces.browser.IBrowserSkinType"
|
||||
name="Loopy" />
|
||||
|
||||
<page for="*"
|
||||
name="body.html"
|
||||
class="loops.browser.skin.loopy.browser.View"
|
||||
permission="zope.View"
|
||||
layer="loops.browser.skin.Loopy" />
|
||||
|
||||
<resource name="loops.css" file="loopy/loops.css"
|
||||
layer="loops.browser.skin.Loopy" />
|
||||
<resource name="custom.css" file="loopy/custom.css"
|
||||
layer="loops.browser.skin.Loopy" />
|
||||
<resource name="favicon.png" file="loops_favicon.png"
|
||||
layer="loops.browser.skin.Loopy" />
|
||||
<resource name="logo.png" file="loops_logo.png"
|
||||
layer="loops.browser.skin.Loopy" />
|
||||
|
||||
<!-- Loopz skin -->
|
||||
|
||||
<zope:interface
|
||||
|
|
|
@ -27,23 +27,7 @@
|
|||
<div id="content" class="span-6"
|
||||
metal:define-macro="content">
|
||||
<metal:breadcrumbs define-slot="breadcrumbs">
|
||||
<table class="breadcrumbs"
|
||||
tal:define="crumbs view/breadcrumbs"
|
||||
tal:condition="crumbs">
|
||||
<tr>
|
||||
<td style="white-space: nowrap; vertical-align: top; width: 10%"
|
||||
i18n:translate="">You are here:</td>
|
||||
<td>
|
||||
<span>
|
||||
<span style="white-space: nowrap"
|
||||
tal:repeat="crumb crumbs">
|
||||
<a tal:attributes="href crumb/url"
|
||||
tal:content="crumb/label" />
|
||||
<tal:delimiter
|
||||
condition="not:repeat/crumb/end"> ></tal:delimiter></span> </span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<metal:tabs use-macro="views/node_macros/breadcrumbs" />
|
||||
</metal:breadcrumbs>
|
||||
<div metal:define-slot="actions"></div>
|
||||
<div metal:define-slot="message"></div>
|
||||
|
|
4
browser/skin/loopy/__init__.py
Normal file
4
browser/skin/loopy/__init__.py
Normal file
|
@ -0,0 +1,4 @@
|
|||
# package loops.browser.skin.loopy
|
||||
#
|
||||
# variant of the Loopz skin with all portlets on the left
|
||||
#
|
51
browser/skin/loopy/body.pt
Normal file
51
browser/skin/loopy/body.pt
Normal file
|
@ -0,0 +1,51 @@
|
|||
<tal:block i18n:domain="loops">
|
||||
<div metal:use-macro="views/cybertools.body_macros/body">
|
||||
|
||||
|
||||
<a href="#" name="top" metal:fill-slot="logo"
|
||||
tal:attributes="href view/topMenu/url"><img
|
||||
src="logo.png" border="0"
|
||||
alt="loops Site"
|
||||
tal:attributes="src string:${resourceBase}logo.png" /></a>
|
||||
|
||||
|
||||
<metal:breadcrumbs fill-slot="breadcrumbs">
|
||||
<metal:tabs use-macro="views/node_macros/breadcrumbs" />
|
||||
</metal:breadcrumbs>
|
||||
|
||||
|
||||
<metal:tabs fill-slot="view_modes">
|
||||
<metal:tabs use-macro="views/node_macros/view_modes" />
|
||||
</metal:tabs>
|
||||
|
||||
|
||||
<metal:left fill-slot="portlet-left">
|
||||
<tal:portlet repeat="macro controller/macros/portlet_left">
|
||||
<metal:portlet use-macro="macro" />
|
||||
</tal:portlet>
|
||||
<tal:portlet repeat="macro controller/macros/portlet_right">
|
||||
<metal:portlet use-macro="macro" />
|
||||
</tal:portlet>
|
||||
</metal:left>
|
||||
|
||||
|
||||
<metal:right fill-slot="portlet-right" />
|
||||
|
||||
|
||||
<metal:footer fill-slot="footer">
|
||||
<div xtal:condition="view/editable"
|
||||
tal:condition="nothing">
|
||||
<span i18n:translate="">For quick creation of notes/links bookmark this link</span>:
|
||||
<a href="#"
|
||||
tal:attributes="href view/popupCreateObjectForm">Create loops Note</a>
|
||||
</div>
|
||||
Powered by
|
||||
<b><a href="http://loops.cy55.de">loops</a></b> ·
|
||||
<b><a href="http://wiki.zope.org/zope3">Zope 3</a></b> ·
|
||||
<b><a href="http://www.python.org">Python</a></b> ·
|
||||
<b><a href="http://www.dojotoolkit.org">Dojo</a></b>.
|
||||
</metal:footer>
|
||||
|
||||
|
||||
</div>
|
||||
</tal:block>
|
29
browser/skin/loopy/browser.py
Normal file
29
browser/skin/loopy/browser.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Copyright (c) 2012 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
|
||||
#
|
||||
|
||||
"""
|
||||
Dummy view class for providing the body template.
|
||||
"""
|
||||
|
||||
from cybertools.browser.view import UnboundTemplateFile
|
||||
|
||||
|
||||
class View(object):
|
||||
|
||||
bodyTemplate = UnboundTemplateFile('body.pt')
|
||||
|
33
browser/skin/loopy/custom.css
Normal file
33
browser/skin/loopy/custom.css
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
custom.css
|
||||
|
||||
*/
|
||||
|
||||
body {
|
||||
color: #242424;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #344080;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#global {
|
||||
border-bottom: 1px solid #d0d0d0;
|
||||
margin-bottom: 2px;
|
||||
padding: 2px 0 20px 5px;
|
||||
}
|
||||
|
||||
.language-switch {
|
||||
position: absolute;
|
||||
left: 83%;
|
||||
top: 42px;
|
||||
}
|
||||
|
||||
.page-actions {
|
||||
position: absolute;
|
||||
right: 25px;
|
||||
top: 42px;
|
||||
}
|
||||
|
649
browser/skin/loopy/loops.css
Normal file
649
browser/skin/loopy/loops.css
Normal file
|
@ -0,0 +1,649 @@
|
|||
/*
|
||||
|
||||
settings specific for view / node objects
|
||||
|
||||
*/
|
||||
|
||||
/* general */
|
||||
|
||||
#content {width: 79%}
|
||||
#menu {width: 20%;}
|
||||
#sub-section {width: 0}
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-bottom: 0.4em;
|
||||
border-bottom: None;
|
||||
}
|
||||
|
||||
a[href]:hover {
|
||||
text-decoration: none;
|
||||
color: #803000;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-size: 100%;
|
||||
background-color: #f4f4f4;
|
||||
overflow: scroll;
|
||||
max-height: 35em;
|
||||
}
|
||||
|
||||
ol, ul, p {
|
||||
margin-top: 0.4em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
ol li, ul li {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
blockquote ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* class-specific */
|
||||
|
||||
.breadcrumbs td {
|
||||
padding-left: 0;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-style: italic;
|
||||
/* margin-top: 0.5em;*/
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.fields td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.dialog div.heading {
|
||||
font-weight: bold;
|
||||
font-size: 140%;
|
||||
margin: 0.5em 0 0.3em 0;
|
||||
}
|
||||
|
||||
.dialog label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.dialog div.buttons {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
tr.even td {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tr.odd td {
|
||||
background-color: none;
|
||||
}
|
||||
|
||||
table.listing {
|
||||
margin: 1px;
|
||||
/*margin-top: 0.5em; */
|
||||
margin-bottom: 1em;
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.listing th {
|
||||
color: #000040;
|
||||
padding: 0 2px 0 2px;
|
||||
border: none;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table.listing td {
|
||||
padding: 2px 2px 2px 2px;
|
||||
white-space: normal;
|
||||
vertical-align: middle;
|
||||
border: none;
|
||||
border-bottom: 1px dotted #dddddd;
|
||||
}
|
||||
|
||||
fieldset.box table.listing td {
|
||||
padding: 0 1px 0 1px;
|
||||
}
|
||||
|
||||
table.listing .number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.listing .center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.listing .nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table.listing tr.even {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table.listing td.checkbox {
|
||||
text-align: center;
|
||||
width: 10px;
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
table.listing td.headline {
|
||||
font-weight: bold;
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
table.listing-details td {
|
||||
white-space: normal;
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
table.listing-details tr.heading td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.listing-details tr.heading td h3 {
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.listing th span.ascending {
|
||||
background-image: url(/++resource++cybertools.icons/arrowdown.gif);
|
||||
background-position: right;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
table.listing th span.descending {
|
||||
background-image: url(/++resource++cybertools.icons/arrowup.gif);
|
||||
background-position: right;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
table.records input, table.records textarea {
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
table.records th {
|
||||
background-color: #fefefe;
|
||||
}
|
||||
|
||||
table.records th, table.records td {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
table.report td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
dl.docutils dt {
|
||||
font-weight: bold;
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
dl.docutils dd {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
dl.docutils dd ul li {
|
||||
margin-left: -1em;
|
||||
}
|
||||
|
||||
fieldset.box {
|
||||
margin: 1em 0 0.5em 0;
|
||||
padding: 0.5em;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
fieldset.box td {
|
||||
padding: 0.2em 0.2em 0.2em 0;
|
||||
}
|
||||
|
||||
#body {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.top-actions {
|
||||
position: absolute;
|
||||
right: 2em;
|
||||
top: 1em;
|
||||
}
|
||||
|
||||
.quicksearch {
|
||||
position: absolute;
|
||||
right: 2em;
|
||||
top: 0.8em;
|
||||
}
|
||||
|
||||
.quicksearch input {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.language-switch {
|
||||
position: absolute;
|
||||
right: 2em;
|
||||
top: 2.4em;
|
||||
}
|
||||
|
||||
.page-actions {
|
||||
position: absolute;
|
||||
right: 2em;
|
||||
top: 3.8em;
|
||||
}
|
||||
|
||||
.top image {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.content-1 h1, h1 {
|
||||
font-size: 180%;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
padding-top: 0.6em;
|
||||
}
|
||||
|
||||
.content-2 h1, .content-1 h2, h2 {
|
||||
font-size: 160%;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
|
||||
.content-3 h1, .content-2 h2, .content-1 h3, h3 {
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
padding-top: 0.4em;
|
||||
}
|
||||
|
||||
.content-4 h1, .content-3 h2, .content-2 h3, .content-1 h4, h4 {
|
||||
font-size: 130%;
|
||||
font-weight: normal;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
|
||||
.content-5 h1, .content-4 h2, .content-3 h3, content-2 h4, h5 {
|
||||
font-size: 120%;
|
||||
/* border: none; */
|
||||
padding-top: 0.2em;
|
||||
}
|
||||
|
||||
.box {
|
||||
padding: 0;
|
||||
padding-top: 0;
|
||||
border-left: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.box {
|
||||
margin: 15px 15px 0 15px;
|
||||
/*border-top: 1px solid #ccc;*/
|
||||
/*border-bottom: 1px solid #ccc;*/
|
||||
}
|
||||
|
||||
div.box h4 {
|
||||
font: 110% Verdana, Tahoma, Arial, Helvetica, sans-serif;
|
||||
color: #000040;
|
||||
border: none;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 4px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 3px;
|
||||
background-color: #eee;
|
||||
height: auto;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.box h1, .box h2, .box h3 {
|
||||
border-bottom: None;
|
||||
}
|
||||
|
||||
.box div.body div.even {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.box div.body div {
|
||||
padding: 0.2em 0.2em 0.2em 0.3em;
|
||||
}
|
||||
|
||||
div.action {
|
||||
border-top: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
div.menu-1, div.menu-2 {
|
||||
border-top: 1px solid #eeeeee;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.box div.body div.menu-3 {
|
||||
border-top: none;
|
||||
padding: 0.1em 0 0.2em 1.5em;
|
||||
}
|
||||
|
||||
.box div.body div.menu-4 {
|
||||
padding-left: 3em;
|
||||
font-size: 90%
|
||||
}
|
||||
|
||||
.delete-item a[href] {
|
||||
color: #ff7777;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.subcolumn {
|
||||
display: inline;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: none;
|
||||
margin-top: 12px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.object-actions {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.object-actions {
|
||||
padding: 1.5em 0 0 0;
|
||||
}
|
||||
|
||||
.content-2 .object-actions {
|
||||
padding: 1em 0 0 0;
|
||||
}
|
||||
|
||||
.listing .object-actions {
|
||||
float: none;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.icon-action {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.flow-left {
|
||||
float: left;
|
||||
padding: 0.4em 0.8em 0.8em 0;
|
||||
}
|
||||
|
||||
.flow-right {
|
||||
float: right;
|
||||
padding: 0.4em 0.8em 0.8em 0;
|
||||
}
|
||||
|
||||
div.image {
|
||||
margin-top: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
img.selected {
|
||||
border: 2px solid #d6dcf6;
|
||||
}
|
||||
|
||||
img.notselected {
|
||||
border: 2px solid #eff8ff;
|
||||
}
|
||||
|
||||
.navlink {
|
||||
font-size: 130%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.navlink a {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
margin: 1em 0 0.5em 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin: 1em 0 1em 0;
|
||||
}
|
||||
|
||||
.button a:link, .button a:visited {
|
||||
padding: 2px 4px 2px 4px;
|
||||
background-color: #e8e8e8;
|
||||
text-decoration: None;
|
||||
color: Black;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: #f4f4f4 #989898 #989898 #f4f4f4;
|
||||
}
|
||||
|
||||
.button a:active {
|
||||
border-color: #989898 #f4f4f4 #f4f4f4 #989898;
|
||||
}
|
||||
|
||||
.itemViews {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.dialog .headline {
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
padding: 1em 0 1em 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: #ffbb00;
|
||||
padding: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.error-heading {
|
||||
margin-bottom: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.message {
|
||||
font-weight: bold;
|
||||
background-color: #c3d9ff;
|
||||
padding: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.header-1 {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* view modes (tabs) */
|
||||
|
||||
ul.view-modes {
|
||||
padding: 0 0 0 2em;
|
||||
margin: 0.7em 0 0 0;
|
||||
white-space: nowrap;
|
||||
list-style-type: none;
|
||||
border-bottom: #ccc 1px solid;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
ul.view-modes li {
|
||||
display: inline
|
||||
}
|
||||
|
||||
ul.view-modes li a {
|
||||
padding: 0.15em 1.25em 0.15em 1.25em;
|
||||
margin: 0 0.5em 0 0;
|
||||
text-decoration: none;
|
||||
border: #ccc 1px solid;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
ul.view-modes li.active a {
|
||||
border-bottom: #eee 1px solid;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
ul.view-modes li.inactive a:hover {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
/* comments */
|
||||
|
||||
div.comment {
|
||||
padding: 0.5em;
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #aaaaff;
|
||||
}
|
||||
|
||||
.comment h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.comment .info {
|
||||
font-style: italic;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* search stuff */
|
||||
|
||||
.searchForm input.button, input.submit {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* blog */
|
||||
|
||||
.blog .description {
|
||||
font-size: 90%;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.blogpost .description {
|
||||
font-size: 90%;
|
||||
color: #666666;
|
||||
padding-top: 0.4em;
|
||||
}
|
||||
|
||||
.blog .info, .blogpost .info {
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
color: #666666;
|
||||
padding-top: 0.4em;
|
||||
}
|
||||
|
||||
/* microart */
|
||||
|
||||
.micropart {
|
||||
background-color: #f7f7f7;
|
||||
padding: 0 5px 0 5px;
|
||||
margin: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
.micropart h3,h4,h5 {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.2em;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* calendar, work items */
|
||||
|
||||
.today {
|
||||
color: #444488;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.calendar td.arrows {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
.calendar td.week_number {
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.calendar td.day {
|
||||
width: 12%;
|
||||
}
|
||||
|
||||
.calendar td.today {
|
||||
border: 1px solid red;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.calendar .has_events {
|
||||
font-weight: bold;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
|
||||
/* dojo stuff */
|
||||
|
||||
.dijitDialog {
|
||||
background-color: #aaaaaa;
|
||||
border: 1px solid #999;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.dijitDialogPaneContent {
|
||||
background-color: #aaaaaa;
|
||||
}
|
||||
|
||||
.dijitDialog th {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 0 5px 8px 5px;
|
||||
}
|
||||
|
||||
.dijitDialog td {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.dijitDialog .headline {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dijitDialog input.text {
|
||||
width: 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.dijitDialog input.submit {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dijitDialogUnderlay {
|
||||
background-color: Lightgrey;
|
||||
}
|
||||
|
||||
div.RichTextEditable {
|
||||
border-top: 2px solid grey;
|
||||
border-left: 2px solid grey;
|
||||
border-right: 2px solid #eeeeee;
|
||||
border-bottom: 2px solid #eeeeee;
|
||||
}
|
|
@ -24,6 +24,7 @@ from cgi import parse_qs
|
|||
from zope import interface, component
|
||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.traversing.api import getName
|
||||
|
||||
from cybertools.typology.interfaces import IType
|
||||
from loops.browser.lobo import standard
|
||||
|
@ -52,8 +53,24 @@ class Base(object):
|
|||
|
||||
class SectionView(Base, ConceptView):
|
||||
|
||||
pass
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return book_template.macros['section']
|
||||
|
||||
@Lazy
|
||||
def tabview(self):
|
||||
if self.editable:
|
||||
return 'index.html'
|
||||
|
||||
def getCssClassForResource(self, r):
|
||||
documentType = self.conceptManager['documenttype']
|
||||
for c in r.context.getConcepts([self.defaultPredicate]):
|
||||
if c.conceptType == documentType:
|
||||
return getName(c)
|
||||
return 'textelement'
|
||||
|
||||
|
||||
# layout parts - probably obsolete:
|
||||
|
||||
class PageLayout(Base, standard.Layout):
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ type(u'documenttype', u'Dokumentenart', options=u'qualifier:assign',
|
|||
# book types
|
||||
type(u'book', u'Buch', viewName=u'', typeInterface=u'',
|
||||
options=u'action.portlet:create_subtype,edit_concept')
|
||||
type(u'page', u'Seite', viewName=u'page_layout',
|
||||
typeInterface=u'loops.compound.book.interfaces.IPage',
|
||||
options=u'action.portlet:edit_concept')
|
||||
#type(u'page', u'Seite', viewName=u'page_layout',
|
||||
# typeInterface=u'loops.compound.book.interfaces.IPage',
|
||||
# options=u'action.portlet:edit_concept')
|
||||
type(u'section', u'Kapitel', viewName=u'section_view', typeInterface=u'',
|
||||
options=u'action.portlet:create_subtype,edit_concept')
|
||||
|
||||
|
@ -20,7 +20,7 @@ concept(u'issubtype', u'is Subtype', u'predicate', options=u'hide_children',
|
|||
|
||||
# document types
|
||||
concept(u'keyquestions', u'Leitfragen', u'documenttype')
|
||||
concept(u'maintext', u'Haupttext', u'documenttype')
|
||||
concept(u'textelement', u'Textabschnitt', u'documenttype')
|
||||
concept(u'quote', u'Zitat', u'documenttype')
|
||||
concept(u'story', u'Geschichte', u'documenttype')
|
||||
concept(u'usecase', u'Fallbeispiel', u'documenttype')
|
||||
|
@ -28,4 +28,4 @@ concept(u'usecase', u'Fallbeispiel', u'documenttype')
|
|||
# book structure
|
||||
child(u'book', u'section', u'issubtype', usePredicate=u'ispartof')
|
||||
child(u'section', u'section', u'issubtype', usePredicate=u'ispartof')
|
||||
child(u'section', u'page', u'issubtype', usePredicate=u'ispartof')
|
||||
#child(u'section', u'page', u'issubtype', usePredicate=u'ispartof')
|
||||
|
|
|
@ -1,13 +1,44 @@
|
|||
<html i18n:domain="loops">
|
||||
|
||||
|
||||
<metal:section define-macro="section">
|
||||
<metal:info use-macro="view/concept_macros/concepttitle" />
|
||||
<div tal:repeat="related item/resources">
|
||||
<div class="object-actions" style="padding-top: 0"
|
||||
tal:define="url python:view.getUrlForTarget(related.context)"
|
||||
tal:condition="related/editable">
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit"
|
||||
tal:define="targetUid python:view.getUidForObject(related.context);
|
||||
url
|
||||
string:$url/edit_object.html?version=this&targetUid=$targetUid"
|
||||
tal:attributes="href url;
|
||||
onclick string:objectDialog('edit', '$url');;
|
||||
return false">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/vcard_edit.png" /></a>
|
||||
<a i18n:translate="" i18n:attributes="title"
|
||||
title="Edit with external editor."
|
||||
tal:condition="related/xeditable"
|
||||
tal:attributes="href string:$url/external_edit?version=this">
|
||||
<img tal:attributes="src
|
||||
string:$resourceBase/cybertools.icons/application_edit.png" /></a>
|
||||
</div>
|
||||
<div tal:attributes="class python:
|
||||
item.getCssClassForResource(related)"
|
||||
tal:content="structure related/render" />
|
||||
</div>
|
||||
</metal:section>
|
||||
|
||||
|
||||
<!-- layout part macros - obsolete? -->
|
||||
|
||||
<metal:part define-macro="headline">
|
||||
<div tal:define="cell part/getView">
|
||||
<metal:headline use-macro="item/macros/headline" />
|
||||
</div>
|
||||
</metal:part>
|
||||
|
||||
|
||||
<metal:part define-macro="text">
|
||||
<tal:cell repeat="cell part/getResources">
|
||||
<div tal:attributes="class cell/cssClass">
|
||||
|
|
|
@ -219,7 +219,7 @@ class WorkReportInstance(ReportInstance):
|
|||
|
||||
def getAllSubtasks(self, concept):
|
||||
result = []
|
||||
for c in concept.getChildren():
|
||||
for c in concept.getChildren([self.view.defaultPredicate]):
|
||||
if c.conceptType in self.taskTypes:
|
||||
result.append(c)
|
||||
result.extend(self.getAllSubtasks(c))
|
||||
|
@ -227,7 +227,8 @@ class WorkReportInstance(ReportInstance):
|
|||
|
||||
def selectWorkItems(self, task, parts):
|
||||
# TODO: take states from parts
|
||||
kw = dict(task=util.getUidForObject(task), state=self.states)
|
||||
kw = dict(task=util.getUidForObject(baseObject(task)),
|
||||
state=self.states)
|
||||
if 'userName' in parts:
|
||||
kw['userName'] = parts['userName'].comparisonValue
|
||||
wi = self.workItems
|
||||
|
|
Loading…
Add table
Reference in a new issue