Projects can be shared with users and groups. Does not work with contents yet, still some bugs in templates
authorverrierj
Tue, 06 Dec 2011 17:45:35 +0100
changeset 268 c0c161736794
parent 267 e00779f0dcba
child 269 4b8042fc3d33
Projects can be shared with users and groups. Does not work with contents yet, still some bugs in templates
src/ldt/ldt/ldt_utils/forms.py
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_group.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_ldt.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/permissions.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/sharewith.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/userslist.html
src/ldt/ldt/ldt_utils/urls.py
src/ldt/ldt/ldt_utils/views.py
src/ldt/ldt/security/utils.py
src/ldt/ldt/static/ldt/js/multiselect.js
--- a/src/ldt/ldt/ldt_utils/forms.py	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/forms.py	Tue Dec 06 17:45:35 2011 +0100
@@ -2,26 +2,64 @@
 from django.utils.translation import ugettext_lazy as _
 from django.contrib.auth.models import User, Group
 from django.forms.widgets import MultipleHiddenInput
-from django.contrib.admin.widgets import FilteredSelectMultiple
 from ldt.forms import widgets as ldt_widgets
 from models import Project, Content, Media
 from utils import generate_uuid
 
+# This class should be moved somewhere else
+class LazyMultipleChoiceField(forms.MultipleChoiceField):
+    
+    # Should do some checking here
+    def validate(self, value):
+        pass    
+
+class ShareForm(forms.ModelForm):
+    read_list = LazyMultipleChoiceField(required=False, widget=MultipleHiddenInput())
+    write_list = LazyMultipleChoiceField(required=False, widget=MultipleHiddenInput()) 
+
+    def clean(self):
+        read_list = self.data.getlist("read_list")
+        write_list = self.data.getlist("write_list")
+        
+        elems = read_list + write_list
+        users = [e.split('-')[0] for e in elems if e.split('-')[1] == 'user' ]
+        groups = [e.split('-')[0] for e in elems if e.split('-')[1] == 'group' ]
+        
+        users = User.objects.filter(id__in=users)
+        groups = Group.objects.filter(id__in=groups)
+        
+        def create_real_lists(list, users, groups):
+            new_list = []
+            for e in list:
+                id, cls_name = e.split('-')
+                if cls_name == 'user':
+                    new_list.append(users.get(id=id))
+                elif cls_name == 'group':
+                    new_list.append(groups.get(id=id))
+            return new_list
+         
+        new_read_list = create_real_lists(read_list, users, groups)
+        new_write_list = create_real_lists(write_list, users, groups)
+
+        self.cleaned_data["read_list"] = new_read_list
+        self.cleaned_data["write_list"] = new_write_list
+        return self.cleaned_data
+    
 
 class LdtImportForm(forms.Form):
     importFile = forms.FileField()
     videoPath = forms.CharField(required=False)
     flatten = forms.BooleanField(required=False, initial=True)   
     
-class LdtAddForm(forms.ModelForm):
+class LdtAddForm(ShareForm):
     title = forms.CharField(required=True)
-    contents = forms.ModelMultipleChoiceField(Content.objects.all()) #@UndefinedVariable
+    #contents = forms.ModelMultipleChoiceField(Content.objects.all())
     description = forms.CharField(widget=forms.Textarea, required=False)
-    groups = forms.ModelMultipleChoiceField(Group.objects.all(), required=False)
-    # owner = forms.ModelChoiceField(Author.objects.all())
+    
+    # remove contents from exclude list    
     class Meta:
         model = Project
-        exclude = ("ldt_id", "ldt", "created_by", "changed_by", "creation_date", "modification_date", "state", "owner")   
+        exclude = ("ldt_id", "ldt", "created_by", "changed_by", "creation_date", "modification_date", "state", "owner", "contents")   
 
 class PermissionForm(forms.Form):
     share = forms.BooleanField(required=False, widget=forms.CheckboxInput(attrs={'class':'checkbox_group'}))
@@ -32,14 +70,18 @@
     contents = forms.ModelMultipleChoiceField(Content.objects.all()) #@UndefinedVariable
     index_projects = forms.BooleanField(required=False, initial=False)
 
-class SearchForm(forms.Form):
+class SearchForm(forms.ModelForm):
     search = forms.CharField(label=_("Search"))
     field = forms.ChoiceField([(u"all", _("all")), (u"title", _("title")), (u"abstract", _("resume")), (u"tags", _("tags"))], label=_("Fields"))
     ldt_pres = forms.BooleanField(required=False, initial=True, label=_("Display the results in Lignes De Temps"))
 
-class AddProjectForm (forms.Form):
+class AddProjectForm (ShareForm):
     title = forms.CharField(widget=forms.TextInput(attrs={'class':'inputbox required'}))
     description = forms.CharField(widget=forms.Textarea, required=False)
+    
+    class Meta:
+        model = Project
+        exclude = ("ldt_id", "ldt", "created_by", "changed_by", "creation_date", "modification_date", "state", "owner", "contents")   
 
 class CopyProjectForm (forms.Form):
     title = forms.CharField()
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_group.html	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_group.html	Tue Dec 06 17:45:35 2011 +0100
@@ -7,7 +7,8 @@
 {% block js_import %}
 	{{ block.super }}
     <script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}/js/jquery.nyroModal.min.js"></script>  
