Merge branch 'adapted_with_request'
Conflicts: integrator/testdata/office/example.docx
This commit is contained in:
commit
b6a0621283
5 changed files with 180 additions and 35 deletions
|
@ -312,7 +312,7 @@ class BaseView(GenericView, I18NView):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def adapted(self):
|
def adapted(self):
|
||||||
return adapted(self.context, self.languageInfo)
|
return adapted(self.context, self.languageInfo, self.request)
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def baseObject(self):
|
def baseObject(self):
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -43,10 +43,11 @@ from loops import util
|
||||||
|
|
||||||
# convenience functions
|
# convenience functions
|
||||||
|
|
||||||
def adapted(obj, langInfo=None):
|
def adapted(obj, langInfo=None, request=None):
|
||||||
""" Return adapter based on the object type's type interface.
|
""" Return adapter based on the object type's type interface.
|
||||||
"""
|
"""
|
||||||
if isinstance(obj, AdapterBase):
|
if isinstance(obj, AdapterBase):
|
||||||
|
obj.request = request
|
||||||
return obj
|
return obj
|
||||||
t = IType(obj, None)
|
t = IType(obj, None)
|
||||||
if t is not None:
|
if t is not None:
|
||||||
|
@ -57,6 +58,7 @@ def adapted(obj, langInfo=None):
|
||||||
if isinstance(adapted, I18NAdapterBase):
|
if isinstance(adapted, I18NAdapterBase):
|
||||||
adapted.languageInfo = langInfo
|
adapted.languageInfo = langInfo
|
||||||
if adapted is not None:
|
if adapted is not None:
|
||||||
|
adapted.request = request
|
||||||
return adapted
|
return adapted
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
@ -98,7 +100,7 @@ class AdapterBase(object):
|
||||||
|
|
||||||
adapts(IConcept)
|
adapts(IConcept)
|
||||||
|
|
||||||
_adapterAttributes = ('context', '__parent__',)
|
_adapterAttributes = ('context', '__parent__', 'request')
|
||||||
_contextAttributes = list(IConcept)
|
_contextAttributes = list(IConcept)
|
||||||
_noexportAttributes = ()
|
_noexportAttributes = ()
|
||||||
_textIndexAttributes = ()
|
_textIndexAttributes = ()
|
||||||
|
|
|
@ -200,6 +200,7 @@ class ILoopsAdapter(IConceptSchema):
|
||||||
|
|
||||||
context = Attribute('The underlying persistent object.')
|
context = Attribute('The underlying persistent object.')
|
||||||
uid = Attribute('Unique id of the context object.')
|
uid = Attribute('Unique id of the context object.')
|
||||||
|
request = Attribute('A a mapping with current settings, optional.')
|
||||||
|
|
||||||
def getChildren():
|
def getChildren():
|
||||||
""" Return a collection of child objects provided by the context
|
""" Return a collection of child objects provided by the context
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
Definition of basic view classes and other browser related stuff for the
|
Definition of basic view classes and other browser related stuff for the
|
||||||
loops.search package.
|
loops.search package.
|
||||||
|
|
||||||
$Id$
|
$Id: browser.py 4160 2011-02-07 16:53:08Z helmutm $
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import interface, component
|
from zope import interface, component
|
||||||
|
@ -32,11 +32,13 @@ from zope.i18nmessageid import MessageFactory
|
||||||
|
|
||||||
from cybertools.ajax import innerHtml
|
from cybertools.ajax import innerHtml
|
||||||
from cybertools.relation.interfaces import IRelationRegistry
|
from cybertools.relation.interfaces import IRelationRegistry
|
||||||
|
from cybertools.stateful.interfaces import IStateful, IStatesDefinition
|
||||||
from cybertools.typology.interfaces import ITypeManager
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.browser.common import BaseView
|
from loops.browser.common import BaseView
|
||||||
from loops.browser.node import NodeView
|
from loops.browser.node import NodeView
|
||||||
from loops.common import adapted, AdapterBase
|
from loops.common import adapted, AdapterBase
|
||||||
from loops.expert.concept import ConceptQuery, FullQuery
|
from loops.expert.concept import ConceptQuery, FullQuery
|
||||||
|
from loops.interfaces import IResource
|
||||||
from loops.organize.personal.browser.filter import FilterView
|
from loops.organize.personal.browser.filter import FilterView
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
@ -151,17 +153,90 @@ class Search(BaseView):
|
||||||
def getRowName(self, obj):
|
def getRowName(self, obj):
|
||||||
return obj.getLongTitle()
|
return obj.getLongTitle()
|
||||||
|
|
||||||
def getRowLabel(self, obj, name):
|
def getRowLabel(self, obj, name=None):
|
||||||
if isinstance(obj, AdapterBase):
|
if isinstance(obj, AdapterBase):
|
||||||
obj = obj.context
|
obj = obj.context
|
||||||
|
if name is None:
|
||||||
|
name = obj.title
|
||||||
return '%s (%s)' % (name, obj.conceptType.title)
|
return '%s (%s)' % (name, obj.conceptType.title)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def statesDefinitions(self):
|
||||||
|
return [component.getUtility(IStatesDefinition, name=n)
|
||||||
|
for n in self.globalOptions('organize.stateful.resource', ())]
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def selectedStates(self):
|
||||||
|
result = {}
|
||||||
|
for k, v in self.request.form.items():
|
||||||
|
if k.startswith('state.') and v:
|
||||||
|
result[k] = v
|
||||||
|
return result
|
||||||
|
|
||||||
def submitReplacing(self, targetId, formId, view):
|
def submitReplacing(self, targetId, formId, view):
|
||||||
self.registerDojo()
|
self.registerDojo()
|
||||||
return 'submitReplacing("%s", "%s", "%s"); return false;' % (
|
return 'submitReplacing("%s", "%s", "%s"); return false;' % (
|
||||||
targetId, formId,
|
targetId, formId,
|
||||||
'%s/.target%s/@@searchresults.html' % (view.url, self.uniqueId))
|
'%s/.target%s/@@searchresults.html' % (view.url, self.uniqueId))
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def results(self):
|
||||||
|
form = self.request.form
|
||||||
|
type = form.get('search.1.text', 'loops:*')
|
||||||
|
text = form.get('search.2.text')
|
||||||
|
if text is not None:
|
||||||
|
text = util.toUnicode(text, encoding='ISO8859-15') # IE hack!!!
|
||||||
|
useTitle = form.get('search.2.title')
|
||||||
|
useFull = form.get('search.2.full')
|
||||||
|
conceptType = form.get('search.3.type', 'loops:concept:*')
|
||||||
|
#conceptTitle = form.get('search.3.text')
|
||||||
|
#if conceptTitle is not None:
|
||||||
|
# conceptTitle = util.toUnicode(conceptTitle, encoding='ISO8859-15')
|
||||||
|
conceptUid = form.get('search.3.text')
|
||||||
|
result = FullQuery(self).query(text=text, type=type,
|
||||||
|
useTitle=useTitle, useFull=useFull,
|
||||||
|
#conceptTitle=conceptTitle,
|
||||||
|
conceptUid=conceptUid,
|
||||||
|
conceptType=conceptType)
|
||||||
|
rowNum = 4
|
||||||
|
while rowNum < 10:
|
||||||
|
addCriteria = form.get('search.%i.text_selected' % rowNum)
|
||||||
|
rowNum += 1
|
||||||
|
if not addCriteria:
|
||||||
|
break
|
||||||
|
if addCriteria == 'none':
|
||||||
|
continue
|
||||||
|
addSelection = FullQuery(self).query(text=text, type=type,
|
||||||
|
useTitle=useTitle, useFull=useFull,
|
||||||
|
conceptUid=addCriteria)
|
||||||
|
if result:
|
||||||
|
result = [r for r in result if r in addSelection]
|
||||||
|
else:
|
||||||
|
result = addSelection
|
||||||
|
result = [r for r in result if self.checkStates(r)]
|
||||||
|
fv = FilterView(self.context, self.request)
|
||||||
|
result = fv.apply(result)
|
||||||
|
result = sorted(result, key=lambda x: x.title.lower())
|
||||||
|
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.'):]
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
stf = component.queryAdapter(obj, IStateful, name=std)
|
||||||
|
if stf is None:
|
||||||
|
continue
|
||||||
|
for state in states:
|
||||||
|
if stf.state == state:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
#class SearchResults(BaseView):
|
#class SearchResults(BaseView):
|
||||||
class SearchResults(NodeView):
|
class SearchResults(NodeView):
|
||||||
|
|
123
search/search.pt
123
search/search.pt
|
@ -4,7 +4,8 @@
|
||||||
tal:define="macros item/search_macros;
|
tal:define="macros item/search_macros;
|
||||||
idPrefix string:${view/itemNum}.search;
|
idPrefix string:${view/itemNum}.search;
|
||||||
formId string:$idPrefix.form;
|
formId string:$idPrefix.form;
|
||||||
resultsId string:$idPrefix.results">
|
resultsId string:$idPrefix.results;
|
||||||
|
submitted request/search.submitted|nothing">
|
||||||
<h1 tal:attributes="class string:content-$level;
|
<h1 tal:attributes="class string:content-$level;
|
||||||
ondblclick item/openEditWindow"
|
ondblclick item/openEditWindow"
|
||||||
tal:content="item/title">
|
tal:content="item/title">
|
||||||
|
@ -19,7 +20,8 @@
|
||||||
<input type="hidden" name="search.resultsId" value="1.results"
|
<input type="hidden" name="search.resultsId" value="1.results"
|
||||||
tal:attributes="value resultsId" />
|
tal:attributes="value resultsId" />
|
||||||
<table cellpadding="3">
|
<table cellpadding="3">
|
||||||
<tal:block repeat="search_param python: ['type', 'text', 'concept']">
|
<tal:block repeat="search_param python:
|
||||||
|
['type', 'text', 'concept', 'state']">
|
||||||
<metal:row use-macro="macros/search_row" />
|
<metal:row use-macro="macros/search_row" />
|
||||||
</tal:block>
|
</tal:block>
|
||||||
<tr tal:condition="nothing">
|
<tr tal:condition="nothing">
|
||||||
|
@ -30,10 +32,10 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td colspan="3">
|
<td colspan="3"><br />
|
||||||
<input type="submit" name="button.search" value="Search" class="submit"
|
<input type="submit" name="button.search" value="Search" class="submit"
|
||||||
i18n:attributes="value"
|
i18n:attributes="value"
|
||||||
tal:attributes="onclick python:
|
tal:attributes="xx_onclick python:
|
||||||
item.submitReplacing(resultsId, formId, view)" />
|
item.submitReplacing(resultsId, formId, view)" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -45,7 +47,7 @@
|
||||||
<div metal:define-macro="search_results" id="1.search.results"
|
<div metal:define-macro="search_results" id="1.search.results"
|
||||||
tal:attributes="id resultsId | request/search.resultsId"
|
tal:attributes="id resultsId | request/search.resultsId"
|
||||||
i18n:domain="loops"
|
i18n:domain="loops"
|
||||||
tal:define="item nocall:view;
|
xtal:define="item nocall:view;
|
||||||
controller nocall:view/@@controller;
|
controller nocall:view/@@controller;
|
||||||
resourceBase controller/resourceBase;">
|
resourceBase controller/resourceBase;">
|
||||||
<fieldset class="box"
|
<fieldset class="box"
|
||||||
|
@ -140,12 +142,15 @@
|
||||||
tal:attributes="for string:$idPrefix.text">
|
tal:attributes="for string:$idPrefix.text">
|
||||||
<span i18n:translate="">Type</span>:</label>
|
<span i18n:translate="">Type</span>:</label>
|
||||||
<select name="text"
|
<select name="text"
|
||||||
tal:attributes="name string:$namePrefix.text;
|
tal:define="name string:$namePrefix.text;
|
||||||
id string:$idPrefix.text;">
|
value request/?name|nothing"
|
||||||
|
tal:attributes="name name;
|
||||||
|
id string:$idPrefix.text;">
|
||||||
<tal:types repeat="type item/typesForSearch">
|
<tal:types repeat="type item/typesForSearch">
|
||||||
<option value="loops:*"
|
<option value="loops:*"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:attributes="value type/token"
|
tal:attributes="value type/token;
|
||||||
|
selected python: value == type.token"
|
||||||
tal:content="type/title">Topic</option>
|
tal:content="type/title">Topic</option>
|
||||||
</tal:types>
|
</tal:types>
|
||||||
</select>
|
</select>
|
||||||
|
@ -167,17 +172,19 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" checked
|
<input type="checkbox" value="yes"
|
||||||
name="title" id="title" value="yes"
|
tal:define="name string:$namePrefix.title"
|
||||||
tal:attributes="name string:$namePrefix.title;
|
tal:attributes="name name;
|
||||||
id string:$idPrefix.title;" />
|
id string:$idPrefix.title;
|
||||||
|
checked request/?name|not:submitted|string:yes" />
|
||||||
<label for="title"
|
<label for="title"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:attributes="for string:$idPrefix.title">Title</label>
|
tal:attributes="for string:$idPrefix.title">Title</label>
|
||||||
<input type="checkbox"
|
<input type="checkbox" value="yes"
|
||||||
name="full" id="full" value="yes"
|
tal:define="name string:$namePrefix.full"
|
||||||
tal:attributes="name string:$namePrefix.full;
|
tal:attributes="name name;
|
||||||
id string:$idPrefix.full;" />
|
id string:$idPrefix.full;
|
||||||
|
checked request/?name|nothing" />
|
||||||
<label for="full"
|
<label for="full"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:attributes="for string:$idPrefix.full">Full text</label>
|
tal:attributes="for string:$idPrefix.full">Full text</label>
|
||||||
|
@ -188,9 +195,11 @@
|
||||||
<span i18n:translate="">Search text</span>:</label>
|
<span i18n:translate="">Search text</span>:</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" name="text"
|
<input type="text"
|
||||||
tal:attributes="name string:$namePrefix.text;
|
tal:define="name string:$namePrefix.text"
|
||||||
id string:$idPrefix.text;" />
|
tal:attributes="name name;
|
||||||
|
id string:$idPrefix.text;
|
||||||
|
value request/?name|nothing" />
|
||||||
<input type="button" value="+"
|
<input type="button" value="+"
|
||||||
title="Add search word"
|
title="Add search word"
|
||||||
tal:condition="nothing" />
|
tal:condition="nothing" />
|
||||||
|
@ -224,10 +233,13 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select name="text_selected"
|
<select name="text_selected"
|
||||||
tal:attributes="name string:$namePrefix.text_selected;
|
tal:define="name string:$namePrefix.text_selected;
|
||||||
|
value request/?name|nothing"
|
||||||
|
tal:attributes="name name;
|
||||||
id string:$idPrefix.text;">
|
id string:$idPrefix.text;">
|
||||||
<tal:concepts repeat="concept python: item.conceptsForType(type['token'])">
|
<tal:concepts repeat="concept python: item.conceptsForType(type['token'])">
|
||||||
<option tal:attributes="value concept/token"
|
<option tal:attributes="value concept/token;
|
||||||
|
selected python: value == concept['token']"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:content="concept/title">Zope Corp</option>
|
tal:content="concept/title">Zope Corp</option>
|
||||||
</tal:concepts>
|
</tal:concepts>
|
||||||
|
@ -242,13 +254,17 @@
|
||||||
tal:attributes="for string:$idPrefix.type">
|
tal:attributes="for string:$idPrefix.type">
|
||||||
<span i18n:translate="">Type</span>:</label>
|
<span i18n:translate="">Type</span>:</label>
|
||||||
<select name="type"
|
<select name="type"
|
||||||
tal:attributes="name string:$namePrefix.type;
|
tal:define="name string:$namePrefix.type;
|
||||||
|
global conceptTypeValue request/?name|string:"
|
||||||
|
tal:attributes="name name;
|
||||||
id string:$idPrefix.type;
|
id string:$idPrefix.type;
|
||||||
|
value conceptTypeValue;
|
||||||
onChange string:setConceptTypeForComboBox('$idPrefix.type', '$idPrefix.text')">
|
onChange string:setConceptTypeForComboBox('$idPrefix.type', '$idPrefix.text')">
|
||||||
<tal:types repeat="type item/conceptTypesForSearch">
|
<tal:types repeat="type item/conceptTypesForSearch">
|
||||||
<option value="loops:*"
|
<option value="loops:*"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
tal:attributes="value type/token"
|
tal:attributes="value type/token;
|
||||||
|
selected python: conceptTypeValue == type.token"
|
||||||
tal:content="type/title">Topic</option>
|
tal:content="type/title">Topic</option>
|
||||||
</tal:types>
|
</tal:types>
|
||||||
</select>
|
</select>
|
||||||
|
@ -266,23 +282,74 @@
|
||||||
tal:condition="nothing" />
|
tal:condition="nothing" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<tal:combo tal:define="dummy item/initDojo">
|
<tal:combo tal:define="dummy item/initDojo;
|
||||||
|
name string:$namePrefix.text;
|
||||||
|
value request/?name|nothing;
|
||||||
|
concept python:
|
||||||
|
value and view.getObjectForUid(value);
|
||||||
|
displayValue python:
|
||||||
|
concept and concept.title or u''">
|
||||||
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
||||||
url="listConceptsForComboBox.js?searchType=" >
|
url="listConceptsForComboBox.js?searchType="
|
||||||
|
tal:attributes="url
|
||||||
|
string:listConceptsForComboBox.js?searchType=$conceptTypeValue">
|
||||||
</div>
|
</div>
|
||||||
<input dojoType="dijit.form.FilteringSelect" store="conceptSearch"
|
<input dojoType="dijit.form.FilteringSelect" store="conceptSearch"
|
||||||
autoComplete="False" labelAttr="label" style="height: 16px"
|
autoComplete="False" labelAttr="label" style="height: 16px"
|
||||||
name="concept.search.text" id="concept.search.text"
|
name="concept.search.text" id="concept.search.text"
|
||||||
tal:attributes="name string:$namePrefix.text;
|
tal:attributes="name name;
|
||||||
id string:$idPrefix.text" />
|
id string:$idPrefix.text;
|
||||||
|
displayedValue displayValue" />
|
||||||
</tal:combo>
|
</tal:combo>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</metal:text>
|
</metal:text>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:text define-macro="state"
|
||||||
|
tal:define="stateDefs item/statesDefinitions;
|
||||||
|
deftype string:resource"
|
||||||
|
tal:condition="stateDefs">
|
||||||
|
<tr>
|
||||||
|
<td metal:use-macro="macros/minus"/>
|
||||||
|
<td colspan="3">
|
||||||
|
<h2 i18n:translate="">Restrict to objects with certain states</h2>
|
||||||
|
</td>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<th i18n:translate="">Workflow</th>
|
||||||
|
<th colspan="2"
|
||||||
|
i18n:translate="">States</th>
|
||||||
|
</tr>
|
||||||
|
<tr tal:repeat="def stateDefs">
|
||||||
|
<td></td>
|
||||||
|
<td valign="top"
|
||||||
|
tal:content="def/name"
|
||||||
|
i18n:translate=""></td>
|
||||||
|
<td colspan="2">
|
||||||
|
<tal:states repeat="state def/states">
|
||||||
|
<tal:state define="name string:state.$deftype.${def/name};
|
||||||
|
value state/name">
|
||||||
|
<input type="checkbox"
|
||||||
|
tal:attributes="name string:$name:list;
|
||||||
|
value value;
|
||||||
|
checked python:
|
||||||
|
value in item.selectedStates.get(name, ());
|
||||||
|
id string:$name.$value"
|
||||||
|
/> <label tal:content="state/title"
|
||||||
|
i18n:translate=""
|
||||||
|
tal:attributes="for string:$name.$value" />
|
||||||
|
|
||||||
|
</tal:state>
|
||||||
|
</tal:states>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</metal:text>
|
||||||
|
|
||||||
|
|
||||||
<td metal:define-macro="minus">
|
<td metal:define-macro="minus">
|
||||||
<input type="button" value="−"
|
<input type="button" value="−"
|
||||||
title="Remove search parameter"
|
title="Remove search parameter"
|
||||||
tal:condition="python: param not in ['type', 'text', 'concept']" />
|
tal:condition="python:
|
||||||
|
param not in ['type', 'text', 'concept', 'state']" />
|
||||||
</td>
|
</td>
|
||||||
|
|
Loading…
Add table
Reference in a new issue