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 e27d136..8b2b1c0 100644 Binary files a/gen/ui/linkMany.png and b/gen/ui/linkMany.png differ diff --git a/gen/ui/move.png b/gen/ui/move.png new file mode 100644 index 0000000..f1c2078 Binary files /dev/null and b/gen/ui/move.png differ diff --git a/gen/ui/unlinkManyUp.png b/gen/ui/unlinkManyUp.png index 1b61dda..1bdc8b3 100644 Binary files a/gen/ui/unlinkManyUp.png and b/gen/ui/unlinkManyUp.png differ