-	<script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}js/projectscontents.js" ></script>  
+	<script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}js/projectscontents.js" ></script> 
+	<script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}js/multiselect.js"></script>
 	{{ content_form.media.js }}
 {% endblock %}
 
@@ -47,50 +48,8 @@
 	{{ block.super }}
 	<script type="text/javascript">
 	
-	function move_users (from, to, users) {
-		var admins = $("#adminselection");		
-		for (var i=0; i < users.length; i++) {
-			var option = $("option[value=" + users[i] + "]", from);
-			option.css('color', 'black');
-			$("input[value=" + users[i]+ "]", admins).remove();
-			to.append(option);
-		}		
-	}
-	
-	function remove_from_form( form, user_list) {		
-		for (var i=0; i < user_list.length; i++) {
-			$("input[value=" + user_list[i] + "]", form).remove();
-		}
-	}
-	
-	function add_to_form(form, user_list, name) {		
-		for (var i=0; i < user_list.length; i++) {
-			form.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + user_list[i] + "\"/>");
-		}
-	}
-	
-	function get_all_options (select) {
-		var all = Array();
-		$("option", select).each(function()	{	
-			all.push($(this).val());
-		});
-		return all;
-	}	
-	
 	function init_events(container) {
-		filter_users();
-	}
-	
-	function filter_users() {
-		var members_list = get_all_options($("#selecteduserslist"));
-			
-		$("#userslist option").each(function () {
-			for (var i = 0; i < members_list.length; i++) {
-				if (members_list[i] == $(this).attr('value')) {
-					$(this).remove();
-				}
-			}		
-		});		
+		filter_elems($("#userslist"),$("#selecteduserslist") );
 	}
 	
 	$(document).ready(function() {	
@@ -99,54 +58,9 @@
 			parent.$.nmTop().close();
 		});
 		
-		$("#selectusers").click(function () {
-			var user_list = $("#userslist").val();
-			move_users($("#userslist"), $("#selecteduserslist"), user_list);
-			add_to_form($("#memberselection"), user_list, "members_list");
-		});
-		
-		$("#removeusers").click(function () {
-			var user_list = $("#selecteduserslist").val();
-			move_users($("#selecteduserslist"), $("#userslist"), user_list);
-			remove_from_form($("#memberselection"), user_list);
-		});
-		
-		$("#selectallusers").click(function () {
-			var user_list = get_all_options("#userslist");
-			move_users($("#userslist"), $("#selecteduserslist"), user_list);
-			add_to_form($("#memberselection"), user_list, "members_list");
-		});
-		
-		$("#removeallusers").click(function () {
-			var user_list = get_all_options("#selecteduserslist");
-			move_users($("#selecteduserslist"), $("#userslist"), get_all_options("#selecteduserslist"));
-			remove_from_form($("#memberselection"), user_list);
-		});
-		
-		$("#chooseadmin").click(function () {
-			var users = $("#selecteduserslist").val();
-			
-			for (var i=0; i < users.length; i++) {
-				$("#selecteduserslist option[value=" + users[i] + "]").css('color', '#2181B1');
-				$("#adminselection").append("<input type=\"hidden\" name=\"admin_list\" value=\"" + users[i]+ "\" />");
-			}
-		});
-		
-		$("#removeadmin").click(function () {
-			var users = $("#selecteduserslist").val();
-			
-			for (var i=0; i < users.length; i++) {
-				$("#selecteduserslist option[value=" + users[i] + "]").css('color', 'black');
-				$("#adminselection input[value=" + users[i]+ "]").remove();
-			}
-		});
-			
-		var user_filter_url = "{% url ldt.ldt_utils.views.users_filter filter='__FILTER__' id_group='__ID_GROUP__'%}";
-		input_list_init = [
-			{'input_selector':"#searchuserinput", 'container_selector':"#userslist", 'url':user_filter_url}
-		];	           	
-		searchFieldInit(input_list_init);
-		filter_users();
+		var search_url = "{% url ldt.ldt_utils.views.share_filter filter='__FILTER__' %}";
+		init_multi_select_events ($("#userslist"), $("#selecteduserslist"), $("#memberselection"), $("#adminselection"), "#searchuserinput", search_url);
+
 	});
 	</script>
 
@@ -175,15 +89,15 @@
 			<div class="searchfield rounded span-4"><input type="text" name="search" id="searchuserinput" class="searchfieldinput searchfieldinputbase" value="{% trans 'search' %}"/><img id="projectsajaxloader" class="searchajaxloader" src="{{LDT_MEDIA_PREFIX}}/img/ajax-loader-16x16.gif" alt="loader"/><img id="projecsclear" class="searchclear" src="{{LDT_MEDIA_PREFIX}}img/clear-left.png"/></div>
 		</div><br /><br />	
 		<select multiple="multiple" id="userslist">
-			{% include "ldt/ldt_utils/partial/userslist.html" %}
+			{% include "ldt/ldt_utils/partial/sharewith.html" %}
 		</select>
 		<div id="userslistfooter">
-			<a href="#" id="selectallusers" title="{% trans "select all users" %}">{% trans "select all" %}</a>
+			<a href="#" id="selectall" title="{% trans "select all users" %}">{% trans "select all" %}</a>
 		</div>
 	</div>
 	<div id="selectors">
