
    Ah                         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ej,                        ZeddddfdZd Zy)zForms for treebeard.    )forms)QuerySet)	ErrorList)modelform_factory)escape)	mark_safe)gettext_lazy)AL_Node)MP_Node)NS_Nodec            	       Z    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            Z	 ej                  d ed            Z
d Zdddddedddf	 fd	Zd Zd fd	Zed        Zed        Zed        Zedd       Z x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leftBeforerightAfterTPosition)requiredlabelFzRelative toc                    | j                   r$d}|j                         }|r|j                  }nSd}nP|j                         }|rd}|j                  }n/d}|j	                         rd}n|j                         j                  }||dS )Nr    r   r   )_ref_node_id	_position)	is_sorted
get_parentpkget_prev_siblingis_root)selfinstancepositionnode_parentref_node_idprev_siblings         ?/home/dcms/DCMS/lib/python3.12/site-packages/treebeard/forms.py_get_position_ref_nodez#MoveNodeForm._get_position_ref_node<   s    >>%H"--/K)nn #446L"*oo(##%"$K"*"5"5"7":":K +%' 	'    Nzid_%s:c
                    | j                   }|j                  t        d      t        |j                  dd      | _        | j                  r| j
                  j                  }n| j
                  j                  }|| j                  d   _	        | j                  |j                  |	      }|| j                  d   _	        |j                  j                   j                  j                         }|r|j                  nt        | j                  d   _        |	i }n| j!                  |	      }||j#                  |       t%        | L  d|||||||||	d	|
 y )	Nz&ModelForm has no model class specified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_unsorteddeclared_fieldschoicesmk_dropdown_treer   	formfield	to_pythonintcoercer)   updatesuper__init__)r"   r/   r0   r1   r2   r3   r4   r5   r6   r#   kwargsoptschoices_sort_moder@   pkFormFieldinitial_r<   s                   r(   rH   zMoveNodeForm.__init__R   s?    zz::EFF !_eD>> $ H H $ J J4E[)1 ''

X'F7>^,4jj&&))335OZk6K6K`c^,3
 H228<HOOG$ 	)UGF+%		) "(		)r*   c                     d}d| j                   v rI| j                   d   dk7  r*| j                   d   }|j                         rt        |      }| j                   d= | j                   d   }| j                   d= ||fS )z4 delete auxilary fields not belonging to node model Nr   0r   )cleaned_dataisdigitrD   )r"   reference_node_idposition_types      r(   _clean_cleaned_dataz MoveNodeForm._clean_cleaned_datay   s     T...  0C7$($5$5n$E!$,,.(+,=(>%!!.1))+6k*///r*   c                    | j                         \  }}| j                  j                  j                  r|ro| j                  j
                  j                  j                  |      }|j                  | j                        | _        | j                  j                  ||       n| j                  j
                  j                  | j                        | _        n| j                  j                          |rN| j                  j
                  j                  j                  |      }| j                  j                  ||       nO| j                  rd}nd}| j                  j                  | j                  j
                  j                         |       | j                  j                          t        | -  |       | j                  S )N)r   )r#   )posr   zfirst-sibling)commit)rT   r#   _stateaddingr8   r9   objectsget	add_childmoveadd_rootsaver   get_first_root_noderefresh_from_dbrG   )r"   rW   rS   rR   reference_noderV   r<   s         r(   r_   zMoveNodeForm.save   sZ   +/+C+C+E((==&& !%!1!1!9!9!=!=( "> "* . 8 8$-- 8 P"">}"E $

 0 0 9 94== 9 QMM  !%!1!1!9!9!=!=( "> "*"">}"E>>*C)C""4::#3#3#G#G#I3O%%'F#}}r*   c                 :    | || k(   xs |j                  |       S y)NT)is_descendant_of)r.   possible_parents     r(   is_loop_safezMoveNodeForm.is_loop_safe   s4    8+ B%66x@B r*   c                     d| dz
  z  S )Nz&nbsp;&nbsp;&nbsp;&nbsp;   r7   )levels    r(   	mk_indentzMoveNodeForm.mk_indent   s    )UQY77r*   c           
          | j                  ||      ri|j                  |      D ]T  \  }}|j                  |j                  t	        | j                  |j                               t        |      z         f       V yy)z! Recursively build options tree. N)rf   get_annotated_listappendr   r   rj   	get_depthr   )clsr.   nodeoptionsitem_s         r(   add_subtreezMoveNodeForm.add_subtree   so     Hd+2248 ea3==AQ3RU[\`Ua3a)bcde ,r*   c                 r    dt        d      fg}|j                         D ]  }| j                  |||        |S )z% Creates a tree-like list of choices Nz
-- root --)rs   get_root_nodesrt   )ro   r9   r.   rq   rp   s        r(   rA   zMoveNodeForm.mk_dropdown_tree   sB     !L/*+((* 	5DOOHdG4	5r*   )T)N)__name__
__module____qualname____doc__rs   r=   r>   r   ChoiceFieldr   r   r)   r   rH   rT   r_   staticmethodrf   rj   classmethodrt   rA   __classcell__)r<   s   @r(   r   r      s   : 
:'	1\?+! 
*+,	8	!G*# "!!4q}EI$5$$e1];KLL', !gd93!&%)N0 8   8 8 e e  r*   r   Nc                 :    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)r9   formfieldsexcludeformfield_callbackwidgets_excludes          r(   movenodeform_factoryr      s-      &eW5H#tVX'97D Dr*   c                     |rt        |      }nd}t        | t              r|dz  }|S t        | t              r|dz  }|S t        | t              r|dz  }|S )Nr7   )	sib_orderparent)depthnumchildpath)r   lftrgttree_id)tuple
issubclassr
   r   r   )r9   r   r   s      r(   r   r      si    >%!++
 O	 
E7	#11 O 
E7	#66Or*   )rz   djangor   django.db.models.queryr   django.forms.modelsr   r   r   django.utils.htmlr   django.utils.safestringr   django.utils.translationr	   rs   treebeard.al_treer
   treebeard.mp_treer   treebeard.ns_treer   	ModelFormr   r   r   r7   r*   r(   <module>r      sR      + ) M $ - 6 % % %o5?? od &2$,04D*r*   