1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
4 # This file is part of the Patchwork package.
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 from django.contrib.auth.models import User
22 from django import forms
24 from patchwork.models import Patch, State, Bundle, UserProfile
25 from registration.forms import RegistrationFormUniqueEmail
26 from registration.models import RegistrationProfile
28 class RegistrationForm(RegistrationFormUniqueEmail):
29 first_name = forms.CharField(max_length = 30, required = False)
30 last_name = forms.CharField(max_length = 30, required = False)
31 username = forms.CharField(max_length=30, label=u'Username')
32 email = forms.EmailField(max_length=100, label=u'Email address')
33 password = forms.CharField(widget=forms.PasswordInput(),
35 password1 = forms.BooleanField(required = False)
36 password2 = forms.BooleanField(required = False)
38 def save(self, profile_callback = None):
39 user = RegistrationProfile.objects.create_inactive_user( \
40 username = self.cleaned_data['username'],
41 password = self.cleaned_data['password'],
42 email = self.cleaned_data['email'],
43 profile_callback = profile_callback)
44 user.first_name = self.cleaned_data.get('first_name', '')
45 user.last_name = self.cleaned_data.get('last_name', '')
50 return self.cleaned_data
52 class LoginForm(forms.Form):
53 username = forms.CharField(max_length = 30)
54 password = forms.CharField(widget = forms.PasswordInput)
56 class BundleForm(forms.ModelForm):
59 fields = ['name', 'public']
61 class CreateBundleForm(forms.ModelForm):
62 def __init__(self, *args, **kwargs):
63 super(CreateBundleForm, self).__init__(*args, **kwargs)
70 name = self.cleaned_data['name']
71 count = Bundle.objects.filter(owner = self.instance.owner, \
74 raise forms.ValidationError('A bundle called %s already exists' \
78 class DelegateField(forms.ModelChoiceField):
79 def __init__(self, project, *args, **kwargs):
80 queryset = User.objects.filter(userprofile__in = \
82 .filter(maintainer_projects = project) \
84 super(DelegateField, self).__init__(queryset, *args, **kwargs)
87 class PatchForm(forms.ModelForm):
88 def __init__(self, instance = None, project = None, *args, **kwargs):
89 if (not project) and instance:
90 project = instance.project
92 raise Exception("meep")
93 super(PatchForm, self).__init__(instance = instance, *args, **kwargs)
94 self.fields['delegate'] = DelegateField(project, required = False)
98 fields = ['state', 'archived', 'delegate']
100 class UserProfileForm(forms.ModelForm):
103 fields = ['primary_project', 'patches_per_page']
105 class OptionalDelegateField(DelegateField):
106 no_change_choice = ('*', 'no change')
108 def __init__(self, no_change_choice = None, *args, **kwargs):
110 if (no_change_choice):
111 self.no_change_choice = no_change_choice
112 super(OptionalDelegateField, self). \
113 __init__(initial = self.no_change_choice[0], *args, **kwargs)
115 def _get_choices(self):
117 super(OptionalDelegateField, self)._get_choices())
118 choices.append(self.no_change_choice)
121 choices = property(_get_choices, forms.ChoiceField._set_choices)
123 def is_no_change(self, value):
124 return value == self.no_change_choice[0]
126 def clean(self, value):
127 if value == self.no_change_choice[0]:
129 return super(OptionalDelegateField, self).clean(value)
131 class OptionalModelChoiceField(forms.ModelChoiceField):
132 no_change_choice = ('*', 'no change')
134 def __init__(self, no_change_choice = None, *args, **kwargs):
136 if (no_change_choice):
137 self.no_change_choice = no_change_choice
138 super(OptionalModelChoiceField, self). \
139 __init__(initial = self.no_change_choice[0], *args, **kwargs)
141 def _get_choices(self):
143 super(OptionalModelChoiceField, self)._get_choices())
144 choices.append(self.no_change_choice)
147 choices = property(_get_choices, forms.ChoiceField._set_choices)
149 def is_no_change(self, value):
150 return value == self.no_change_choice[0]
152 def clean(self, value):
153 if value == self.no_change_choice[0]:
155 return super(OptionalModelChoiceField, self).clean(value)
157 class MultipleBooleanField(forms.ChoiceField):
158 no_change_choice = ('*', 'no change')
159 def __init__(self, *args, **kwargs):
160 super(MultipleBooleanField, self).__init__(*args, **kwargs)
161 self.choices = [self.no_change_choice] + \
162 [(True, 'Archived'), (False, 'Unarchived')]
164 def is_no_change(self, value):
165 return value == self.no_change_choice[0]
167 class MultiplePatchForm(PatchForm):
168 state = OptionalModelChoiceField(queryset = State.objects.all())
169 archived = MultipleBooleanField()
171 def __init__(self, project, *args, **kwargs):
172 super(MultiplePatchForm, self).__init__(project = project,
174 self.fields['delegate'] = OptionalDelegateField(project = project,
177 def save(self, instance, commit = True):
178 opts = instance.__class__._meta
180 raise ValueError("The %s could not be changed because the data "
181 "didn't validate." % opts.object_name)
182 data = self.cleaned_data
183 # remove 'no change fields' from the data
184 for f in opts.fields:
185 if not f.name in data:
188 field = self.fields.get(f.name, None)
192 if field.is_no_change(data[f.name]):
195 return forms.save_instance(self, instance,
196 self._meta.fields, 'changed', commit)
198 class UserPersonLinkForm(forms.Form):
199 email = forms.EmailField(max_length = 200)