-		<a href="#" id="selectusers"><img src="{{LDT_MEDIA_PREFIX}}img/to-right.gif" title="{% trans "select users" %}"></a><br />
-		<a href="#" id="removeusers"><img src="{{LDT_MEDIA_PREFIX}}img/to-left.gif" title="{% trans "remove users" %}"></a>
+		<a href="#" id="selectelems"><img src="{{LDT_MEDIA_PREFIX}}img/to-right.gif" title="{% trans "select users" %}"></a><br />
+		<a href="#" id="removeelems"><img src="{{LDT_MEDIA_PREFIX}}img/to-left.gif" title="{% trans "remove users" %}"></a>
 	</div>
 	
 	<div id="memberslistcontainer">
@@ -196,9 +110,9 @@
 			{% endfor %}
 		</select>
 		<div id="selecteduserslistfooter" >
-			<a href="#" id="removeallusers" title="{% trans "select all users" %}">{% trans "remove all" %}</a>
-			| <a href="#" id="chooseadmin" title="{% trans "Decide whether a user user can change this group" %}">{% trans "is admin" %}</a>
-			| <a href="#" id="removeadmin">{% trans "is not admin" %}</a>
+			<a href="#" id="removeall" title="{% trans "select all users" %}">{% trans "remove all" %}</a>
+			| <a href="#" id="chooseaux" title="{% trans "Decide whether a user user can change this group" %}">{% trans "is admin" %}</a>
+			| <a href="#" id="removeaux">{% trans "is not admin" %}</a>
 		</div>	
 	</div>	
 	
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_ldt.html	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/create_ldt.html	Tue Dec 06 17:45:35 2011 +0100
@@ -5,7 +5,9 @@
 
 {% block js_import %}
 	{{ block.super }}
-    <script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}/js/jquery.nyroModal.min.js"></script>    
+    <script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}/js/jquery.nyroModal.min.js"></script> 
+    <script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}js/projectscontents.js"></script>  
+    <script type="text/javascript" src="{{LDT_MEDIA_PREFIX}}js/multiselect.js"></script> 
 	{{ content_form.media.js }}
 {% endblock %}
 
@@ -14,29 +16,16 @@
 	{{ content_form.media.css }}
 	<link rel="stylesheet" href="{{LDT_MEDIA_PREFIX}}css/ldt.css" />
 	<link rel="stylesheet" href="{{LDT_MEDIA_PREFIX}}css/ldtform.css" />
-	<link rel="stylesheet" href="{{LDT_MEDIA_PREFIX}}css/workspace.css" />
-	
+	<link rel="stylesheet" href="{{LDT_MEDIA_PREFIX}}css/workspace.css" />	
 {% endblock %}
 
 {% block js_declaration %}
 	{{ block.super }}
 	<script type="text/javascript">
 	
-	function activate_initial_permissions() {		
-		$("#grouplist tr").each(function (e) {
-			if ($("input[type=checkbox]", $(this)).is(":checked")) {
-				var perm = $(".perm_field", $(this)).val();
-				if (perm) {
-					$(".perm_read, .perm_write", $(this)).addClass("permission");
-				}				
-				if (perm == 'read') {
-					$(".perm_read", $(this)).addClass("choice");
-				} else if (perm == 'write') {
-					$(".perm_write", $(this)).addClass("choice");
-				} 				
-			}
-		});
-	}
+	function init_events(container) {
+		filter_elems($("#sharelist"),$("#selectedlist") );
+	}	
 	
 	$(document).ready(function() {
 		
@@ -51,8 +40,6 @@
 			e.preventDefault();
 			parent.$.nmTop().close();
 		});		
-
-		check_uncheck_all("group");
 				
 	});
 	</script>
@@ -68,11 +55,10 @@
         theme_advanced_buttons3 : "",
         theme_advanced_toolbar_location : "top",
         theme_advanced_toolbar_align : "left",
-        width: "665",
-        height: "150"       
+        width: "300",
+        height: "150"
 	});
 
-
     </script>
 
 {% endblock %}
@@ -90,38 +76,7 @@
 	{% endfor %}
 	<label for="description" class="projectdesc">{% trans "Description :" %}</label>
 	{{form.description}}
-	
-	<div id="lefttable" class="span-9">
-	<label>{% trans "List of contents" %}</label>
-
-		<div class="span-8 last" id="ldtcreatecontentslistcontainer">
-			<div class="span-8 last projectscontentstablediv" id="ldtcreatecontentstablediv">
-				<table class="projectscontentstable">
-				
-					<tr class="projectscontentsheader last" id="contentslistheader">
-						<td class="cellcheckbox">
-						{% if not ldt_id %}
-							{% if contents|length > 1 %}
-							<input class="selectallcontents" id="global_checkbox_content" type="checkbox" checked="true" />	 
-							{% endif %}
-						{% endif %}	
-						</td>				
-						<td class="projectcontentsheadertitle">{% trans "name" %}</td>
-					</tr>
-				
-				    <tbody class="projectscontentsbody">
-				{% for content in contents %}
-					<tr class="imageline {% cycle 'projectscontentsoddline' 'projectscontentsevenline'%}">
-					    <td class="cellcheckbox"><input type="checkbox" class="checkbox_content" name="contents" value="{{ content.id }}" checked="true" {% if ldt_id %}disabled="disabled"{% endif %} /></td>
-					    <td class="contenttitle">{{ content.title }}</td>
-					</tr>
-				{% endfor %}
-					</tbody>
-				</table>			
-			</div>
-		</div>
-	</div>	
-     
+   
     {% include "ldt/ldt_utils/partial/permissions.html" %}
                    
     <div id="submitcontent-buttons" class="span-11 last">
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/permissions.html	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/permissions.html	Tue Dec 06 17:45:35 2011 +0100
@@ -1,99 +1,77 @@
 {% load i18n %}
 
