appy.pod: bugfix while including a PDF file into a document; ease the inclusion of Plone images from a Plone/Zope DB through 'do text from document' statements; appy.gen: added obj.mayAct method that allows to display conditionnally the column 'Actions' when an object is shown in a list (query or ref); improved navigation from sub-objects to parent objects; improved layout.
This commit is contained in:
parent
9c5f92337b
commit
13f3400577
|
@ -923,6 +923,15 @@ class BaseMixin:
|
|||
if hasattr(appyObj, 'mayNavigate'): return appyObj.mayNavigate()
|
||||
return True
|
||||
|
||||
def mayAct(self):
|
||||
'''May the currently logged user see column "actions" for this
|
||||
object? This can be used for hiding the "edit" icon, for example:
|
||||
when a user may edit only a restricted set of fields on an object,
|
||||
we may avoid showing him the global "edit" icon.'''
|
||||
appyObj = self.appy()
|
||||
if hasattr(appyObj, 'mayAct'): return appyObj.mayAct()
|
||||
return True
|
||||
|
||||
def mayDelete(self):
|
||||
'''May the currently logged user delete this object? This condition
|
||||
comes as an addition/refinement to the corresponding workflow
|
||||
|
@ -1291,6 +1300,13 @@ class BaseMixin:
|
|||
'''Returns a reference to the config module.'''
|
||||
return self.__class__.config
|
||||
|
||||
def getParent(self):
|
||||
'''If this object is stored within another one, this method returns it.
|
||||
Else (if the object is stored directly within the tool or the root
|
||||
data folder) it returns None.'''
|
||||
parent = self.getParentNode()
|
||||
if parent.meta_type != 'Folder': return parent
|
||||
|
||||
def index_html(self):
|
||||
'''Redirects to /ui.'''
|
||||
return self.REQUEST.RESPONSE.redirect(self.getUrl())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
body { font: 75% Lucida,Helvetica,Arial,sans-serif; background-color: #EAEAEA; }
|
||||
pre { font: 100% Lucida,Helvetica,Arial,sans-serif; margin: 0}
|
||||
body { font: 75% Helvetica,Arial,sans-serif; background-color: #EAEAEA; }
|
||||
pre { font: 100% Helvetica,Arial,sans-serif; margin: 0}
|
||||
h1 { font-size: 11pt; margin:0;}
|
||||
h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;}
|
||||
h3 { font-size: 9pt; margin:0; font-weight: bold;}
|
||||
|
@ -19,13 +19,13 @@ input[type=button] { border: 1px solid #cccccc;
|
|||
input[type=submit] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
cursor: pointer; }
|
||||
input[type=password] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
font-family: Lucida,Helvetica,Arial,sans-serif;}
|
||||
font-family: Helvetica,Arial,sans-serif;}
|
||||
input[type=text] { border: 1px solid #cccccc; background-color: #f8f8f8;
|
||||
font-family: Lucida,Helvetica,Arial,sans-serif;
|
||||
font-family: Helvetica,Arial,sans-serif;
|
||||
margin-bottom: 1px}
|
||||
select { border: 1px solid #cccccc; background-color: #f8f8f8;}
|
||||
|
||||
textarea { width: 99%; font: 100% Lucida,Helvetica,Arial,sans-serif;
|
||||
textarea { width: 99%; font: 100% Helvetica,Arial,sans-serif;
|
||||
border: 1px solid #a79e9e; background-color: #f8f8f8;}
|
||||
label { font-weight: 600; font-style: italic; line-height: 1.4em;}
|
||||
legend { padding-bottom: 2px; padding-right: 3px; color: black;}
|
||||
|
@ -40,19 +40,19 @@ img {border: 0}
|
|||
border-style: solid; border-width: 1px; border-color: grey; }
|
||||
.top { height: 75px; margin-left: 3em; vertical-align: top;}
|
||||
.lang { margin-right: 3px; }
|
||||
.userStrip { background-color: #89A6B1; height: 40px;
|
||||
border-top: 3px solid #405A64; border-bottom: 2px solid #5F7983; }
|
||||
.userStrip { background-color: #d7dee4; height: 40px;
|
||||
border-top: 1px solid #5F7983; border-bottom: 1px solid #5F7983; }
|
||||
.login { margin-top: 2px; margin-bottom: 2px; color: white;}
|
||||
.buttons { margin-left: 4px;}
|
||||
.message { color: #fd9c03; position: absolute; top: -55px; left: 100px;
|
||||
width: 700px; border: 1px black dashed; padding: 2px 6px;
|
||||
background-color: #f4f5f6}
|
||||
.discreet { font-size: 90%; }
|
||||
.portlet { width: 150px; padding: 12px 9px 9px 9px;
|
||||
border-right: 2px solid #5F7983;}
|
||||
.portlet { width: 150px; border-right: 1px solid #5F7983;}
|
||||
.portletContent { margin: 9px; }
|
||||
.portletTitle { font-weight: bold; font-size: 110%; margin-bottom: 4px;}
|
||||
.portletCurrent { font-weight: bold; }
|
||||
.portletSep { border-top: 1px solid grey; margin-top: 9px; padding-top: 9px;}
|
||||
.portletSep { border-top: 1px solid #5F7983; margin-top: 2px;}
|
||||
.portletPage { font-style: italic; }
|
||||
.portletGroup { font-variant: small-caps; font-weight: bold; font-style: normal;
|
||||
margin: 0.4em 0 0.2em 0; }
|
||||
|
@ -68,7 +68,7 @@ img {border: 0}
|
|||
.list { border: 1px solid grey; margin-bottom: 3px;}
|
||||
.list td, .list th { border: 1px solid grey;
|
||||
padding-left: 5px; padding-right: 5px; padding-top: 3px;}
|
||||
.list th { background-color: #c8d7e1; font-style: italic; font-weight: normal;}
|
||||
.list th { background-color: #d7dee4; font-style: italic; font-weight: normal;}
|
||||
.grid th { font-style: italic; font-weight: normal;
|
||||
border-bottom: 2px solid grey; padding: 2px 2px;}
|
||||
.grid td { padding-right: 5px; }
|
||||
|
|
|
@ -63,15 +63,15 @@
|
|||
backText navInfo/backText">
|
||||
<tr valign="middle">
|
||||
<tal:comment replace="nothing">Go to the source URL (search or referred object)</tal:comment>
|
||||
<td tal:condition="sourceUrl"><a tal:attributes="href sourceUrl"><img style="cursor:pointer"
|
||||
<td tal:condition="sourceUrl"><a tal:attributes="href sourceUrl"><img
|
||||
tal:attributes="src string: $appUrl/ui/gotoSource.png;
|
||||
title python: backText + ' : ' + tool.translate('goto_source')"/></a></td>
|
||||
<tal:comment replace="nothing">Go to the first page</tal:comment>
|
||||
<td tal:condition="firstUrl"><a tal:attributes="href firstUrl"><img style="cursor:pointer"
|
||||
<td tal:condition="firstUrl"><a tal:attributes="href firstUrl"><img
|
||||
tal:attributes="src string: $appUrl/ui/arrowLeftDouble.png;
|
||||
title python: tool.translate('goto_first')"/></a></td>
|
||||
<tal:comment replace="nothing">Go to the previous page</tal:comment>
|
||||
<td tal:condition="previousUrl"><a tal:attributes="href previousUrl"><img style="cursor:pointer"
|
||||
<td tal:condition="previousUrl"><a tal:attributes="href previousUrl"><img
|
||||
tal:attributes="src string: $appUrl/ui/arrowLeftSimple.png;
|
||||
title python: tool.translate('goto_previous')"/></a></td>
|
||||
<tal:comment replace="nothing">Explain which element is currently shown</tal:comment>
|
||||
|
@ -80,11 +80,11 @@
|
|||
<span tal:replace="python: totalNumber"/>
|
||||
</td>
|
||||
<tal:comment replace="nothing">Go to the next page</tal:comment>
|
||||
<td tal:condition="python: nextUrl"><a tal:attributes="href nextUrl"><img style="cursor:pointer"
|
||||
<td tal:condition="python: nextUrl"><a tal:attributes="href nextUrl"><img
|
||||
tal:attributes="src string: $appUrl/ui/arrowRightSimple.png;
|
||||
title python: tool.translate('goto_next')"/></a></td>
|
||||
<tal:comment replace="nothing">Go to the last page</tal:comment>
|
||||
<td tal:condition="lastUrl"><a tal:attributes="href lastUrl"><img style="cursor:pointer"
|
||||
<td tal:condition="lastUrl"><a tal:attributes="href lastUrl"><img
|
||||
tal:attributes="src string: $appUrl/ui/arrowRightDouble.png;
|
||||
title python: tool.translate('goto_last')"/></a></td>
|
||||
</tr>
|
||||
|
|
|
@ -9,49 +9,56 @@
|
|||
contextObj tool/getPublishedObject;
|
||||
rootClasses tool/getRootClasses">
|
||||
|
||||
<tal:publishedObject condition="python: contextObj and contextObj.mayNavigate()">
|
||||
<div class="portletTitle" tal:content="contextObj/Title"></div>
|
||||
<div class="portletContent" tal:condition="python: contextObj and contextObj.mayNavigate()">
|
||||
<div class="portletTitle" tal:define="parent contextObj/getParent">
|
||||
<span tal:replace="contextObj/Title"></span>
|
||||
<div style="float:right" tal:condition="python: parent">
|
||||
<a tal:attributes="href parent/absolute_url">
|
||||
<img tal:attributes="src string: $appUrl/ui/gotoSource.png"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<span><metal:phases use-macro="here/ui/portlet/macros/phases"/></span>
|
||||
</tal:publishedObject>
|
||||
</div>
|
||||
|
||||
<tal:comment replace="nothing">One section for every searchable root class.</tal:comment>
|
||||
<tal:section repeat="rootClass python: [rc for rc in rootClasses if tool.userMaySearch(rc)]">
|
||||
<tal:comment replace="nothing">Section title, with action icons</tal:comment>
|
||||
<table width="100%"
|
||||
tal:attributes="class python:test((repeat['rootClass'].number()==1) and not contextObj, '', 'portletSep')">
|
||||
<tr>
|
||||
<td>
|
||||
<a tal:attributes="href python: '%s?className=%s' % (queryUrl, rootClass);
|
||||
class python:test(not currentSearch and (currentClass==rootClass), 'portletCurrent', '')"
|
||||
tal:content="structure python: _(rootClass + '_plural')"></a>
|
||||
</td>
|
||||
<td align="right"
|
||||
tal:define="addPermission python: '%s: Add %s' % (appName, rootClass);
|
||||
userMayAdd python: user.has_permission(addPermission, appFolder);
|
||||
createMeans python: tool.getCreateMeans(rootClass)">
|
||||
<tal:comment replace="nothing">Create a new object from a web form</tal:comment>
|
||||
<a tal:condition="python: ('form' in createMeans) and userMayAdd"
|
||||
tal:attributes="href python: '%s/do?action=Create&className=%s' % (toolUrl, rootClass);
|
||||
title python: _('query_create')">
|
||||
<img tal:attributes="src string: $appUrl/ui/plus.png"/>
|
||||
</a>
|
||||
<tal:comment replace="nothing">Create (a) new object(s) by importing data</tal:comment>
|
||||
<a tal:condition="python: ('import' in createMeans) and userMayAdd"
|
||||
tal:attributes="href python: '%s/ui/import?className=%s' % (toolUrl, rootClass);
|
||||
title python: _('query_import')">
|
||||
<img tal:attributes="src string: $appUrl/ui/import.png"/>
|
||||
</a>
|
||||
<tal:comment replace="nothing">Search objects of this type</tal:comment>
|
||||
<a tal:define="showSearch python: tool.getAttr('enableAdvancedSearchFor%s' % rootClass)"
|
||||
tal:condition="showSearch"
|
||||
tal:attributes="href python: '%s/ui/search?className=%s' % (toolUrl, rootClass);
|
||||
title python: _('search_objects')">
|
||||
<img tal:attributes="src string: $appUrl/ui/search.gif"/>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tal:comment replace="nothing">Searches for this content type.</tal:comment>
|
||||
<tal:comment replace="nothing">One section for every searchable root class.</tal:comment>
|
||||
<tal:section repeat="rootClass python: [rc for rc in rootClasses if tool.userMaySearch(rc)]">
|
||||
|
||||
<tal:comment replace="nothing">A separator if required</tal:comment>
|
||||
<div class="portletSep" tal:define="nb repeat/rootClass/number"
|
||||
tal:condition="python: (nb == 1 and contextObj) or (nb != 1)"></div>
|
||||
|
||||
<div class="portletContent">
|
||||
<tal:comment replace="nothing">Section title, with action icons</tal:comment>
|
||||
<a tal:attributes="href python: '%s?className=%s' % (queryUrl, rootClass);
|
||||
class python:test(not currentSearch and (currentClass==rootClass), 'portletCurrent', '')"
|
||||
tal:content="structure python: _(rootClass + '_plural')">
|
||||
</a>
|
||||
<div style="float: right"
|
||||
tal:define="addPermission python: '%s: Add %s' % (appName, rootClass);
|
||||
userMayAdd python: user.has_permission(addPermission, appFolder);
|
||||
createMeans python: tool.getCreateMeans(rootClass)">
|
||||
<tal:comment replace="nothing">Create a new object from a web form</tal:comment>
|
||||
<a tal:condition="python: ('form' in createMeans) and userMayAdd"
|
||||
tal:attributes="href python: '%s/do?action=Create&className=%s' % (toolUrl, rootClass);
|
||||
title python: _('query_create')">
|
||||
<img tal:attributes="src string: $appUrl/ui/plus.png"/>
|
||||
</a>
|
||||
<tal:comment replace="nothing">Create (a) new object(s) by importing data</tal:comment>
|
||||
<a tal:condition="python: ('import' in createMeans) and userMayAdd"
|
||||
tal:attributes="href python: '%s/ui/import?className=%s' % (toolUrl, rootClass);
|
||||
title python: _('query_import')">
|
||||
<img tal:attributes="src string: $appUrl/ui/import.png"/>
|
||||
</a>
|
||||
<tal:comment replace="nothing">Search objects of this type</tal:comment>
|
||||
<a tal:define="showSearch python: tool.getAttr('enableAdvancedSearchFor%s' % rootClass)"
|
||||
tal:condition="showSearch"
|
||||
tal:attributes="href python: '%s/ui/search?className=%s' % (toolUrl, rootClass);
|
||||
title python: _('search_objects')">
|
||||
<img tal:attributes="src string: $appUrl/ui/search.gif"/>
|
||||
</a>
|
||||
</div>
|
||||
<tal:comment replace="nothing">Searches for this content type.</tal:comment>
|
||||
<tal:searchOrGroup repeat="searchOrGroup python: tool.getSearches(rootClass)">
|
||||
<tal:group condition="searchOrGroup/isGroup">
|
||||
<tal:expanded define="group searchOrGroup;
|
||||
|
@ -84,7 +91,7 @@
|
|||
class python: test(search['name'] == currentSearch, 'portletCurrent', '');"
|
||||
tal:content="structure search/label"></a>
|
||||
</dt>
|
||||
</tal:searchOrGroup>
|
||||
</tal:searchOrGroup>
|
||||
</tal:section>
|
||||
</metal:portlet>
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
|
||||
<tal:comment replace="nothing">Column "Actions"</tal:comment>
|
||||
<td align="right">
|
||||
<table class="noStyle">
|
||||
<table class="noStyle" tal:condition="obj/mayAct">
|
||||
<tr>
|
||||
<tal:comment replace="nothing">Edit the element</tal:comment>
|
||||
<td>
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table width="99%">
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr valign="top">
|
||||
<tal:comment replace="nothing">Portlet</tal:comment>
|
||||
<td tal:condition="python: tool.showPortlet(context)" class="portlet">
|
||||
|
|
|
@ -210,7 +210,9 @@
|
|||
</td>
|
||||
<tal:comment replace="nothing">Actions</tal:comment>
|
||||
<td align="right">
|
||||
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" />
|
||||
<tal:show condition="obj/mayAct">
|
||||
<metal:showObjectActions use-macro="app/ui/widgets/ref/macros/objectActions" />
|
||||
</tal:show>
|
||||
</td>
|
||||
</tr>
|
||||
</tal:row>
|
||||
|
|
|
@ -146,7 +146,7 @@ class PdfImporter(DocImporter):
|
|||
if os.path.exists(nextImage):
|
||||
# Use internally an Image importer for doing this job.
|
||||
imgImporter =ImageImporter(None, nextImage, 'jpg',self.renderer)
|
||||
imgImporter.setAnchor('paragraph')
|
||||
imgImporter.setImageInfo('paragraph', True, None, None, None)
|
||||
self.res += imgImporter.run()
|
||||
os.remove(nextImage)
|
||||
else:
|
||||
|
|
|
@ -297,6 +297,9 @@ class Renderer:
|
|||
# Guess document format
|
||||
if isinstance(content, FileWrapper):
|
||||
format = content.mimeType
|
||||
elif hasattr(content, 'filename') and content.filename:
|
||||
format = os.path.splitext(content.filename)[1][1:]
|
||||
content = content.data
|
||||
if not format:
|
||||
# It should be deduced from p_at
|
||||
if not at:
|
||||
|
|
Loading…
Reference in a new issue