From 8d24a40724ee3eaa3bd793c0fb396955ac4e8091 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Sat, 24 Nov 2012 09:42:21 +0100 Subject: [PATCH] improve option-controlled filtering by states, + checkbox for showing all items --- browser/common.py | 26 +++++++++++++++++----- browser/concept.py | 2 +- browser/concept_macros.pt | 6 +++-- locales/de/LC_MESSAGES/loops.mo | Bin 20373 -> 20444 bytes locales/de/LC_MESSAGES/loops.po | 5 ++++- organize/personal/browser/filter.py | 33 +++++++++++++++++++--------- organize/stateful/browser.py | 16 +++++++++++++- organize/stateful/configure.zcml | 6 +++++ organize/stateful/view_macros.pt | 8 +++++-- 9 files changed, 80 insertions(+), 22 deletions(-) diff --git a/browser/common.py b/browser/common.py index 9ac9bf4..6fd3e15 100644 --- a/browser/common.py +++ b/browser/common.py @@ -54,6 +54,7 @@ from zope.traversing.api import getName, getParent from cybertools.ajax.dojo import dojoMacroTemplate from cybertools.browser.view import GenericView from cybertools.meta.interfaces import IOptions +from cybertools.meta.element import Element from cybertools.relation.interfaces import IRelationRegistry from cybertools.stateful.interfaces import IStateful from cybertools.text import mimetypes @@ -132,7 +133,6 @@ class BaseView(GenericView, I18NView): actions = {} portlet_actions = [] parts = () - filter_input = () icon = None modeName = 'view' isToplevel = False @@ -186,6 +186,15 @@ class BaseView(GenericView, I18NView): return '%s/.%s-%s' % (baseUrl, targetId, normalizeForUrl(title)) return '%s/.%s' % (baseUrl, targetId) + def filterInput(self): + result = [] + for name in self.getOptions('filter_input'): + view = component.queryMultiAdapter( + (self.context, self.request), name='filter_input.' + name) + if view is not None: + result.append(view) + return result + @Lazy def principalId(self): principal = self.request.principal @@ -574,11 +583,18 @@ class BaseView(GenericView, I18NView): def globalOptions(self): return IOptions(self.loopsRoot) - def getOptions(self, key): + def getOptions(self, keys): for opt in (self.options, self.typeOptions, self.globalOptions): - value = opt[key] - if not isinstance(value, DummyOptions): - return value + if isinstance(opt, DummyOptions): + continue + #import pdb; pdb.set_trace() + v = opt + for key in keys.split('.'): + if isinstance(v, list): + break + v = getattr(v, key) + if not isinstance(v, DummyOptions): + return v def getPredicateOptions(self, relation): return IOptions(adapted(relation.predicate), None) or DummyOptions() diff --git a/browser/concept.py b/browser/concept.py index 45bfdc3..8ed97a7 100644 --- a/browser/concept.py +++ b/browser/concept.py @@ -361,7 +361,7 @@ class ConceptView(BaseView): options = IOptions(adapted(r.predicate), None) if options is not None and options('hide_children'): continue - filterOptions = self.getOptions('filter') + filterOptions = self.getOptions('filter.states') if not fv.check(r.context, filterOptions): continue yield r diff --git a/browser/concept_macros.pt b/browser/concept_macros.pt index e7cfad4..78ca2b3 100644 --- a/browser/concept_macros.pt +++ b/browser/concept_macros.pt @@ -10,7 +10,6 @@
- @@ -31,12 +30,14 @@ -
+
@@ -61,6 +62,7 @@ string:$resourceBase/cybertools.icons/table.png" /> +