+<style type="text/css">
+	  select {
+	    width: 200px;
+	    height: 200px;
+	    margin: 5px;
+	  }
+	  
+	  #elemslistcontainer,  #selectedlistcontainer, #selectors {
+	  	float: left;
+	  }
+	  
+	  #selectedlistcontainer {
+	  	margin-top: 35px;
+	  }
+	  
+	  #selectedlistfooter, #elemslistfooter {
+	  	text-align: center;
+	  }
+	  
+	  #selectors {	  
+	  	margin-top: 125px;
+	  }
+	  	   
+	</style>
+	
+	
 <script type="text/javascript">
 	
-	function activate_initial_permissions() {		
-		$("#grouplist tr").each(function (e) {
-			if ($("input[type=checkbox]", $(this)).is(":checked")) {
-				var perm = $(".perm_field", $(this)).val();
-				var line = $(this).closest("tr");
-				if (perm) {
-					$(".perm_read, .perm_write", $(this)).addClass("pointer");
-				}				
-				if (perm == 'read') {
-					$(".perm_read", $(this)).addClass("bold");
-				} else if (perm == 'write') {
-					$(".perm_write", $(this)).addClass("bold");
-				} 				
-			}
-		});
-	}
-	
-	function activate_rw_events() {
-		$(".pointer").live('click', function () {
-            var group_name = $(this).attr('value');
-        	var group_id = group_name.split('_').pop();
-            
-            $("a[value=\"" + group_name + "\"]").removeClass('bold');
-            $(this).addClass('bold');
-            
-            if ($(this).hasClass('perm_read')) {
-            	var perm = 'read';
-            } else {
-            	var perm = 'write';            	
-            }
-            
-            $(".perm_field",$(this).closest('tr')).attr('value', perm);
-        });
-		
-        $(".checkbox_group").live('change', function() {
-            var line = $(this).closest('tr');
-            
-            $(".perm_read, .perm_write", line).removeClass("bold");
-			
-            if (!$(this).is(":checked")) {
-                $(".bold", line).removeClass('bold');
-                $(".perm_read, .perm_write", line).removeClass('pointer');
-            } else {
-                $(".perm_read", line).addClass('bold');
-                $(".perm_read, .perm_write", line).addClass('pointer');
-            }
-        }); 
-	}
-	
 	$(document).ready(function() {
-		check_uncheck_all("group");
-		activate_initial_permissions();
-		activate_rw_events();				
+		var search_url = "{% url ldt.ldt_utils.views.share_filter filter='__FILTER__' %}";
+
+		init_multi_select_events ($("#sharelist"), $("#selectedlist"), $("#read"), $("#write"), "#searchuserinput", search_url);
 	});
 </script>
 
+<div id="elemslistcontainer">
+	<div id="elemslistheader">
+		{% trans "User list" %}<br />
+		<div class="searchfield rounded span-4"><input type="text" name="search" id="searchuserinput" class="searchfieldinput searchfieldinputbase" value="{% trans 'search' %}"/><img id="projectsajaxloader" class="searchajaxloader" src="{{LDT_MEDIA_PREFIX}}/img/ajax-loader-16x16.gif" alt="loader"/><img id="projecsclear" class="searchclear" src="{{LDT_MEDIA_PREFIX}}img/clear-left.png"/></div>
+	</div><br /><br />	
+	<select multiple="multiple" id="sharelist">
+		{% include "ldt/ldt_utils/partial/sharewith.html" %}
+	</select>
+	<div id="elemslistfooter">
+		<a href="#" id="selectall" title="{% trans "select all users" %}">{% trans "select all" %}</a>
+	</div>
+</div>
 
-<div id="righttable" class="span-9">
-	    <label>{% trans "group list"%}</label>
+<div id="selectors">
+	<a href="#" id="selectelems"><img src="{{LDT_MEDIA_PREFIX}}img/to-right.gif" title="{% trans "select users" %}"></a><br />
+	<a href="#" id="removeelems"><img src="{{LDT_MEDIA_PREFIX}}img/to-left.gif" title="{% trans "remove users" %}"></a>
+</div>
 	
