a
    Cg                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ G dd dejZeddddfddZdd ZdS )zForms for treebeard.    )forms)QuerySet)	ErrorList)modelform_factory)escape)	mark_safe)gettext_lazy)AL_Node)MP_Node)NS_Nodec                	       s   e Zd ZdZdedfdedffZdedfded	fd
edffZejdeddZ	ejdeddZ
dd Zdddddedddf	 fdd	Zdd Zd$ fdd	Zedd Zedd Zed d! Zed%d"d#Z  ZS )&MoveNodeForma<  
    Form to handle moving a node in a tree.

    Handles sorted/unsorted trees.

    It adds two fields to the form:

    - Relative to: The target node where the current node will
                   be moved to.
    - Position: The position relative to the target node that
                will be used to move the node. These can be:

                - For sorted trees: ``Child of`` and ``Sibling of``
                - For unsorted trees: ``First child of``, ``Before`` and
                  ``After``

    .. warning::

        Subclassing :py:class:`MoveNodeForm` directly is
        discouraged, since special care is needed to handle
        excluded fields, and these change depending on the
        tree type.

        It is recommended that the :py:func:`movenodeform_factory`
        function is used instead.

    sorted-childzChild ofsorted-siblingz
Sibling offirst-childzFirst child ofleftZBeforerightZAfterTZPosition)requiredlabelFzRelative toc                 C   sb   | j r$d}| }|r|j}qXd}n4| }|r<d}|j}nd}| rNd}n
| j}||dS )Nr    r   r   )_ref_node_id	_position)	is_sortedZ
get_parentpkZget_prev_siblingZis_root)selfinstancepositionZnode_parentZref_node_idZprev_sibling r   N/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/treebeard/forms.py_get_position_ref_node<   s"    
z#MoveNodeForm._get_position_ref_nodeNzid_%s:c
                    s   | j }|jd u rtdt|jdd| _| jr8| jj}n| jj}|| jd _	| j
|j|	d}|| jd _	|jj j }|r|jnt| jd _|	d u ri }n
| |	}|d ur|| t jf |||||||||	d	|
 d S )Nz&ModelForm has no model class specifiedZnode_order_byFr   )for_noder   )	datafilesauto_idprefixinitialerror_classlabel_suffixempty_permittedr   )_metamodel
ValueErrorgetattrr   	__class__&_MoveNodeForm__position_choices_sorted(_MoveNodeForm__position_choices_unsortedZdeclared_fieldschoicesmk_dropdown_treer   Z	formfieldZ	to_pythonintZcoercer   updatesuper__init__)r   r!   r"   r#   r$   r%   r&   r'   r(   r   kwargsoptsZchoices_sort_moder0   ZpkFormFieldZinitial_r-   r   r   r5   R   s2    



zMoveNodeForm.__init__c                 C   sX   d}d| j v r>| j d dkr6| j d }| r6t|}| j d= | j d }| j d= ||fS )z4 delete auxilary fields not belonging to node model Nr   0r   )Zcleaned_dataisdigitr2   )r   reference_node_idposition_typer   r   r   _clean_cleaned_datay   s    


z MoveNodeForm._clean_cleaned_datac                    s   |   \}}| jjjrd|rN| jjjj|d}|j| jd| _| jj	||d q| jjj
| jd| _nX| j  |r| jjjj|d}| jj	||d n&| jrd}nd}| j	| jj | | j  t j|d | jS )N)r   )r   )posr   zfirst-sibling)commit)r=   r   _stateZaddingr)   r*   ZobjectsgetZ	add_childmoveZadd_rootsaver   Zget_first_root_nodeZrefresh_from_dbr4   )r   r?   r<   r;   Zreference_noder>   r8   r   r   rC      s,    




zMoveNodeForm.savec                 C   s    | d ur|| k p| | S dS )NT)Zis_descendant_of)r    Zpossible_parentr   r   r   is_loop_safe   s    zMoveNodeForm.is_loop_safec                 C   s   d| d  S )Nz&nbsp;&nbsp;&nbsp;&nbsp;   r   )levelr   r   r   	mk_indent   s    zMoveNodeForm.mk_indentc              	   C   sJ   |  ||rF||D ].\}}||jt| | t| f qdS )z! Recursively build options tree. N)rD   Zget_annotated_listappendr   r   rG   Z	get_depthr   )clsr    nodeoptionsitem_r   r   r   add_subtree   s    zMoveNodeForm.add_subtreec                 C   s.   dt dfg}| D ]}| ||| q|S )z% Creates a tree-like list of choices Nz
-- root --)rM   Zget_root_nodesrN   )rI   r*   r    rK   rJ   r   r   r   r1      s    zMoveNodeForm.mk_dropdown_tree)T)N)__name__
__module____qualname____doc__rM   r.   r/   r   ZChoiceFieldr   r   r   r   r5   r=   rC   staticmethodrD   rG   classmethodrN   r1   __classcell__r   r   r8   r   r      s2   




'


r   Nc                 C   s   t | |}t| |||||S )ad  Dynamically build a MoveNodeForm subclass with the proper Meta.

    :param Node model:

        The subclass of :py:class:`Node` that will be handled
        by the form.

    :param form:

        The form class that will be used as a base. By
        default, :py:class:`MoveNodeForm` will be used.

    :return: A :py:class:`MoveNodeForm` subclass
    )_get_exclude_for_modeldjango_modelform_factory)r*   formfieldsexcludeZformfield_callbackZwidgets_excluder   r   r   movenodeform_factory   s    
r\   c                 C   sP   |rt |}nd}t| tr&|d7 }n&t| tr:|d7 }nt| trL|d7 }|S )Nr   )Z	sib_orderparent)depthZnumchildpath)r^   ZlftZrgtZtree_id)tuple
issubclassr	   r
   r   )r*   rZ   r[   r   r   r   rV      s    





rV   )rR   Zdjangor   Zdjango.db.models.queryr   Zdjango.forms.modelsr   r   rW   Zdjango.utils.htmlr   Zdjango.utils.safestringr   Zdjango.utils.translationr   rM   Ztreebeard.al_treer	   Ztreebeard.mp_treer
   Ztreebeard.ns_treer   Z	ModelFormr   r\   rV   r   r   r   r   <module>   s     3