diff --git a/locales/de/LC_MESSAGES/loops.mo b/locales/de/LC_MESSAGES/loops.mo index e863d65a78cf2ba94072c4ea24870b567a773be8..17e544377e294040669dc1c1dfd4bdabbe3efb7c 100644 GIT binary patch delta 7854 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 delta 7779 zcmYk=3w+P@9>?+DF1Fb)8ymK@F=K|A&1G(LADcT{GG>IxC6}yH=;wqabYV(|LQ3Uw zTB#H%x<@G`gha|MQNluWUhn_!vmSnr$H((~zy5yzcFy6IeoI&Sxkn-cmpVLS{2V6^ z^TQnHN74(URq8k)@s86ED`F!Yj6wLYxd?;FmtX*{K!$KuVP)Ka3AhET;z6v4zhWiF zah*#f)X|?->KKGnIFT5I38=NSKn>UnHNarhLPlW-j<I;fkvnSJE0~XfHiP5s@;RAojrkSw+a*SHLQhuu{xeZ z^$Va<BFQYUQUy2`DnEBFw#kS~%re-)gdAP~=^?(iZ8;0;v0e?4!fVW^ih2KDmQNA*iZwaY-A zR9nmEqb3@PI+^=W?dMs3p-Vz5Ux7NxQq+pyM;+-N)Kwfo4R9WH^#7pRSFZ1!Kpg61 z($IGjsD1^g@y4M}b_QyLPg=dZoP-A2fEswKReX-VJGJtY7)t#m%R9;5-Bv*@ECqwG zHR|L#qE4hMY9YN*?TWAhPDD=9b&5%7MYB*H9z`9|5-VSZ8t{441Zz<{+=$I_hm~JO zjdLBfk>Cc7!%vG7g?fjYV=xXhi!e~%|7c%=9}v_4lQ9Gzu>5S)#EVb^l%RI70(}cZ zEod!jr&~}*z6*8aKcIGg0oBew#jB6TXnp?;NNB|!P*>3#^?4McIuu*^BUb)2>S|s^ z^?Mif((Obo^f+o^XHYNeIjo3RQ70SN(Cb$bT@}fG7Q1zuqnQTTF?R1%lRXQ;w6klzERiLA&!q#M^q2BfEJd|LJiy-yJH^e zgqEWwT8BD;O{fWWpcb^>>VHP<{5MR-GAmDL?43k|#+<)8q*9=jw!tv$gubh=d?9MZ zccLbqgT8kH)vg5Dl(PnPlDkpg{V`0!Yp5%&o$8%vE7Zvsxg@m1k*JBsqK@buE1!j2 zoAWSg!cr^WjQ-@ep-ybO)qjS1XTCyBa2z%6Dbzd{QR81ly`*l1Cf-0bkTNF*byPW+ zfs?Txu0fr^MbrsYP4fn-g&H^s^|m)ey?h<4yo;HOT3BDKgd>p+xXxq}+QC%Ril?LQ zau%xLQ>dM;vHG>B_Up|}sEN0tcJ?)Dfrn7z{fz2=8uc!m#caHc>H7ZL@v3SE6Hy(D zQ5|QZ7V;2k;AK|71}l@_fLyDy1rzWj>WYHXy>Y6b@-VOi13ZZ8_qdgpSouq+1-y;gz)sY--w5G&2*m^A48JHT$C`E`K0I3;ssHDJ}_h z+=%M11vS79)WAD23iqM@;yH`@Oha3GKPatGFIPXTg88WaBQX*uU^R3x8keBPTUTDb zorI2RFY1nupawW+e!g zt8<+=68e6VPy@9_Eg%~;Kp(3wwE8KilbUJHLH!Sx1*mu7WmLaX)Wq+hPU3Ua2_D88 zcok#x{YSR;3Q|!Gvr%_E$Q*~Y$wy}- z5Y=xIR@e7G-zuInUqkKSBh(RpgSxZhsJ~>cU<}6c1|?%lOu{164rgO5u12-nhWbnB z0IGc%Y5@uDIR97@tx4zzZ$)*u8?}Q)n1U}Nb2?w4UZzlfb#z7Xs3T6s1k6Bvt^-h4 zGzhhkVW^k%E>yoMsEs|4#rf;)UqFHGZW(I8Rj7{Zu{OSg8u%b;VMne0FI4-W_TC9a zU~TfrsEy=U`AF2!-;cV&g;u_%J?F1GdxrwK8+A0tF%GX=KBj~BCsuRR0(zq+xC3>! zvrwPkV$?XR&9_kPccJeJQ73o>bpn;$j$T1L>TWYoE6hio$avHb$W(J0rjehC+R;YT zQEx|0{3+@yI*jUn3UzY7qdvdOsQ(%|oxFZ-0118fp~z`EF{qA%PBTqw3&=$3U0jLcYp!!e1VOWf=j&Lst9qk2F!;o%X zJ{EN%>8QKwfLdTKHo<(sF&?N%P%mOUQE&l>);TurnypPTC1B}NqY=hCcTnF~Y6nw!Yp%d7R zA^1IN0Y9O3dJ1)PF+IHU6jb{()XUcfRo@FW@etHFMHql%P(ShGQSZt;tcXve+PSN( zVjXJ7TTnkFAE1tKKdQqoR(~EfQ5kB0tJoI|2qm zb)C;hsNql868}KGlnr`$6Ldp$?28(BFoxl9a{>mDpN3kfYvuD%@61xv&Nreqv<)@i zF07>Q|DaWzMD5@b>LgnA_9pI#+Hp_R1btB7`yi_yi%rNEVq2)_Z3t5huU;|dhcTp#?6E(qJ%O6F3u4gPC$cv%zs-XHsqxvPG zHr%8y=dT51QV@>0s15~|za2Hf6x7kqMD5^F^h3QTdhYOWcA8OC*0*#E9Bt{ol;5F_ zJco(TbpMGYdQsR=rS=TQFl%^;bRE*S5(T7h5Wf+69we$!UX{ouipl>;{6gGCtR+qp z8;Ka|ze4?<{7v*D@9*-Dei$-|SBTpP-R*qhPD0N>59dQXLG+-H9v!KEWPT@-h{?nk zL<;dfq32Vg3!xvKH;5;R2SzJxj zvH?|`uYY(tP<9)!k90nc#}+sh#}Pvbei>codlGt{BMuOkmEoyLWBx?AL%maDhzgYN!Z!);VWf%_>d}8vHxsv$PqH$VmlE$1_Yg;k zc7BSY!2HK#F@OH|MSosFLVrkKx2($ct9AN!sX#ZWwgj0Cj8q_5}$I`t~KS2Kw zBZ$t#uf*5HRYFfw+P5LnysYovFZuUj%lD@4JJK~RpGUsGrG4jLnSxu0K7=0q@AODw z5$RB03I7WTr&+oab-OJcKzg~QYm@$*bPY_#kBM2tF!G7SBcwy|8T|JtzyG)XE%6dB z+>|dPJ%o;Ju^zU>2Z&grih{B@LQgw$Dd~}x?u^5UEXz-#t~Kewgqy)XPf^eqJEEQ- zq9yscz8wG8JDwy)S^jCWHcltrAqr@J2=yE!o*;@S3&cW9AreSO6Z424i5@!tbSnCg zDIwMnuM&eOdmDQZIi$~{o{pqH!pDga74ZB)q)|Q-FA(<=5kw6_PaJWP$RoB9)oFV# z>Umk;Up*4TiH20nMm+xkQhp{JsUGtul$ z`3IJ6qBgq!W+cvG6tR$qCchW;WRiXnE8!Gh34bYJUrXQ2F*2KoF|_^Uri!MdyHM7| z%G#3F(+xY{?WLVZv8Pq!kgh}g$Lji1zMga{2H?*`J7O^r>$j<8d}jEjds8EW{W3Pq SZ$7`;k_%bUn_A|q4gNo)OY-Lc diff --git a/locales/de/LC_MESSAGES/loops.po b/locales/de/LC_MESSAGES/loops.po index 6eec2d7..9fd4fb7 100644 --- a/locales/de/LC_MESSAGES/loops.po +++ b/locales/de/LC_MESSAGES/loops.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: $Id$\n" "POT-Creation-Date: 2007-05-22 12:00 CET\n" -"PO-Revision-Date: 2012-11-22 12:00 CET\n" +"PO-Revision-Date: 2012-11-24 12:00 CET\n" "Last-Translator: Helmut Merz \n" "Language-Team: loops developers \n" "MIME-Version: 1.0\n" @@ -882,6 +882,9 @@ msgstr "nach" # state definitions +msgid "Show all" +msgstr "Alle anzeigen" + msgid "Restrict to objects with certain states" msgstr "Auf Objekte mit bestimmtem Status beschränken" diff --git a/organize/personal/browser/filter.py b/organize/personal/browser/filter.py index 06c787b..cedf846 100644 --- a/organize/personal/browser/filter.py +++ b/organize/personal/browser/filter.py @@ -108,17 +108,30 @@ class FilterView(NodeView): result.setdefault(obj.getType(), set([])).add(obj) return result + def checkOptions(self, obj, options): + if isinstance(options, list): + return True + form = self.request.form + if form.get('filter.states') == 'all': + return True + filterStates = options + for std in filterStates.keys(): + formStates = form.get('filter.states.' + std) + if formStates == 'all': + continue + stf = component.getAdapter(obj, IStateful, name=std) + if formStates: + if stf.state not in formStates.split(','): + return False + else: + if stf.state not in getattr(filterStates, std): + return False + return True + def check(self, obj, options=None): - if options: - for std in options.states.keys(): - stf = component.getAdapter(obj, IStateful, name=std) - formStates = self.request.form.get('states.' + std) - if formStates: - if stf.state not in formStates.split(','): - return False - else: - if stf.state not in getattr(options.states, std): - return False + if options is not None: + if not self.checkOptions(obj, options): + return False fs = self.filterStructure if not fs: return True diff --git a/organize/stateful/browser.py b/organize/stateful/browser.py index da9a340..7f24d2b 100644 --- a/organize/stateful/browser.py +++ b/organize/stateful/browser.py @@ -35,6 +35,8 @@ from loops.security.common import checkPermission from loops.util import _ +template = ViewPageTemplateFile('view_macros.pt') + statefulActions = ('classification_quality', 'simple_publishing', 'task_states',) @@ -78,7 +80,7 @@ for std in statefulActions: #class StateQuery(ConceptView): class StateQuery(BaseView): - template = ViewPageTemplateFile('view_macros.pt') + template = template form_action = 'execute_search_action' @@ -145,3 +147,15 @@ class StateQuery(BaseView): uids = q.apply() return self.viewIterator(getObjects(uids, self.loopsRoot)) return [] + + +class FilterAllStates(BaseView): + + @Lazy + def macros(self): + return template.macros + + @Lazy + def macro(self): + return self.macros['filter_allstates'] + diff --git a/organize/stateful/configure.zcml b/organize/stateful/configure.zcml index e5cd542..0514400 100644 --- a/organize/stateful/configure.zcml +++ b/organize/stateful/configure.zcml @@ -71,6 +71,12 @@ class="loops.organize.stateful.browser.StateQuery" permission="zope.View" /> + + diff --git a/organize/stateful/view_macros.pt b/organize/stateful/view_macros.pt index 913fd36..6dfad17 100644 --- a/organize/stateful/view_macros.pt +++ b/organize/stateful/view_macros.pt @@ -2,8 +2,12 @@ - + +