-        <div class="span-8 last" id="ldtcreatecontentslistcontainer">
-            <div class="span-8 last projectscontentstablediv" id="ldtcreatecontentstablediv">
-                <table class="projectscontentstable">
-                    {{ management_form }}
-                
-                    <tr class="projectscontentsheader last" id="contentslistheader">
-                        <td class="cellcheckbox">                        
-                        {% if groups|length > 1 %}
-                        	<input class="selectallgroups" id="global_checkbox_group" type="checkbox" />
-                        {% endif %}                            
-                        </td>				
-                        <td class="projectcontentsheadertitle">{% trans "nom" %}</td>
-                        <td class="projectcontentsheadertitle span-3" >{% trans "Permissions" %}</td>
-                    </tr>
-                
-                    <tbody class="projectscontentsbody" id="grouplist">
-                
-				    {% for form, group in group_form %}			    			    
-				    <tr class="imageline projectscontentsoddline">
-				    	<td class="cellcheckbox">{{ form.share }}</td>
-				    	<td class="projecttitle">{{ group.name }}</td>
-				    	<td>
-				    	<a value="group_{{group.id}}" class="perm_read" title="{% trans "This group can read the project" %}">{% trans "perm.read" %}</a>
-				        <a value="group_{{group.id}}" class="perm_write" title="{% trans "This group can change the project" %}">{% trans "perm.write" %}</a>
-				       	</td>
-				       	{{ form.perms }}
-				       	{{ form.group }}
-				    </tr>
-				    {% endfor %}
-				    				                
-                    </tbody>
-                </table>		
-            </div>		
-      </div>       
-</div>      
+<div id="selectedlistcontainer">
+	<div id="selectedlistheader">
+		{% trans "Members list" %}
+	</div>
+	<select multiple="multiple" id="selectedlist" >
+		{% for user in member_list %}
+			<option value="{{user.type}}-{{ user.id }}" {% if user.change %}style="color: #2181B1;"{% endif %}>{{ user.username }}</option>
+		{% endfor %}
+	</select>
+	<div id="selectedlistfooter" >
+		<a href="#" id="removeall" title="{% trans "select all users" %}">{% trans "remove all" %}</a>
+		| <a href="#" id="chooseaux" title="{% trans "Decide whether a user user can change this group" %}">{% trans "is admin" %}</a>
+		| <a href="#" id="removeaux">{% trans "is not admin" %}</a>
+	</div>	
+</div>
+
+<div id="read">
+</div>
+
+<div id="write">
+</div>
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/sharewith.html	Tue Dec 06 17:45:35 2011 +0100
@@ -0,0 +1,5 @@
+{% load i18n %}
+
+{% for res in elem_list%}
+	<option value="{{ res.id }}-{{ res.type }}" >{{ res.name }}</option>
+{% endfor %}
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/userslist.html	Mon Dec 05 14:25:21 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% load i18n %}
-
-{% for user in user_list %}
-	<option value="{{ user.id }}">{{ user.username }}</option>
-{% endfor %}
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/urls.py	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/urls.py	Tue Dec 06 17:45:35 2011 +0100
@@ -32,7 +32,7 @@
     url(r'^filterprojects/_(?P<filter>[\w\%\_\-\+]*?)/(?P<is_owner>true|false)/(?P<status>\d)/(?P<id_group>.*)$', "views.projects_filter",),
     url(r'^filtercontents/_(?P<filter>[\w\%\_\-\+]*?)/$', "views.contents_filter",),
     url(r'^filtergroups/_(?P<filter>[\w\%\_\-\+]*?)/$', "views.groups_filter",),
-    url(r'filterusers/_(?P<filter>[\w\%\_\-\+]*?)/(?P<id_group>.*)$', "views.users_filter"),
+    url(r'filtershare/_(?P<filter>[\w\%\_\-\+]*?)/$', "views.share_filter"),
     (r'^embedpopup/?$', "views.popup_embed"),
     url(r'^segment/(?P<project_id>.*)/(?P<content_id>.*)/(?P<ensemble_id>.*)/(?P<cutting_id>.*)/(?P<segment_id>.*)/$', 'views.index_segment'),
     url(r'^segmentInit/(?P<project_id>.*)/(?P<content_id>.*)/(?P<ensemble_id>.*)/(?P<cutting_id>.*)/(?P<segment_id>.*)/$', 'views.init_segment'),
--- a/src/ldt/ldt/ldt_utils/views.py	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/ldt_utils/views.py	Tue Dec 06 17:45:35 2011 +0100
@@ -20,7 +20,7 @@
 from forms import (LdtAddForm, SearchForm, AddProjectForm, CopyProjectForm,
     ContentForm, MediaForm, GroupAddForm, PermissionForm)
 from guardian.core import ObjectPermissionChecker
-from guardian.shortcuts import assign, remove_perm, get_perms, get_objects_for_group
+from guardian.shortcuts import assign, remove_perm, get_perms, get_objects_for_group, get_objects_for_user
 from ldt.ldt_utils.models import Content
 from ldt.ldt_utils.utils import boolean_convert, LdtUtils, LdtSearch
 from ldt.security.utils import (assign_object_to_groups, set_forbidden_stream, 
@@ -181,27 +181,28 @@
                               {'projects': project_list, 'show_username':show_username,
                                'is_gecko': is_gecko, 'group_id':id_group},
                               context_instance=RequestContext(request))
+
+def share_filter(request, filter):
     
-def users_filter(request, filter, id_group=None):
-    if filter and len(filter) > 0 and filter[0] == '_':
-        filter = filter[1:]
+    if not filter or len(filter) == 0:
+        raise AttributeError("filter should be a string")
     
