From 5de5372becc647688e2ecbaccf0f4e6de24c7e4f Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Tue, 15 Apr 2014 19:52:18 +0200 Subject: [PATCH] [gen] Added attribute Ref.numbered allowing to produce numbered lists of tied objects and controls for easily moving objects from one position to another. --- fields/ref.py | 97 ++++++++++++++++++++++++++++++---------- gen/tr/Appy.pot | 4 ++ gen/tr/ar.po | 4 ++ gen/tr/de.po | 4 ++ gen/tr/en.po | 4 ++ gen/tr/es.po | 4 ++ gen/tr/fr.po | 4 ++ gen/tr/it.po | 4 ++ gen/tr/nl.po | 4 ++ gen/ui/appy.js | 18 +++++++- gen/ui/linkMany.png | Bin 322 -> 327 bytes gen/ui/move.png | Bin 0 -> 233 bytes gen/ui/unlinkManyUp.png | Bin 321 -> 316 bytes 13 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 gen/ui/move.png diff --git a/fields/ref.py b/fields/ref.py index c4ad141..05879b0 100644 --- a/fields/ref.py +++ b/fields/ref.py @@ -78,13 +78,12 @@ class Ref(Field): # This PX displays icons for triggering actions on a given referenced object # (edit, delete, etc). pxObjectActions = Px(''' - +
- @@ -171,6 +170,25 @@ class Ref(Field): onclick=":ajaxBaseCall.replace('**v**', 'True')"/> ''') + # Shows the object number in a numbered list of tied objects. + pxNumber = Px(''' + :objectIndex+1 + ''') + # PX that displays referred objects as a list. pxViewList = Px(''' @@ -215,6 +233,7 @@ class Ref(Field): var2="columns=ztool.getColumnsSpecifiers(tiedClassName, \ field.shownInfo, dir)"> + + + class=":loop.tied.odd and 'even' or 'odd'" + var2="tiedUid=tied.o.id; + objectIndex=field.getIndexOf(zobj, tiedUid)|None"> +
@@ -108,9 +107,9 @@ class Ref(Field): :tied.pxTransitions - +
:_(refField.labelId) @@ -228,8 +247,12 @@ class Ref(Field): onclick=":'toggleAllRefCbs(%s)' % q(ajaxHookId)"/>
:field.pxNumber @@ -246,8 +269,8 @@ class Ref(Field): - +
@@ -287,6 +310,7 @@ class Ref(Field): (q(ajaxHookId), q(zobj.absolute_url()), \ q(field.name), q(innerRef)); changeOrder=False; + changeNumber=False; checkboxes=field.getAttribute(zobj, 'checkboxes') and \ (totalNumber > 1); showSubTitles=showSubTitles|\ @@ -340,6 +364,7 @@ class Ref(Field): info=field.getValue(zobj,startNumber=startNumber,someObjects=True); objects=info.objects; totalNumber=info.totalNumber; + numberWidth=len(str(totalNumber)); batchSize=info.batchSize; batchNumber=len(objects); folder=zobj.getCreateFolder(); @@ -353,6 +378,9 @@ class Ref(Field): (q(ajaxHookId), q(zobj.absolute_url()), \ q(field.name), q(innerRef)); changeOrder=field.getAttribute(zobj, 'changeOrder'); + numbered=field.isNumbered(zobj); + changeNumber=not inPickList and numbered and canWrite and \ + changeOrder and (totalNumber > 3); checkboxesEnabled=field.getAttribute(zobj, 'checkboxes'); checkboxes=checkboxesEnabled and (totalNumber > 1); showSubTitles=req.get('showSubTitles', 'true') == 'true'"> @@ -425,10 +453,11 @@ class Ref(Field): width=None, height=5, maxChars=None, colspan=1, master=None, masterValue=None, focus=False, historized=False, mapping=None, label=None, queryable=False, queryFields=None, queryNbCols=1, - navigable=False, changeOrder=True, checkboxes=True, - checkboxesDefault=None, sdefault='', scolspan=1, swidth=None, - sheight=None, sselect=None, persist=True, render='list', - menuIdMethod=None, menuInfoMethod=None, menuUrlMethod=None): + navigable=False, changeOrder=True, numbered=False, + checkboxes=True, checkboxesDefault=None, sdefault='', + scolspan=1, swidth=None, sheight=None, sselect=None, + persist=True, render='list', menuIdMethod=None, + menuInfoMethod=None, menuUrlMethod=None): self.klass = klass self.attribute = attribute # May the user add new objects through this ref ? @@ -513,12 +542,20 @@ class Ref(Field): self.queryNbCols = queryNbCols # Within the portlet, will referred elements appear ? self.navigable = navigable - # If "changeOrder" is False, it even if the user has the right to modify - # the field, it will not be possible to move objects or sort them. + # If "changeOrder" is or returns False, it even if the user has the + # right to modify the field, it will not be possible to move objects or + # sort them. self.changeOrder = changeOrder - # If "checkboxes" is True, every linked object will be "selectable" vi - # a checkbox: global actions will be possible, that will act on the - # subset of selected objects: delete, unlink, etc. + # If "numbered" is or returns True, a leading column will show the + # number of every tied object. Moreover, if the user can change order of + # tied objects, an input field will allow him to enter a new number for + # the tied object. If "numbered" is or returns a string, it will be used + # as width for the column containing the number. Else, a default width + # will be used. + self.numbered = numbered + # If "checkboxes" is or returns True, every linked object will be + # "selectable" via a checkbox. Global actions will be activated and will + # act on the subset of selected objects: delete, unlink, etc. self.checkboxes = checkboxes # Default value for checkboxes, if enabled. if checkboxesDefault == None: @@ -719,6 +756,14 @@ class Ref(Field): menu.icon = icon return res + def isNumbered(self, obj): + '''Must we show the order number of every tied object?''' + res = self.getAttribute(obj, 'numbered') + if not res: return res + # Returns the column width. + if not isinstance(res, basestring): return '15px' + return res + def getMenuUrl(self, zobj, tied): '''We must provide the URL of the p_tied object, when shown in a Ref field in render mode 'menus'. If self.menuUrlMethod is specified, @@ -941,9 +986,6 @@ class Ref(Field): uid = rq['refObjectUid'] uids = getattr(obj.aq_base, self.name) oldIndex = uids.index(uid) - # Remove the object from its previous position. - uids.remove(uid) - # Re-insert the object at its new position. if move == 'up': newIndex = oldIndex - 1 elif move == 'down': @@ -951,8 +993,17 @@ class Ref(Field): elif move == 'top': newIndex = 0 elif move == 'bottom': - newIndex = len(uids) - uids.insert(newIndex, uid) + newIndex = len(uids) - 1 + elif move.startswith('index'): + # New index starts at 1 (oldIndex starts at 0). + try: + newIndex = int(move.split('_')[1]) - 1 + except ValueError: + newIndex = -1 + # If newIndex is negative, it means that the move can't occur. + if newIndex > -1: + uids.remove(uid) + uids.insert(newIndex, uid) xhtmlToText = re.compile('<.*?>', re.S) def getReferenceLabel(self, refObject, unlimited=False): diff --git a/gen/tr/Appy.pot b/gen/tr/Appy.pot index 9d9a5c8..ef47237 100644 --- a/gen/tr/Appy.pot +++ b/gen/tr/Appy.pot @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "" diff --git a/gen/tr/ar.po b/gen/tr/ar.po index e392dfb..cef7ded 100644 --- a/gen/tr/ar.po +++ b/gen/tr/ar.po @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "" diff --git a/gen/tr/de.po b/gen/tr/de.po index 0dc5b22..84322f1 100644 --- a/gen/tr/de.po +++ b/gen/tr/de.po @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "Anfertigen" diff --git a/gen/tr/en.po b/gen/tr/en.po index 56c4ab9..3a5bd77 100644 --- a/gen/tr/en.po +++ b/gen/tr/en.po @@ -112,6 +112,10 @@ msgstr "Move to top" msgid "move_bottom" msgstr "Move to bottom" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "Update the hereabove number and click here to move this element to a new position." + #. Default: "create" msgid "query_create" msgstr "create" diff --git a/gen/tr/es.po b/gen/tr/es.po index 4cc7770..05f20fc 100644 --- a/gen/tr/es.po +++ b/gen/tr/es.po @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "Crear" diff --git a/gen/tr/fr.po b/gen/tr/fr.po index cee996a..de56336 100644 --- a/gen/tr/fr.po +++ b/gen/tr/fr.po @@ -112,6 +112,10 @@ msgstr "Déplacer en première position" msgid "move_bottom" msgstr "Déplacer en dernière position" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "Modifiez le numéro ci-dessus et cliquez ici pour déplacer l'élément à une nouvelle position." + #. Default: "create" msgid "query_create" msgstr "Créer" diff --git a/gen/tr/it.po b/gen/tr/it.po index 7df20b8..75a5e43 100644 --- a/gen/tr/it.po +++ b/gen/tr/it.po @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "Creazione in corso" diff --git a/gen/tr/nl.po b/gen/tr/nl.po index a253d41..320b5a8 100644 --- a/gen/tr/nl.po +++ b/gen/tr/nl.po @@ -111,6 +111,10 @@ msgstr "" msgid "move_bottom" msgstr "" +#. Default: "Update the hereabove number and click here to move this element to a new position." +msgid "move_number" +msgstr "" + #. Default: "create" msgid "query_create" msgstr "Aanmaken" diff --git a/gen/ui/appy.js b/gen/ui/appy.js index 2bbde76..d2b5c4b 100644 --- a/gen/ui/appy.js +++ b/gen/ui/appy.js @@ -1,3 +1,5 @@ +var wrongTextInput = '#F9EDBE none'; + // Functions related to user authentication function cookiesAreEnabled() { // Test whether cookies are enabled by attempting to set a cookie and then @@ -240,7 +242,20 @@ function askRefField(hookId, objectUrl, fieldName, innerRef, startNumber, params[startKey] = startNumber; if (action) params['action'] = action; if (actionParams) { - for (key in actionParams) { params[key] = actionParams[key]; }; + for (key in actionParams) { + if ((key == 'move') && (typeof actionParams[key] == 'object')) { + // Get the new index from an input field + var id = actionParams[key].id; + id = id.substr(0, id.length-4); + var input = document.getElementById(id); + if (isNaN(input.value)) { + input.style.background = wrongTextInput; + return; + } + params[key] = 'index_' + input.value; + } + else params[key] = actionParams[key]; + }; } var px = (scope == 'objs')? ':pxView': ':pxViewPickList'; askAjaxChunk(hookId, 'GET', objectUrl, fieldName + px, params, null, @@ -735,7 +750,6 @@ function doConfirm() { } } -var wrongTextInput = '#F9EDBE none'; // Function triggered when the user asks password reinitialisation function doAskPasswordReinit() { // Check that the user has typed a login diff --git a/gen/ui/linkMany.png b/gen/ui/linkMany.png index e27d136b93cf1f980497ff009dcf2634e80b98b6..8b2b1c0b2e3446ba13bd7115532f4ccc6295d088 100644 GIT binary patch delta 252 zcmV=W7Hwgd$0002_L%V;GKp=k)5h*k=6~k}<0075HL_t(&-tF5#3c@fH zMbSjEf=)AWtk7k2kzGNz@#$LrI^x7=h$2)UYT=%d&{?>cH)vxiB>-v%jsS#(-AL}v zT?nb1b4=GCoCYM^ovRRREbNGx6~e-I|FNcZ4AVMpeg?b@>v%rhBI=`Rp97o1nuloR zA+9#6d003-yf@yT#YI$*Y^*k}8WkH0l8sg4s!_4AAlq1dR9uH(W8uHT>f<6R$iiyl zA}UD3s&N7GumHls&!rIVFJ}QNvHwcP%y?B9AG-j#tW03^WorHa0000~R4A delta 247 zcmVT22Hwpg${{a7>y{D6rKp=ku4hS=TLKwvW006>CL_t(&-tF5l3WGop zM&VuA6WDHJoq)&ikeaQ~j_G~DX~2c5@+t%y3pXMnQL70(Y)*K0-AbW|YuPgfvW;qUJqrICXj{}9uJY5_^G|tZr+Q@rAfu~z=enG;` zQ=C0A5qX8;Rw7JGJC8W1+`b{9^7OrhVbAqxnqgfWziRa!250`tyB`tm5MgtXNovXm zmw8E7Z!FyO<^Pofd#7K&>zj1+OthY3=&w~AI=u^6S6Rh6e~ YfA5CuUU-4+7|;a_p00i_>zopr0OHY8lmGw# literal 0 HcmV?d00001 diff --git a/gen/ui/unlinkManyUp.png b/gen/ui/unlinkManyUp.png index 1b61ddae50387adb59da9ce364686d094d11cbe8..1bdc8b35eb32dff0a4a76202b5714a853eb14680 100644 GIT binary patch delta 241 zcmV&yUYj&*+On2a70W9`XM&FuQIq358oAXY^?=A?Zy#+uy7g4-I;}u z$~njMdf+r5;qHt=uw&su%&ZX>{`|$Nh0}sKtXjhJ{va+0!|G9mKwJ=owTo(5SK?iQ zAgnQ}T8IntVU1DsnBL+74y2(>{vMIjzwIM?^qv3Bs&)7cB~)Y0pE8l rfUt17QP?kM0V;9)OUKN(s*GtHhB|4qK#J{1Hwpg${{a7>y{D6rKp=kv2o)y+uH>%(006;BL_t(&-tF753BxcD zK+#js5C-k09W+UH$R?NGWkxv27D^KZTg2c*SJ?1hWl$$R(iL*3wF=&-;V8;22hmN`$!J6xJfDX`W(< z3l3p@iHf)|99ADy3uzS>upw?Oe1ck>UQ@{;*V}pxV0Z_^I~d-9|A+T(_F{O)`0)P2 w8nAD82M7y?x(eIlEWk_X|I$%ao+@M53pQwK<*b@!bN~PV07*qoM6N<$f;y^idH?_b