U
    zh                     @   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_siblingis_root)selfinstancepositionZnode_parentZref_node_idZprev_sibling r   W/var/www/dating/data/www/fatepal.com/env/lib/python3.8/site-packages/treebeard/forms.py_get_position_ref_node<   s"    
z#MoveNodeForm._get_position_ref_nodeNzid_%s:c
                    s   | j }|jd k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 kri }n
| |	}|d k	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_moder1   ZpkFormFieldZinitial_r.   r   r   r6   R   s<    



     zMoveNodeForm.__init__c                 C   sX   d}d| j k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isdigitr3   )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+   objectsgetZ	add_childmoveZadd_rootsaver   Zget_first_root_nodeZrefresh_from_dbr5   )r   r@   r=   r<   Zreference_noder?   r9   r   r   rE      s,    




zMoveNodeForm.savec                 C   s    | d k	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)rF   Zget_annotated_listappendr   r   rI   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 --)rO   Zget_root_nodesrP   )rK   r+   r!   rM   rL   r   r   r   r2      s    zMoveNodeForm.mk_dropdown_tree)T)N)__name__
__module____qualname____doc__rO   r/   r0   r   ZChoiceFieldr   r   r   r   r6   r>   rE   staticmethodrF   rI   classmethodrP   r2   __classcell__r   r   r9   r   r      s8   




   '


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+   r\   r]   r   r   r   rX      s    





rX   )rT   djangor   Zdjango.db.models.queryr   Zdjango.forms.modelsr   r   rY   Zdjango.utils.htmlr   Zdjango.utils.safestringr   Zdjango.utils.translationr   rO   Ztreebeard.al_treer	   Ztreebeard.mp_treer
   Ztreebeard.ns_treer   Z	ModelFormr   r^   rX   r   r   r   r   <module>   s"    3 