-    query = Q(id=settings.ANONYMOUS_USER_ID) | Q(id=request.user.id) | Q(is_superuser=True)   
-    filter_query = Q(username__icontains=filter) if filter else Q()    
-    user_list = User.objects.exclude(query).filter(filter_query)[0:20]  
+    filter = filter[1:]
+    
+    users = User.objects.filter(username__icontains=filter)[0:20]
+    groups = Group.objects.filter(name__icontains=filter).exclude(name=settings.PUBLIC_GROUP_NAME)[0:20]
     
-    if id_group:
-        group = Group.objects.get(id=id_group)
-        members_list = group.user_set.all()
-        for u in user_list:
-            if u in members_list:
-                u.member = True
-            if u.has_perm('change_group', group):
-                u.admin = True  
+    resp = []
+    for u in users:
+        resp.append({'name':u.username, 'id':u.id, 'type': 'user'})
     
-    return render_to_response("ldt/ldt_utils/partial/userslist.html", {'user_list': user_list},
-                              context_instance=RequestContext(request))
-
+    for g in groups:
+        resp.append({'name': g.name, 'id': g.id, 'type': 'group'})
+   
+    resp = sorted(resp, key=lambda elem: elem['name'].lower())
+    
+    return render_to_response("ldt/ldt_utils/partial/sharewith.html", {'elem_list' : resp}, context_instance=RequestContext(request))
+    
 @login_required
 def contents_filter(request, filter): 
     if filter and len(filter) > 0 and filter[0] == '_':
@@ -222,7 +223,6 @@
                               {'contents': content_list},
                               context_instance=RequestContext(request))
 
-
 @login_required
 def groups_filter(request, filter):
     if filter and len(filter) > 0 and filter[0] == '_':
@@ -449,40 +449,38 @@
 
 @login_required
 def create_ldt_view(request):
-    permission_formset = formset_factory(PermissionForm, extra=0)
     groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME)
     redirect_to = ''
     if request.method == "POST" :
         form = LdtAddForm(request.POST)
         form_status = "none"
         contents = Content.safe_objects.all()
-        group_form = permission_formset(request.POST)
-                
-        if form.is_valid() and group_form.is_valid():
-            user = request.user
-            
+           
+        if form.is_valid():            
+            user = request.user            
             project = Project.create_project(title=form.cleaned_data['title'], user=user, 
-                                             contents=form.cleaned_data['contents'],
+                                             #contents=form.cleaned_data['contents'],
+                                             contents=[],
                                              description=form.cleaned_data['description'])
   
-            assign_object_to_groups(project, group_form.cleaned_data)
+            assign_object_to_groups(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], user)
             form_status = "saved"
             is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
             if is_gecko :
                 redirect_to = reverse('index_project_full', args=[project.ldt_id])
             else:
-                return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id]))        
-
-        management_form, group_form  = get_perm_form(groups, permission_formset)  
-                  
+                return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id]))       
+     
     else:
         form = LdtAddForm()
-        contents = Content.safe_objects.all() #@UndefinedVariable        
-        management_form, group_form  = get_perm_form(groups, permission_formset)        
+        contents = Content.safe_objects.all()             
         form_status = "none"    
-            
-    return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form, 'group_form': group_form, 'management_form': management_form, 'form_status':form_status,
-                                                                'redirect_to': redirect_to, 'create_project_action':reverse(create_ldt_view), 'language_code' : settings.LANGUAGE_CODE[2:]}, context_instance=RequestContext(request))
+    
+    user_list = User.objects.all()[0:20]
+    elem_list = [{'name': u.username, 'id': u.id, 'type': 'user'} for u in user_list]
+    return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form, 'form_status':form_status,
+                                                                'redirect_to': redirect_to, 'create_project_action':reverse(create_ldt_view), 'language_code' : settings.LANGUAGE_CODE[2:],
+                                                                'elem_list': elem_list}, context_instance=RequestContext(request))
      
 def created_ldt(request):
     return render_to_response('ldt/ldt_utils/save_done.html', context_instance=RequestContext(request))
@@ -500,7 +498,6 @@
 def init_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id):
 
     if project_id != u"_":
-        assert False, project_id
         get_object_or_404(Project.safe_objects, ldt_id=project_id)
     
     ldtgen = LdtUtils()
@@ -842,7 +839,6 @@
 
 @login_required
 def create_project(request, iri_id): 
-    permission_formset = formset_factory(PermissionForm, extra=0)
     content = get_object_or_404(Content.safe_objects, iri_id=iri_id)
     contents = [ content, ]
     groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME)
@@ -851,39 +847,36 @@
     
     if request.method == "POST" :
         
-        group_form = permission_formset(request.POST)
         form = AddProjectForm(request.POST)
         
-        if form.is_valid() and group_form.is_valid():
+        if form.is_valid():
             user = request.user
             project = Project.create_project(title=form.cleaned_data['title'], user=user, contents=contents, description=form.cleaned_data['description'])
-            form_status = "saved"
+            form_status = "saved" 
+            assign_object_to_groups(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], user)
+
             # Modal window is not used with firefox
             is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
             if is_gecko :
                 redirect_to = reverse('index_project_full', args=[project.ldt_id])
             else:
                 return HttpResponseRedirect(reverse('index_project', args=[project.ldt_id]))
