<s> """<STR_LIT>""" <EOL> from django import forms <EOL> from django . db . models . query import QuerySet <EOL> from django . forms . models import BaseModelForm , ErrorList , model_to_dict <EOL> from django . forms . models import modelform_factory as django_modelform_factory <EOL> from django . utils . safestring import mark_safe <EOL> from django . utils . translation import ugettext_lazy as _ <EOL> from treebeard . al_tree import AL_Node <EOL> from treebeard . mp_tree import MP_Node <EOL> from treebeard . ns_tree import NS_Node <EOL> class MoveNodeForm ( forms . ModelForm ) : <EOL> """<STR_LIT>""" <EOL> __position_choices_sorted = ( <EOL> ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) , <EOL> ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) , <EOL> ) <EOL> __position_choices_unsorted = ( <EOL> ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) , <EOL> ( '<STR_LIT:left>' , _ ( '<STR_LIT>' ) ) , <EOL> ( '<STR_LIT:right>' , _ ( '<STR_LIT>' ) ) , <EOL> ) <EOL> _position = forms . ChoiceField ( required = True , label = _ ( "<STR_LIT>" ) ) <EOL> _ref_node_id = forms . TypedChoiceField ( required = False , <EOL> coerce = int , <EOL> label = _ ( "<STR_LIT>" ) ) <EOL> def _get_position_ref_node ( self , instance ) : <EOL> if self . is_sorted : <EOL> position = '<STR_LIT>' <EOL> node_parent = instance . get_parent ( ) <EOL> if node_parent : <EOL> ref_node_id = node_parent . pk <EOL> else : <EOL> ref_node_id = '<STR_LIT>' <EOL> else : <EOL> prev_sibling = instance . get_prev_sibling ( ) <EOL> if prev_sibling : <EOL> position = '<STR_LIT:right>' <EOL> ref_node_id = prev_sibling . pk <EOL> else : <EOL> position = '<STR_LIT>' <EOL> if instance . is_root ( ) : <EOL> ref_node_id = '<STR_LIT>' <EOL> else : <EOL> ref_node_id = instance . get_parent ( ) . pk <EOL> return { '<STR_LIT>' : ref_node_id , <EOL> '<STR_LIT>' : position } <EOL> def __init__ ( self , data = None , files = None , auto_id = '<STR_LIT>' , prefix = None , <EOL> initial = None , error_class = ErrorList , label_suffix = '<STR_LIT::>' , <EOL> empty_permitted = False , instance = None ) : <EOL> opts = self . _meta <EOL> if opts . model is None : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> self . is_sorted = getattr ( opts . model , '<STR_LIT>' , False ) <EOL> if self . is_sorted : <EOL> choices_sort_mode = self . __class__ . __position_choices_sorted <EOL> else : <EOL> choices_sort_mode = self . __class__ . __position_choices_unsorted <EOL> self . declared_fields [ '<STR_LIT>' ] . choices = choices_sort_mode <EOL> choices = self . mk_dropdown_tree ( opts . model , for_node = instance ) <EOL> self . declared_fields [ '<STR_LIT>' ] . choices = choices <EOL> if instance is None : <EOL> initial_ = { } <EOL> else : <EOL> initial_ = self . _get_position_ref_node ( instance ) <EOL> if initial is not None : <EOL> initial_ . update ( initial ) <EOL> super ( MoveNodeForm , self ) . __init__ ( <EOL> data , files , auto_id , prefix , initial_ , error_class , label_suffix , <EOL> empty_permitted , instance ) <EOL> def _clean_cleaned_data ( self ) : <EOL> """<STR_LIT>""" <EOL> reference_node_id = <NUM_LIT:0> <EOL> if '<STR_LIT>' in self . cleaned_data : <EOL> reference_node_id = self . cleaned_data [ '<STR_LIT>' ] <EOL> del self . cleaned_data [ '<STR_LIT>' ] <EOL> position_type = self . cleaned_data [ '<STR_LIT>' ] <EOL> del self . cleaned_data [ '<STR_LIT>' ] <EOL> return position_type , reference_node_id <EOL> def save ( self , commit = True ) : <EOL> position_type , reference_node_id = self . _clean_cleaned_data ( ) <EOL> if self . instance . pk is None : <EOL> cl_data = { } <EOL> for field in self . cleaned_data : <EOL> if not isinstance ( self . cleaned_data [ field ] , ( list , QuerySet ) ) : <EOL> cl_data [ field ] = self . cleaned_data [ field ] <EOL> if reference_node_id : <EOL> reference_node = self . _meta . model . objects . get ( <EOL> pk = reference_node_id ) <EOL> self . instance = reference_node . add_child ( ** cl_data ) <EOL> self . instance . move ( reference_node , pos = position_type ) <EOL> else : <EOL> self . instance = self . _meta . model . add_root ( ** cl_data ) <EOL> else : <EOL> self . instance . save ( ) <EOL> if reference_node_id : <EOL> reference_node = self . _meta . model . objects . get ( <EOL> pk = reference_node_id ) <EOL> self . instance . move ( reference_node , pos = position_type ) <EOL> else : <EOL> if self . is_sorted : <EOL> pos = '<STR_LIT>' <EOL> else : <EOL> pos = '<STR_LIT>' <EOL> self . instance . move ( self . _meta . model . get_first_root_node ( ) , pos ) <EOL> self . instance = self . _meta . model . objects . get ( pk = self . instance . pk ) <EOL> super ( MoveNodeForm , self ) . save ( commit = commit ) <EOL> return self . instance <EOL> @ staticmethod <EOL> def is_loop_safe ( for_node , possible_parent ) : <EOL> if for_node is not None : <EOL> return not ( <EOL> possible_parent == for_node <EOL> ) or ( possible_parent . is_descendant_of ( for_node ) ) <EOL> return True <EOL> @ staticmethod <EOL> def mk_indent ( level ) : <EOL> return '<STR_LIT>' * ( level - <NUM_LIT:1> ) <EOL> @ classmethod <EOL> def add_subtree ( cls , for_node , node , options ) : <EOL> """<STR_LIT>""" <EOL> if cls . is_loop_safe ( for_node , node ) : <EOL> options . append ( <EOL> ( node . pk , <EOL> mark_safe ( cls . mk_indent ( node . get_depth ( ) ) + str ( node ) ) ) ) <EOL> for subnode in node . get_children ( ) : <EOL> cls . add_subtree ( for_node , subnode , options ) <EOL> @ classmethod <EOL> def mk_dropdown_tree ( cls , model , for_node = None ) : <EOL> """<STR_LIT>""" <EOL> options = [ ( <NUM_LIT:0> , _ ( '<STR_LIT>' ) ) ] <EOL> for node in model . get_root_nodes ( ) : <EOL> cls . add_subtree ( for_node , node , options ) <EOL> return options <EOL> def movenodeform_factory ( model , form = MoveNodeForm , fields = None , exclude = None , <EOL> formfield_callback = None , widgets = None ) : <EOL> """<STR_LIT>""" <EOL> _exclude = _get_exclude_for_model ( model , exclude ) <EOL> return django_modelform_factory ( <EOL> model , form , fields , _exclude , formfield_callback , widgets ) <EOL> def _get_exclude_for_model ( model , exclude ) : <EOL> if exclude : <EOL> _exclude = tuple ( exclude ) <EOL> else : <EOL> _exclude = ( ) <EOL> if issubclass ( model , AL_Node ) : <EOL> _exclude += ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> elif issubclass ( model , MP_Node ) : <EOL> _exclude += ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:path>' ) <EOL> elif issubclass ( model , NS_Node ) : <EOL> _exclude += ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> return _exclude </s>