-            assign_object_to_groups(project, group_form.cleaned_data)
-        
-        management_form, group_form = get_perm_form(groups, permission_formset)  
+         
 
     else:
         form = AddProjectForm()
-        management_form, group_form = get_perm_form(groups, permission_formset)
         
-    return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status': form_status, 'contents':contents,'groups' : groups, 'group_form': group_form,
-                                                                'management_form': management_form, 'redirect_to': redirect_to, 'create_project_action':reverse("ldt.ldt_utils.views.create_project", args=[iri_id])}, context_instance=RequestContext(request))
+    return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status': form_status, 'contents':contents,'groups' : groups,
+                                                                'redirect_to': redirect_to, 'create_project_action':reverse("ldt.ldt_utils.views.create_project", args=[iri_id])}, context_instance=RequestContext(request))
 
 @login_required
 def update_project(request, ldt_id):
-    permission_formset = formset_factory(PermissionForm, extra=0)
     project = get_object_or_404(Project.safe_objects, ldt_id=ldt_id)
     contents = project.contents.all()
     groups = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME)
-    
-    management_form = None    
-        
+    elem_list = User.objects.all()[0:20]
+    elem_list = [{'name': e.username, 'id': e.id, 'type': e.type} for e in elem_list]
+            
     if request.method == "POST" :
         submit_action = request.REQUEST.get("submit_button", False)
         if submit_action == "prepare_delete":
@@ -901,14 +894,11 @@
                 project.delete()
             form_status = 'deleted'
             form = AddProjectForm()
-            group_form = permission_formset()
         else:
             form_status = 'none' 
             form = AddProjectForm(request.POST)
-            group_form = permission_formset(request.POST)
             
-            if form.is_valid() and group_form.is_valid():
-                
+            if form.is_valid():          
                 if project.title != form.cleaned_data['title'] or project.description != form.cleaned_data['description']:
                     project.title = form.cleaned_data['title']
                     project.description = form.cleaned_data['description']
@@ -919,32 +909,15 @@
                     project.ldt = lxml.etree.tostring(ldt, pretty_print=True)
                     project.save()                    
                     
-                assign_object_to_groups(project, group_form.cleaned_data)
+                assign_object_to_groups(project, form.cleaned_data["read_list"], form.cleaned_data["write_list"], request.user)
                 form_status = "saved"
     else:
         form = AddProjectForm({'title':unicode(project.title), 'description':unicode(project.get_description())})
         
-        perm_list = [] 
-        for group in groups:
-            group_perms = get_perms(group, project)
-            share = False
-            perm = None
-            if 'view_project' in group_perms:
-                share = True
-                perm = 'read'
-            if 'change_project' in group_perms:
-                perm = 'write'
-                
-            perm_list.append({'share': share, 'perms': perm, 'group': group.id })
-        permission = permission_formset(initial=perm_list)    
-        management_form = permission.management_form
-        group_form = zip(permission, groups)
-
         form_status = 'none'
        
     return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'form_status':form_status, 'groups': groups,
-                              'ldt_id': ldt_id, 'contents':contents, 'group_form': group_form, 'management_form': management_form, 
-                              'create_project_action':reverse("ldt.ldt_utils.views.update_project", args=[ldt_id])}, context_instance=RequestContext(request))
+                                                                'elem_list': elem_list, 'ldt_id': ldt_id, 'contents':contents, 'create_project_action':reverse("ldt.ldt_utils.views.update_project", args=[ldt_id])}, context_instance=RequestContext(request))
 
 @login_required
 def copy_project(request, ldt_id, group_id=None): 
@@ -1334,6 +1307,7 @@
         return HttpResponseServerError('<h1>User can not leave a group.</h1>')
     query = Q(id=settings.ANONYMOUS_USER_ID) | Q(id=request.user.id) | Q(is_superuser=True)
     user_list = User.objects.exclude(query)[0:20]
+    user_list = [{'name': x.username, 'id': x.id, 'type': 'user'} for x in user_list]
     form_status = ''
     
     if request.method == 'POST':
@@ -1359,7 +1333,7 @@
         form = GroupAddForm()
         form.fields['members_list'].queryset = user_list       
     
-    return render_to_response("ldt/ldt_utils/create_group.html", {'form' : form, 'form_status' : form_status, 'user_list' : user_list, 'admin_list': user_list}, context_instance=RequestContext(request))
+    return render_to_response("ldt/ldt_utils/create_group.html", {'form' : form, 'form_status' : form_status, 'elem_list' : user_list}, context_instance=RequestContext(request))
 
 @login_required
 def update_group(request, group_id):
@@ -1398,7 +1372,7 @@
                         
                 for user in new_member_list:                       
                     group.user_set.add(user)
-                    if user in admin_list and user.get_profile().is_regular:
+                    if user in admin_list:
                         assign('change_group', user, group)
                     else:
                         remove_perm('change_group', user, group)
--- a/src/ldt/ldt/security/utils.py	Mon Dec 05 14:25:21 2011 +0100
+++ b/src/ldt/ldt/security/utils.py	Tue Dec 06 17:45:35 2011 +0100
@@ -1,8 +1,7 @@
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
-from django.contrib.auth.models import Group
 from guardian.core import ObjectPermissionChecker
-from guardian.shortcuts import assign, remove_perm
+from guardian.shortcuts import assign, remove_perm, get_users_with_perms, get_groups_with_perms
 
 try:
     from threading import local
@@ -104,19 +103,28 @@
             
     return obj_list      
 
-def assign_object_to_groups(object, permissions):
+def assign_object_to_groups(object, read_list, write_list, owner):
     name = object.__class__.__name__.lower()
-    for elem in permissions:
-        group = Group.objects.get(id=elem['group'])
-        if elem['share']:
-            assign('view_%s' % name, group, object)
-            if elem['perms'] == 'write':
-                assign('change_%s' % name, group, object)
-            else:
-                remove_perm('change_%s' % name, group, object)
+    
+    old_users = get_users_with_perms(object).exclude(id=owner.id)
+    old_groups = get_groups_with_perms(object)
+    
+    for elem in read_list:
+        assign('view_%s' % name, elem, object)
+        if elem in write_list:
+            assign('change_%s' % name, elem, object)
         else:
-            remove_perm('view_%s' % name, group, object)
-            remove_perm('change_%s' % name, group, object)
+            remove_perm('change_%s' % name, elem, object)            
+                
+    def remove_perms(new_list, old_list, obj, name):
+        for e in old_list:
+            if e not in new_list:
+                remove_perm('view_%s' % name, e, obj)
+                remove_perm('change_%s' % name, e, obj)
+                
+    remove_perms(read_list, old_users, object, name)
+    remove_perms(read_list, old_groups, object, name)
+            
             
 def get_perm_form(groups, formset):
     perm_list = [] 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/static/ldt/js/multiselect.js	Tue Dec 06 17:45:35 2011 +0100
@@ -0,0 +1,103 @@
+function init_multi_select_events (first_list, sec_list, first_selection, sec_selection, search_input, search_url) {
+	
+	$("#selectelems").click(function () {
+		var list = get_selected_elems(first_list);
+		move_elem(first_list, sec_list, list);
+		add_to_form(first_selection, list, "read_list");
+	});
+
+	$("#removeelems").click(function () {
+		var list = get_selected_elems(sec_list);
+		move_elem(sec_list, first_list, list);
+		remove_from_form(first_selection, list);
+	});
+
+	$("#selectall").click(function () {
+		var list = get_all_options(first_list);
+		move_elem(first_list, sec_list, list);
+		add_to_form(first_selection, list, "read_list");
+	});
+
+	$("#removeall").click(function () {
+		var elem_list = get_all_options(sec_list);
+		move_elem(sec_list, first_list, get_all_options(sec_list));
+		remove_from_form(first_selection, elem_list);
+		remove_from_form(sec_selection, elem_list);
+	});
+
+	$("#chooseaux").click(function () {
+		var elems = get_selected_elems(sec_list);
+		
+		for (var i=0; i < elems.length; i++) {
+			$("option[value=" + elems[i] + "]", sec_list).css('color', '#2181B1');
+			$(sec_selection).append("<input type=\"hidden\" name=\"write_list\" value=\"" + elems[i]+ "\" />");
+		}
+	});
+
+	$("#removeaux").click(function () {
+		var users = get_selected_elems(sec_list);
+		
+		for (var i=0; i < users.length; i++) {
+			$("option[value=" + users[i] + "]", sec_list).css('color', 'black');
+			$("input[value=" + users[i] + "]", sec_selection).remove();
+		}
+	});	
+	
+	$(document).ready(function () {
+		filter_elems(first_list, sec_list);
+		input_list_init = [
+			{'input_selector':search_input, 'container_selector': first_list, 'url':search_url}
+		];	           	
+		searchFieldInit(input_list_init);
+	});
+}
+
+function move_elem (from, to, elems) {
+	var selected = $("#sec_selection");		
+	for (var i=0; i < elems.length; i++) {
+		var option = $("option[value=" + elems[i] + "]", from);
+		option.css('color', 'black');
+		$("input[value=" + elems[i] + "]", selected).remove();
+		to.append(option);
+	}		
+}
+
+function get_selected_elems(list) {
+	var selected = Array();
+	$("option:selected", list).each(function (e) {
+		selected.push($(this).val());
+	});
+	return selected;
+}
+
+function remove_from_form(form, elem_list) {		
+	for (var i=0; i < elem_list.length; i++) {
+		$("input[value=" + elem_list[i] + "]", form).remove();
+	}
+}
+
+function add_to_form(form, elem_list, name) {		
+	for (var i=0; i < elem_list.length; i++) {
+		form.append("<input type=\"hidden\" name=\"" + name + "\" value=\"" + elem_list[i] + "\"/>");
+	}
+}
+
+function get_all_options (select) {
+	var all = Array();
+	$("option", select).each(function()	{
+		all.push($(this).val());
+	});
+	return all;
+}	
+
+function filter_elems(first_list, sec_list) {
+	var selected = get_all_options(sec_list);
+		
+	$("option", first_list).each(function () {
+		for (var i = 0; i < selected.length; i++) {
+			if (selected[i] == $(this).attr('value')) {
+				$(this).remove();
+			}
+		}		
+	});		
+}
\ No newline at end of file