A lot of template improvements and translation fixes
- Fixed agenda widget for special slide views (e.g. list of speakers, summary). - Fixed back to motion(s) link - Set icon for list of speakers widget. - Fixed overlay widget layout of form elements. - Added submenu with other config_pages to version.html. - Updated completly DE translations, fixed EN strings. - Coding style: Use correct ugettext and ugettext_lazy strings. Use "as _" for ugettext only. Updated translation. - Improved projector template (clock image, fixed facicon, added subtitle for list of speakers) - Changed permission strings ('oneself'). Added check if group(pk=3) exists. - Added event name and description to base template. Some minor template layout fixes. - Use static subtile (no context var). Show last 2 old_speakers for projector. - Cut old_speakers. - Projektor template style changes (e.g. overlay list of speakers).
This commit is contained in:
parent
f581169e1e
commit
abad75c129
@ -45,7 +45,6 @@ def get_personal_info_widget(request):
|
||||
'submitted_motions': Motion.objects.filter(submitter=request.user),
|
||||
'config_motion_min_supporters': config['motion_min_supporters'],
|
||||
'supported_motions': Motion.objects.filter(supporter=request.user)})
|
||||
|
||||
try:
|
||||
from openslides.assignment.models import Assignment
|
||||
except ImportError:
|
||||
|
@ -14,7 +14,7 @@ from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext_noop, ugettext
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop, ugettext as _
|
||||
|
||||
from mptt.models import MPTTModel, TreeForeignKey
|
||||
|
||||
@ -38,30 +38,30 @@ class Item(MPTTModel, SlideMixin):
|
||||
ORGANIZATIONAL_ITEM = 2
|
||||
|
||||
ITEM_TYPE = (
|
||||
(AGENDA_ITEM, _('Agenda item')),
|
||||
(ORGANIZATIONAL_ITEM, _('Organizational item')))
|
||||
(AGENDA_ITEM, ugettext_lazy('Agenda item')),
|
||||
(ORGANIZATIONAL_ITEM, ugettext_lazy('Organizational item')))
|
||||
|
||||
title = models.CharField(null=True, max_length=255, verbose_name=_("Title"))
|
||||
title = models.CharField(null=True, max_length=255, verbose_name=ugettext_lazy("Title"))
|
||||
"""
|
||||
Title of the agenda item.
|
||||
"""
|
||||
|
||||
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
|
||||
text = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Text"))
|
||||
"""
|
||||
The optional text of the agenda item.
|
||||
"""
|
||||
|
||||
comment = models.TextField(null=True, blank=True, verbose_name=_("Comment"))
|
||||
comment = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Comment"))
|
||||
"""
|
||||
Optional comment to the agenda item. Will not be shoun to normal users.
|
||||
"""
|
||||
|
||||
closed = models.BooleanField(default=False, verbose_name=_("Closed"))
|
||||
closed = models.BooleanField(default=False, verbose_name=ugettext_lazy("Closed"))
|
||||
"""
|
||||
Flag, if the item is finished.
|
||||
"""
|
||||
|
||||
weight = models.IntegerField(default=0, verbose_name=_("Weight"))
|
||||
weight = models.IntegerField(default=0, verbose_name=ugettext_lazy("Weight"))
|
||||
"""
|
||||
Weight to sort the item in the agenda.
|
||||
"""
|
||||
@ -73,7 +73,7 @@ class Item(MPTTModel, SlideMixin):
|
||||
"""
|
||||
|
||||
type = models.IntegerField(max_length=1, choices=ITEM_TYPE,
|
||||
default=AGENDA_ITEM, verbose_name=_("Type"))
|
||||
default=AGENDA_ITEM, verbose_name=ugettext_lazy("Type"))
|
||||
"""
|
||||
Type of the agenda item.
|
||||
|
||||
@ -81,7 +81,7 @@ class Item(MPTTModel, SlideMixin):
|
||||
"""
|
||||
|
||||
duration = models.CharField(null=True, blank=True, max_length=5,
|
||||
verbose_name=_("Duration (hh:mm)"))
|
||||
verbose_name=ugettext_lazy("Duration (hh:mm)"))
|
||||
"""
|
||||
The intended duration for the topic.
|
||||
"""
|
||||
@ -94,7 +94,7 @@ class Item(MPTTModel, SlideMixin):
|
||||
"""
|
||||
|
||||
speaker_list_closed = models.BooleanField(
|
||||
default=False, verbose_name=_("List of speakers is closed"))
|
||||
default=False, verbose_name=ugettext_lazy("List of speakers is closed"))
|
||||
"""
|
||||
True, if the list of speakers is closed.
|
||||
"""
|
||||
@ -125,7 +125,7 @@ class Item(MPTTModel, SlideMixin):
|
||||
For use in Template
|
||||
??Why does {% trans item.print_related_type|capfirst %} not work??
|
||||
"""
|
||||
return ugettext(self.get_related_type().capitalize())
|
||||
return _(self.get_related_type().capitalize())
|
||||
|
||||
def get_title(self):
|
||||
"""
|
||||
@ -158,9 +158,12 @@ class Item(MPTTModel, SlideMixin):
|
||||
}
|
||||
elif config['presentation_argument'] == 'show_list_of_speakers':
|
||||
speakers = Speaker.objects.filter(time=None, item=self.pk).order_by('weight')
|
||||
data = {'title': _('List of speakers for %s') % self.get_title(),
|
||||
old_speakers = Speaker.objects.filter(item=self.pk).exclude(time=None).order_by('time')
|
||||
slice_items = max(0, old_speakers.count()-2)
|
||||
data = {'title': self.get_title(),
|
||||
'template': 'projector/agenda_list_of_speaker.html',
|
||||
'speakers': speakers}
|
||||
'speakers': speakers,
|
||||
'old_speakers': old_speakers[slice_items:]}
|
||||
elif self.related_sid:
|
||||
data = self.get_related_slide().slide()
|
||||
else:
|
||||
@ -244,7 +247,7 @@ class Item(MPTTModel, SlideMixin):
|
||||
class SpeakerManager(models.Manager):
|
||||
def add(self, person, item):
|
||||
if self.filter(person=person, item=item, time=None).exists():
|
||||
raise OpenSlidesError(_('%s is already on the list of speakers of item %d.') % (person, item.id))
|
||||
raise OpenSlidesError(_('%(person)s is already on the list of speakers of item %(id)s.') % {'person': person, 'id': item.id})
|
||||
weight = (self.filter(item=item).aggregate(
|
||||
models.Max('weight'))['weight__max'] or 0)
|
||||
return self.create(item=item, person=person, weight=weight + 1)
|
||||
@ -279,7 +282,7 @@ class Speaker(models.Model):
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('can_be_speaker', ugettext_noop('Can be speaker')),
|
||||
('can_be_speaker', ugettext_noop('Can put oneself on the list of speakers')),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.dispatch import receiver
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop, ugettext as _
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from openslides.config.signals import config_signal
|
||||
@ -41,7 +41,7 @@ def setup_agenda_config_page(sender, **kwargs):
|
||||
widget=forms.DateTimeInput(format='%d.%m.%Y %H:%M'),
|
||||
required=False,
|
||||
label=ugettext_lazy('Begin of event'),
|
||||
help_text=_('Input format: DD.MM.YYYY HH:MM')))
|
||||
help_text=ugettext_lazy('Input format: DD.MM.YYYY HH:MM')))
|
||||
|
||||
extra_stylefiles = ['styles/timepicker.css', 'styles/jquery-ui/jquery-ui.custom.min.css']
|
||||
extra_javascript = ['javascript/jquery-ui.custom.min.js',
|
||||
|
@ -10,7 +10,7 @@
|
||||
:license: GNU GPL, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy, ugettext as _
|
||||
|
||||
from openslides.projector.api import register_slidemodel, register_slidefunc
|
||||
|
||||
@ -26,4 +26,4 @@ def agenda_show():
|
||||
return data
|
||||
|
||||
register_slidemodel(Item, control_template='agenda/control_item.html')
|
||||
register_slidefunc('agenda', agenda_show, weight=-1, name=_('Agenda'))
|
||||
register_slidefunc('agenda', agenda_show, weight=-1, name=ugettext_lazy('Agenda'))
|
||||
|
@ -1,23 +1,8 @@
|
||||
{% load i18n %}
|
||||
|
||||
<style type="text/css">
|
||||
#overlay_speaker_inner {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-radius: 0.2em;
|
||||
background-color: #cccccc;
|
||||
opacity: 0.6;
|
||||
padding: 0.2em 0;
|
||||
margin: 1em;
|
||||
z-index:2;
|
||||
padding: 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="overlay_speaker_inner">
|
||||
<div id="overlay_list_of_speaker_box">
|
||||
{% if speakers %}
|
||||
<header>{% trans "List of speakers:" %}</header>
|
||||
<h3>{% trans "List of speakers" %}:</h3>
|
||||
<ol>
|
||||
{% for speaker in speakers %}
|
||||
<li>{{ speaker }}</li>
|
||||
|
@ -2,5 +2,5 @@
|
||||
{% load tags %}
|
||||
|
||||
<div>
|
||||
<a href="{% url 'agenda_current_list_of_speakers' %}">{% trans 'Put me on the current list of speakers' %}</a>
|
||||
<a href="{% url 'agenda_current_list_of_speakers' %}" class="btn">{% trans 'Put me on the current list of speakers' %}</a>
|
||||
</div>
|
||||
|
@ -79,12 +79,14 @@
|
||||
|
||||
{% if old_speakers %}
|
||||
<div class="well">
|
||||
<b>{% trans "Last speakers:" %}</b>
|
||||
<div class="btn-group" data-toggle="buttons-checkbox">
|
||||
<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#all_speakers">
|
||||
{% trans "Show all speakers" %}
|
||||
</button>
|
||||
</div>
|
||||
<b>{% trans "Last speakers" %}:</b>
|
||||
{% if old_speakers|length > 1 %}
|
||||
<div class="btn-group" data-toggle="buttons-checkbox">
|
||||
<button type="button" class="btn btn-mini" data-toggle="collapse" data-target="#all_speakers">
|
||||
{% trans "Show all speakers" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
<br>
|
||||
<div id="all_speakers" class="collapse out">
|
||||
{% for speaker in old_speakers %}
|
||||
@ -139,7 +141,7 @@
|
||||
<span>{{ forloop.counter }}.</span>
|
||||
<a href="{% model_url speaker %}">{{ speaker }}</a>
|
||||
{% if perms.agenda.can_manage_agenda %}
|
||||
<a href="{% url 'agenda_speaker_speak' item.pk speaker.person.person_id %}" class="btn btn-mini"><i class="icon-bell"></i> Finished speech</a>
|
||||
<a href="{% url 'agenda_speaker_speak' item.pk speaker.person.person_id %}" class="btn btn-mini"><i class="icon-bell"></i> {% trans "Next speaker" %}</a>
|
||||
<a href="{% model_url speaker 'delete' %}" title="{% trans 'Delete' %}" class="btn btn-mini">
|
||||
<i class="icon-remove"></i>
|
||||
</a>
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
<ul style="line-height: 180%">
|
||||
<li class="{% if agenda.active %}activeline{% endif %}">
|
||||
<a href="{% url 'projector_activate_slide' agenda.key %}" class="activate_link btn {% if agenda.active %}btn-primary{% endif %} btn-mini" title="{% trans 'Show' %}">
|
||||
<a href="{% url 'projector_activate_slide' agenda.key %}"
|
||||
class="activate_link btn {% if agenda.active %}btn-primary{% endif %} btn-mini"
|
||||
rel="tooltip" data-original-title="{% trans 'Show' %}">
|
||||
<i class="icon-facetime-video {% if agenda.active %}icon-white{% endif %}"></i>
|
||||
</a>
|
||||
<a href="{% url 'projctor_preview_slide' agenda.key %}" title="{% trans 'Preview' %}" class="icon preview right">
|
||||
@ -16,8 +18,10 @@
|
||||
<ul style="line-height: 180%">
|
||||
{% for item in items %}
|
||||
<li class="{% if item.active %}activeline{% endif %}">
|
||||
<a href="{% url 'projector_activate_slide' item.sid %}" class="activate_link btn {% if item.active %}btn-primary{% endif %} btn-mini" title="{% trans 'Show' %}">
|
||||
<i class="icon-facetime-video {% if item.active %}icon-white{% endif %}"></i>
|
||||
<a href="{% url 'projector_activate_slide' item.sid %}"
|
||||
class="activate_link btn {% if item.active and not summary and not speakers %}btn-primary{% endif %} btn-mini"
|
||||
rel="tooltip" data-original-title="{% trans 'Show' %}">
|
||||
<i class="icon-facetime-video {% if item.active and not summary and not speakers %}icon-white{% endif %}"></i>
|
||||
</a>
|
||||
<a href="{% model_url item 'edit' %}" title="{% trans 'Edit' %}" class="btn btn-mini right">
|
||||
<i class="icon-pencil"></i>
|
||||
@ -25,9 +29,16 @@
|
||||
<a href="{% url 'projctor_preview_slide' item.sid %}" title="{% trans 'Preview' %}" class="btn btn-mini right">
|
||||
<i class="icon-search"></i>
|
||||
</a>
|
||||
<a href="{% url 'projector_activate_slide' item.sid 'show_list_of_speakers' %}"
|
||||
class="activate_link btn btn-mini right {% if item.active and speakers %}btn-primary{% endif %}"
|
||||
rel="tooltip" data-original-title="{% trans 'Show list of speakers' %}">
|
||||
<i class="icon icon-bell {% if item.active and speakers %}icon-white{% endif %}"></i>
|
||||
</a>
|
||||
{% if not item.is_leaf_node %}
|
||||
<a class="activate_link btn btn-mini {% if item.active %}btn-primary{% endif %} right" href="{% url 'projector_activate_slide' item.sid 'summary' %}" title="{% trans 'Show summary for this item' %}">
|
||||
<i class="icon-summary {% if item.active %}icon-white{% endif %}"></i>
|
||||
<a href="{% url 'projector_activate_slide' item.sid 'summary' %}"
|
||||
class="activate_link btn btn-mini {% if item.active and summary %}btn-primary{% endif %} right"
|
||||
rel="tooltip" data-original-title="{% trans 'Show summary for this item' %}">
|
||||
<i class="icon-summary {% if item.active and summary %}icon-white{% endif %}"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% for p in item.get_ancestors %}
|
||||
|
@ -4,28 +4,27 @@
|
||||
|
||||
{% block title %}{{ block.super }} - {{ item }}{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
<style type="text/css">
|
||||
#list_of_speakers li
|
||||
{
|
||||
font-size: 130%;
|
||||
line-height: 160%;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ title }}</h1>
|
||||
<h2 style="margin-top: -15px;">{% trans 'List of speakers' %}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block scrollcontent %}
|
||||
{% if old_speakers|length > 0 %}
|
||||
<ul class="list_of_speakers last_speakers">
|
||||
{% for speaker in old_speakers %}
|
||||
<li>{{ speaker }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if speakers %}
|
||||
<ol id="list_of_speakers">
|
||||
<ol class="list_of_speakers">
|
||||
{% for speaker in speakers %}
|
||||
<li>{{ speaker }}</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% else %}
|
||||
{% trans 'The list of speakers is empty' %}
|
||||
<p><i>{% trans 'The list of speakers is empty.' %}</i></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
@ -266,7 +266,7 @@ class SpeakerAppendView(SingleObjectMixin, RedirectView):
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
if self.object.speaker_list_closed:
|
||||
messages.error(request, _('List of speakers is closed.'))
|
||||
messages.error(request, _('The list of speakers is closed.'))
|
||||
else:
|
||||
try:
|
||||
Speaker.objects.add(item=self.object, person=request.user)
|
||||
@ -337,8 +337,10 @@ class SpeakerSpeakView(SingleObjectMixin, RedirectView):
|
||||
item=self.object.pk).exclude(
|
||||
weight=None).get()
|
||||
except Speaker.DoesNotExist:
|
||||
messages.error(self.request, _('Person %s is not on the list of item %s.'
|
||||
% (kwargs['person_id'], self.object)))
|
||||
messages.error(
|
||||
self.request,
|
||||
_('%(person)s is not on the list of %(item)s.')
|
||||
% {'person': kwargs['person_id'], 'item': self.object})
|
||||
else:
|
||||
speaker.speak()
|
||||
|
||||
@ -439,7 +441,7 @@ class CurrentListOfSpeakersView(RedirectView):
|
||||
if item is None:
|
||||
messages.error(request, _(
|
||||
'There is no list of speakers for the current slide. '
|
||||
'Please choose your agenda item manually from the agenda.'))
|
||||
'Please choose the agenda item manually from the agenda.'))
|
||||
return reverse('dashboard')
|
||||
|
||||
if self.request.user.has_perm('agenda.can_be_speaker'):
|
||||
@ -483,7 +485,9 @@ def get_widgets(request):
|
||||
template='agenda/widget.html',
|
||||
context={
|
||||
'agenda': SLIDE['agenda'],
|
||||
'items': Item.objects.all()},
|
||||
'items': Item.objects.all(),
|
||||
'summary': config['presentation_argument'] == 'summary',
|
||||
'speakers': config['presentation_argument'] == 'show_list_of_speakers'},
|
||||
permission_required='projector.can_manage_projector'),
|
||||
|
||||
Widget(
|
||||
|
@ -11,7 +11,7 @@
|
||||
"""
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy
|
||||
|
||||
from openslides.utils.forms import CssClassMixin
|
||||
from openslides.utils.person import PersonFormField
|
||||
@ -21,7 +21,7 @@ from openslides.assignment.models import Assignment
|
||||
|
||||
class AssignmentForm(forms.ModelForm, CssClassMixin):
|
||||
posts = forms.IntegerField(
|
||||
min_value=1, initial=1, label=_("Number of available posts"))
|
||||
min_value=1, initial=1, label=ugettext_lazy("Number of available posts"))
|
||||
|
||||
class Meta:
|
||||
model = Assignment
|
||||
@ -31,5 +31,5 @@ class AssignmentForm(forms.ModelForm, CssClassMixin):
|
||||
class AssignmentRunForm(forms.Form, CssClassMixin):
|
||||
candidate = PersonFormField(
|
||||
widget=forms.Select(attrs={'class': 'medium-input'}),
|
||||
label=_("Nominate a participant"),
|
||||
label=ugettext_lazy("Nominate a participant"),
|
||||
)
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext_noop # TODO Change this in the code
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.utils.person import PersonField
|
||||
from openslides.config.api import config
|
||||
@ -39,17 +39,17 @@ class AssignmentCandidate(models.Model):
|
||||
class Assignment(models.Model, SlideMixin):
|
||||
prefix = 'assignment'
|
||||
STATUS = (
|
||||
('sea', _('Searching for candidates')),
|
||||
('vot', _('Voting')),
|
||||
('fin', _('Finished')),
|
||||
('sea', ugettext_lazy('Searching for candidates')),
|
||||
('vot', ugettext_lazy('Voting')),
|
||||
('fin', ugettext_lazy('Finished')),
|
||||
)
|
||||
|
||||
name = models.CharField(max_length=100, verbose_name=_("Name"))
|
||||
description = models.TextField(null=True, blank=True, verbose_name=_("Description"))
|
||||
posts = models.PositiveSmallIntegerField(verbose_name=_("Number of available posts"))
|
||||
name = models.CharField(max_length=100, verbose_name=ugettext_lazy("Name"))
|
||||
description = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Description"))
|
||||
posts = models.PositiveSmallIntegerField(verbose_name=ugettext_lazy("Number of available posts"))
|
||||
polldescription = models.CharField(
|
||||
max_length=100, null=True, blank=True,
|
||||
verbose_name=_("Comment on the ballot paper"))
|
||||
verbose_name=ugettext_lazy("Comment on the ballot paper"))
|
||||
status = models.CharField(max_length=3, choices=STATUS, default='sea')
|
||||
|
||||
def set_status(self, status):
|
||||
@ -240,9 +240,8 @@ class Assignment(models.Model, SlideMixin):
|
||||
class Meta:
|
||||
permissions = (
|
||||
('can_see_assignment', ugettext_noop("Can see assignment")),
|
||||
('can_nominate_other',
|
||||
ugettext_noop("Can nominate another person")),
|
||||
('can_nominate_self', ugettext_noop("Can nominate themselves")),
|
||||
('can_nominate_other', ugettext_noop("Can nominate another person")),
|
||||
('can_nominate_self', ugettext_noop("Can nominate oneself")),
|
||||
('can_manage_assignment', ugettext_noop("Can manage assignment")),
|
||||
)
|
||||
ordering = ('name',)
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.dispatch import receiver
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop, ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.config.signals import config_signal
|
||||
from openslides.config.api import ConfigVariable, ConfigPage
|
||||
@ -28,19 +28,19 @@ def setup_assignment_config_page(sender, **kwargs):
|
||||
default_value=False,
|
||||
form_field=forms.BooleanField(
|
||||
required=False,
|
||||
label=_('Only publish voting results for selected winners '
|
||||
'(Projector view only)')))
|
||||
label=ugettext_lazy('Only publish voting results for selected '
|
||||
'winners (Projector view only)')))
|
||||
assignment_pdf_ballot_papers_selection = ConfigVariable(
|
||||
name='assignment_pdf_ballot_papers_selection',
|
||||
default_value='CUSTOM_NUMBER',
|
||||
form_field=forms.ChoiceField(
|
||||
widget=forms.Select(),
|
||||
required=False,
|
||||
label=_('Number of ballot papers (selection)'),
|
||||
label=ugettext_lazy('Number of ballot papers (selection)'),
|
||||
choices=(
|
||||
('NUMBER_OF_DELEGATES', _('Number of all delegates')),
|
||||
('NUMBER_OF_ALL_PARTICIPANTS', _('Number of all participants')),
|
||||
('CUSTOM_NUMBER', _('Use the following custom number')))))
|
||||
('NUMBER_OF_DELEGATES', ugettext_lazy('Number of all delegates')),
|
||||
('NUMBER_OF_ALL_PARTICIPANTS', ugettext_lazy('Number of all participants')),
|
||||
('CUSTOM_NUMBER', ugettext_lazy('Use the following custom number')))))
|
||||
assignment_pdf_ballot_papers_number = ConfigVariable(
|
||||
name='assignment_pdf_ballot_papers_number',
|
||||
default_value=8,
|
||||
@ -48,32 +48,32 @@ def setup_assignment_config_page(sender, **kwargs):
|
||||
widget=forms.TextInput(attrs={'class': 'small-input'}),
|
||||
required=False,
|
||||
min_value=1,
|
||||
label=_('Custom number of ballot papers')))
|
||||
label=ugettext_lazy('Custom number of ballot papers')))
|
||||
assignment_pdf_title = ConfigVariable(
|
||||
name='assignment_pdf_title',
|
||||
default_value=_('Elections'),
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
label=_('Title for PDF document (all elections)')))
|
||||
label=ugettext_lazy('Title for PDF document (all elections)')))
|
||||
assignment_pdf_preamble = ConfigVariable(
|
||||
name='assignment_pdf_preamble',
|
||||
default_value='',
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
required=False,
|
||||
label=_('Preamble text for PDF document (all elections)')))
|
||||
label=ugettext_lazy('Preamble text for PDF document (all elections)')))
|
||||
assignment_poll_vote_values = ConfigVariable(
|
||||
name='assignment_poll_vote_values',
|
||||
default_value='auto',
|
||||
form_field=forms.ChoiceField(
|
||||
widget=forms.Select(),
|
||||
required=False,
|
||||
label=_('Election method'),
|
||||
label=ugettext_lazy('Election method'),
|
||||
choices=(
|
||||
('auto', _('Automatic assign of method.')),
|
||||
('votes', _('Always one option per candidate.')),
|
||||
('yesnoabstain', _('Always Yes-No-Abstain per candidate.')))))
|
||||
('auto', ugettext_lazy('Automatic assign of method')),
|
||||
('votes', ugettext_lazy('Always one option per candidate')),
|
||||
('yesnoabstain', ugettext_lazy('Always Yes-No-Abstain per candidate')))))
|
||||
|
||||
return ConfigPage(title=ugettext_noop('Elections'),
|
||||
url='assignment',
|
||||
|
@ -31,7 +31,7 @@ from openslides.utils.utils import (
|
||||
from openslides.utils.views import FormView, DeleteView, PDFView, RedirectView
|
||||
from openslides.utils.person import get_person
|
||||
from openslides.config.api import config
|
||||
from openslides.participant.models import User
|
||||
from openslides.participant.models import User, Group
|
||||
from openslides.projector.projector import Widget
|
||||
from openslides.poll.views import PollFormView
|
||||
from openslides.agenda.models import Item
|
||||
@ -564,7 +564,12 @@ class AssignmentPollPDF(PDFView):
|
||||
|
||||
# set number of ballot papers
|
||||
if ballot_papers_selection == "NUMBER_OF_DELEGATES":
|
||||
number = User.objects.filter(type__iexact="delegate").count()
|
||||
try:
|
||||
if Group.objects.get(pk=3):
|
||||
number = User.objects.filter(groups__pk=3).count()
|
||||
except Group.DoesNotExist:
|
||||
number = 0
|
||||
|
||||
elif ballot_papers_selection == "NUMBER_OF_ALL_PARTICIPANTS":
|
||||
number = int(User.objects.count())
|
||||
else: # ballot_papers_selection == "CUSTOM_NUMBER"
|
||||
|
@ -1,7 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block content %}
|
||||
@ -12,7 +11,7 @@
|
||||
<div class="btn-toolbar">
|
||||
<div class="btn-group">
|
||||
{% for config_page_dict in config_pages_list %}
|
||||
<a href="/config/{{ config_page_dict.config_page.url }}/" class="btn btn-mini {% if config_page_dict.active %}active{% endif %}">{{ config_page_dict.config_page.title }}</a>
|
||||
<a href="/config/{{ config_page_dict.config_page.url }}/" class="btn btn-mini {% if config_page_dict.active %}active{% endif %}">{% trans config_page_dict.config_page.title %}</a>
|
||||
{% endfor %}
|
||||
<a href="{% url 'core_version' %}" class="btn btn-mini">{% trans 'Version' %}</a>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
from django import forms
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib import messages
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
from openslides.utils.views import FormView
|
||||
from openslides.utils.template import Tab
|
||||
@ -115,7 +115,7 @@ class ConfigView(FormView):
|
||||
"""
|
||||
for key in form.cleaned_data:
|
||||
config[key] = form.cleaned_data[key]
|
||||
messages.success(self.request, _('%s settings successfully saved.' % self.config_page.title))
|
||||
messages.success(self.request, _('%s settings successfully saved.') % _(self.config_page.title))
|
||||
return super(ConfigView, self).form_valid(form)
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.dispatch import Signal, receiver
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop, ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.config.signals import config_signal
|
||||
from openslides.config.api import ConfigVariable, ConfigGroup, ConfigGroupedPage
|
||||
|
@ -5,7 +5,20 @@
|
||||
{% block title %}{{ block.super }} – {% trans 'Version' %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% trans 'Versions' %}</h1>
|
||||
<h1>
|
||||
{% trans 'Version' %}
|
||||
<small>{% trans active_config_page.title %}</small>
|
||||
<small class="pull-right">
|
||||
<div class="btn-toolbar">
|
||||
<div class="btn-group">
|
||||
{% for config_page_dict in config_pages_list %}
|
||||
<a href="/config/{{ config_page_dict.config_page.url }}/" class="btn btn-mini">{% trans config_page_dict.config_page.title %}</a>
|
||||
{% endfor %}
|
||||
<a href="{% url 'core_version' %}" class="btn btn-mini active">{% trans 'Version' %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</small>
|
||||
</h1>
|
||||
{% for version in versions %}
|
||||
<p>{{ version.0 }} {% trans "Version" %}: {{ version.1 }}</p>
|
||||
{% endfor %}
|
||||
|
@ -15,6 +15,7 @@ from django.utils.importlib import import_module
|
||||
|
||||
from openslides import get_version, get_git_commit_id, RELEASE
|
||||
from openslides.utils.views import TemplateView
|
||||
from .signals import config_signal
|
||||
|
||||
|
||||
class VersionView(TemplateView):
|
||||
@ -35,6 +36,13 @@ class VersionView(TemplateView):
|
||||
openslides_version_string += ' Commit: %s' % get_git_commit_id()
|
||||
context['versions'] = [('OpenSlides', openslides_version_string)]
|
||||
|
||||
# collect other config pages
|
||||
config_pages_list = []
|
||||
for receiver, config_page in config_signal.send(sender=self):
|
||||
if config_page.is_shown():
|
||||
config_pages_list.append({'config_page': config_page})
|
||||
context['config_pages_list'] = sorted(config_pages_list, key=lambda config_page_dict: config_page_dict['config_page'].weight)
|
||||
|
||||
# Versions of plugins.
|
||||
for plugin in settings.INSTALLED_PLUGINS:
|
||||
try:
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,21 +1,210 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
# German translations for JavaScript file in OpenSlides package.
|
||||
# Copyright (C) 2011-2013 by OpenSlides team, see AUTHORS.
|
||||
# This file is distributed under the same license as the OpenSlides package.
|
||||
# Emanuel Schütze <emanuel@intevation.de>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenSlides 1.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-03-12 21:29+0100\n"
|
||||
"POT-Creation-Date: 2013-04-23 16:17+0200\n"
|
||||
"PO-Revision-Date: 2012-07-28 11:07+0200\n"
|
||||
"Last-Translator: Oskar Hahn <mail@oshahn.de>\n"
|
||||
"Last-Translator: Emanuel Schütze <emanuel@intevation.de>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:9
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:39
|
||||
msgid "en"
|
||||
msgstr "en"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:10
|
||||
msgid "previous month"
|
||||
msgstr "vorheriger Monat"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:11
|
||||
msgid "next month"
|
||||
msgstr "nächster Monat"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:13
|
||||
msgid "January"
|
||||
msgstr "Januar"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:13
|
||||
msgid "February"
|
||||
msgstr "Februar"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:13
|
||||
msgid "March"
|
||||
msgstr "März"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:14
|
||||
msgid "April"
|
||||
msgstr "April"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:14
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:20
|
||||
msgid "May"
|
||||
msgstr "Mai"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:14
|
||||
msgid "June"
|
||||
msgstr "Juni"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:15
|
||||
msgid "July"
|
||||
msgstr "Juli"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:15
|
||||
msgid "August"
|
||||
msgstr "August"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:15
|
||||
msgid "September"
|
||||
msgstr "September"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:16
|
||||
msgid "October"
|
||||
msgstr "Oktober"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:16
|
||||
msgid "November"
|
||||
msgstr "November"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:16
|
||||
msgid "December"
|
||||
msgstr "Dezember"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:19
|
||||
msgid "Jan"
|
||||
msgstr "Jan"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:19
|
||||
msgid "Feb"
|
||||
msgstr "Feb"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:19
|
||||
msgid "Mar"
|
||||
msgstr "Mär"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:20
|
||||
msgid "Apr"
|
||||
msgstr "Apr"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:20
|
||||
msgid "Jun"
|
||||
msgstr "Jun"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:21
|
||||
msgid "Jul"
|
||||
msgstr "Jul"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:21
|
||||
msgid "Aug"
|
||||
msgstr "Aug"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:21
|
||||
msgid "Sep"
|
||||
msgstr "Sep"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:22
|
||||
msgid "Oct"
|
||||
msgstr "Okt"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:22
|
||||
msgid "Nov"
|
||||
msgstr "Nov"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:22
|
||||
msgid "Dec"
|
||||
msgstr "Dez"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:25
|
||||
msgid "Sunday"
|
||||
msgstr "Sonntag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:25
|
||||
msgid "Monday"
|
||||
msgstr "Montag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:25
|
||||
msgid "Tuesdey"
|
||||
msgstr "Dienstag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:25
|
||||
msgid "Wednesday"
|
||||
msgstr "Mittwoch"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:26
|
||||
msgid "Thursday"
|
||||
msgstr "Donnerstag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:26
|
||||
msgid "Friday"
|
||||
msgstr "Freitag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:26
|
||||
msgid "Saturday"
|
||||
msgstr "Samstag"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:29
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:33
|
||||
msgid "Su"
|
||||
msgstr "So"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:29
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:33
|
||||
msgid "Mo"
|
||||
msgstr "Mo"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:29
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:33
|
||||
msgid "Tu"
|
||||
msgstr "Di"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:29
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:33
|
||||
msgid "We"
|
||||
msgstr "Mi"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:30
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:34
|
||||
msgid "Th"
|
||||
msgstr "Do"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:30
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:34
|
||||
msgid "Fr"
|
||||
msgstr "Fr"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:30
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:34
|
||||
msgid "Sa"
|
||||
msgstr "Sa"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:45
|
||||
msgid "Time"
|
||||
msgstr "Zeit"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:46
|
||||
msgid "Hour"
|
||||
msgstr "Stunde"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:47
|
||||
msgid "Minute"
|
||||
msgstr "Minute"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:48
|
||||
msgid "Current time"
|
||||
msgstr "Aktuelle Zeit"
|
||||
|
||||
#: agenda/static/javascript/agenda-config-datepicker.js:49
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: agenda/static/javascript/agenda.js:27
|
||||
#, c-format
|
||||
msgid ", of which %s are hidden."
|
||||
|
@ -13,7 +13,7 @@
|
||||
import mimetypes
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_noop
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.utils.person.models import PersonField
|
||||
|
||||
@ -23,16 +23,16 @@ class Mediafile(models.Model):
|
||||
Class for uploaded files which can be delivered under a certain url.
|
||||
"""
|
||||
|
||||
mediafile = models.FileField(upload_to='file')
|
||||
mediafile = models.FileField(upload_to='file', verbose_name=ugettext_lazy("File"))
|
||||
"""
|
||||
See https://docs.djangoproject.com/en/dev/ref/models/fields/#filefield
|
||||
for more information.
|
||||
"""
|
||||
|
||||
title = models.CharField(max_length=255, unique=True)
|
||||
title = models.CharField(max_length=255, unique=True, verbose_name=ugettext_lazy("Title"))
|
||||
"""A string representing the title of the file."""
|
||||
|
||||
uploader = PersonField(blank=True)
|
||||
uploader = PersonField(blank=True, verbose_name=ugettext_lazy("Uploaded by"))
|
||||
"""A person – the uploader of a file."""
|
||||
|
||||
timestamp = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -8,5 +8,9 @@
|
||||
/** Navigation icons (mapping to glyphicons-halflings) **/
|
||||
|
||||
.icon-mediafile {
|
||||
background-position: -96px -24px;
|
||||
background-image: url("../img/glyphicons_062_paperclip.png");
|
||||
background-position: 0;
|
||||
}
|
||||
.leftmenu ul li.active a span.ico i.icon-mediafile {
|
||||
background-image: url("../img/glyphicons_062_paperclip_white.png");
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<th>{% trans 'Type' %}</th>
|
||||
<th>{% trans 'Size' %}</th>
|
||||
<th>{% trans 'Upload time' %}</th>
|
||||
<th>{% trans 'Uploader' %}</th>
|
||||
<th>{% trans 'Uploaded by' %}</th>
|
||||
{% if perms.mediafile.can_manage %}
|
||||
<th class="mini_width">{% trans "Actions" %}</th>
|
||||
{% endif %}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"""
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
|
||||
from openslides.utils.forms import CssClassMixin
|
||||
from openslides.utils.forms import CleanHtmlFormMixin
|
||||
@ -30,18 +30,18 @@ class BaseMotionForm(CleanHtmlFormMixin, CssClassMixin, forms.ModelForm):
|
||||
"""
|
||||
clean_html_fields = ('text', 'reason')
|
||||
|
||||
title = forms.CharField(widget=forms.TextInput(), label=_("Title"))
|
||||
title = forms.CharField(widget=forms.TextInput(), label=ugettext_lazy("Title"))
|
||||
"""
|
||||
Title of the motion. Will be saved in a MotionVersion object.
|
||||
"""
|
||||
|
||||
text = forms.CharField(widget=forms.Textarea(), label=_("Text"))
|
||||
text = forms.CharField(widget=forms.Textarea(), label=ugettext_lazy("Text"))
|
||||
"""
|
||||
Text of the motion. Will be saved in a MotionVersion object.
|
||||
"""
|
||||
|
||||
reason = forms.CharField(
|
||||
widget=forms.Textarea(), required=False, label=_("Reason"))
|
||||
widget=forms.Textarea(), required=False, label=ugettext_lazy("Reason"))
|
||||
"""
|
||||
Reason of the motion. will be saved in a MotionVersion object.
|
||||
"""
|
||||
@ -64,7 +64,7 @@ class BaseMotionForm(CleanHtmlFormMixin, CssClassMixin, forms.ModelForm):
|
||||
class MotionSubmitterMixin(forms.ModelForm):
|
||||
"""Mixin to append the submitter field to a MotionForm."""
|
||||
|
||||
submitter = MultiplePersonFormField(label=_("Submitter"))
|
||||
submitter = MultiplePersonFormField(label=ugettext_lazy("Submitter"))
|
||||
"""Submitter of the motion. Can be one or more persons."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -78,7 +78,7 @@ class MotionSubmitterMixin(forms.ModelForm):
|
||||
class MotionSupporterMixin(forms.ModelForm):
|
||||
"""Mixin to append the supporter field to a Motionform."""
|
||||
|
||||
supporter = MultiplePersonFormField(required=False, label=_("Supporters"))
|
||||
supporter = MultiplePersonFormField(required=False, label=ugettext_lazy("Supporters"))
|
||||
"""Supporter of the motion. Can be one or more persons."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -93,8 +93,8 @@ class MotionDisableVersioningMixin(forms.ModelForm):
|
||||
"""Mixin to add the option to the form to choose to disable versioning."""
|
||||
|
||||
disable_versioning = forms.BooleanField(
|
||||
required=False, label=_("Don't create a new version"),
|
||||
help_text=_("Don't create a new version. Useful e. g. for trivial changes."))
|
||||
required=False, label=ugettext_lazy("Don't create a new version"),
|
||||
help_text=ugettext_lazy("Don't create a new version. Useful e.g. for trivial changes."))
|
||||
"""BooleanField to decide, if a new version will be created, or the
|
||||
last_version will be used."""
|
||||
|
||||
@ -102,10 +102,10 @@ class MotionDisableVersioningMixin(forms.ModelForm):
|
||||
class MotionCategoryMixin(forms.ModelForm):
|
||||
"""Mixin to let the user choose the category for the motion."""
|
||||
|
||||
category = forms.ModelChoiceField(queryset=Category.objects.all(), required=False)
|
||||
category = forms.ModelChoiceField(queryset=Category.objects.all(), required=False, label=ugettext_lazy("Category"))
|
||||
|
||||
|
||||
class MotionIdentifierMixin(forms.ModelForm):
|
||||
"""Mixin to let the user choose the identifier for the motion."""
|
||||
|
||||
identifier = forms.CharField(required=False)
|
||||
identifier = forms.CharField(required=False, label=ugettext_lazy("Identifier"))
|
||||
|
@ -21,7 +21,7 @@ from django.db.models import Max
|
||||
from django.dispatch import receiver
|
||||
from django.utils import formats
|
||||
from django.utils.translation import pgettext
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop, ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.utils.person import PersonField
|
||||
from openslides.config.api import config
|
||||
@ -565,7 +565,7 @@ class MotionVersion(models.Model):
|
||||
title = models.CharField(max_length=255, verbose_name=ugettext_lazy("Title"))
|
||||
"""The title of a motion."""
|
||||
|
||||
text = models.TextField(verbose_name=_("Text"))
|
||||
text = models.TextField(verbose_name=ugettext_lazy("Text"))
|
||||
"""The text of a motion."""
|
||||
|
||||
reason = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Reason"))
|
||||
@ -585,7 +585,7 @@ class MotionVersion(models.Model):
|
||||
|
||||
def __unicode__(self):
|
||||
"""Return a string, representing this object."""
|
||||
counter = self.version_number or _('new')
|
||||
counter = self.version_number or ugettext_lazy('new')
|
||||
return "%s Version %s" % (self.motion, counter) # TODO: Should this really be self.motion or the title of the specific version?
|
||||
|
||||
def get_absolute_url(self, link='detail'):
|
||||
|
@ -167,7 +167,7 @@ def motion_to_pdf(pdf, motion):
|
||||
|
||||
# motion reason
|
||||
if motion.reason:
|
||||
pdf.append(Paragraph(_("Reason:"), stylesheet['Heading3']))
|
||||
pdf.append(Paragraph(_("Reason")+":", stylesheet['Heading3']))
|
||||
convert_html_to_reportlab(pdf, motion.reason)
|
||||
return pdf
|
||||
|
||||
|
@ -30,36 +30,36 @@ def setup_motion_config_page(sender, **kwargs):
|
||||
name='motion_stop_submitting',
|
||||
default_value=False,
|
||||
form_field=forms.BooleanField(
|
||||
label=_('Stop submitting new motions by non-staff users'),
|
||||
label=ugettext_lazy('Stop submitting new motions by non-staff users'),
|
||||
required=False))
|
||||
motion_min_supporters = ConfigVariable(
|
||||
name='motion_min_supporters',
|
||||
default_value=0,
|
||||
form_field=forms.IntegerField(
|
||||
widget=forms.TextInput(attrs={'class': 'small-input'}),
|
||||
label=_('Number of (minimum) required supporters for a motion'),
|
||||
label=ugettext_lazy('Number of (minimum) required supporters for a motion'),
|
||||
initial=4,
|
||||
min_value=0,
|
||||
max_value=8,
|
||||
help_text=_('Choose 0 to disable the supporting system')))
|
||||
help_text=ugettext_lazy('Choose 0 to disable the supporting system')))
|
||||
motion_preamble = ConfigVariable(
|
||||
name='motion_preamble',
|
||||
default_value=_('The assembly may decide,'),
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
label=_('Motion preamble')))
|
||||
label=ugettext_lazy('Motion preamble')))
|
||||
motion_pdf_ballot_papers_selection = ConfigVariable(
|
||||
name='motion_pdf_ballot_papers_selection',
|
||||
default_value='CUSTOM_NUMBER',
|
||||
form_field=forms.ChoiceField(
|
||||
widget=forms.Select(),
|
||||
required=False,
|
||||
label=_('Number of ballot papers (selection)'),
|
||||
label=ugettext_lazy('Number of ballot papers (selection)'),
|
||||
choices=[
|
||||
('NUMBER_OF_DELEGATES', _('Number of all delegates')),
|
||||
('NUMBER_OF_ALL_PARTICIPANTS', _('Number of all participants')),
|
||||
('CUSTOM_NUMBER', _("Use the following custom number"))]))
|
||||
('NUMBER_OF_DELEGATES', ugettext_lazy('Number of all delegates')),
|
||||
('NUMBER_OF_ALL_PARTICIPANTS', ugettext_lazy('Number of all participants')),
|
||||
('CUSTOM_NUMBER', ugettext_lazy("Use the following custom number"))]))
|
||||
motion_pdf_ballot_papers_number = ConfigVariable(
|
||||
name='motion_pdf_ballot_papers_number',
|
||||
default_value=8,
|
||||
@ -67,46 +67,46 @@ def setup_motion_config_page(sender, **kwargs):
|
||||
widget=forms.TextInput(attrs={'class': 'small-input'}),
|
||||
required=False,
|
||||
min_value=1,
|
||||
label=_('Custom number of ballot papers')))
|
||||
label=ugettext_lazy('Custom number of ballot papers')))
|
||||
motion_pdf_title = ConfigVariable(
|
||||
name='motion_pdf_title',
|
||||
default_value=_('Motions'),
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
label=_('Title for PDF document (all motions)')))
|
||||
label=ugettext_lazy('Title for PDF document (all motions)')))
|
||||
motion_pdf_preamble = ConfigVariable(
|
||||
name='motion_pdf_preamble',
|
||||
default_value='',
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
required=False,
|
||||
label=_('Preamble text for PDF document (all motions)')))
|
||||
label=ugettext_lazy('Preamble text for PDF document (all motions)')))
|
||||
motion_allow_disable_versioning = ConfigVariable(
|
||||
name='motion_allow_disable_versioning',
|
||||
default_value=False,
|
||||
form_field=forms.BooleanField(
|
||||
label=_('Allow to disable versioning'),
|
||||
label=ugettext_lazy('Allow to disable versioning'),
|
||||
required=False))
|
||||
motion_workflow = ConfigVariable(
|
||||
name='motion_workflow',
|
||||
default_value=1,
|
||||
form_field=forms.ChoiceField(
|
||||
widget=forms.Select(),
|
||||
label=_('Workflow of new motions'),
|
||||
label=ugettext_lazy('Workflow of new motions'),
|
||||
required=True,
|
||||
choices=[(workflow.pk, workflow.name) for workflow in Workflow.objects.all()]))
|
||||
choices=[(workflow.pk, ugettext_lazy(workflow.name)) for workflow in Workflow.objects.all()]))
|
||||
motion_identifier = ConfigVariable(
|
||||
name='motion_identifier',
|
||||
default_value='manually',
|
||||
form_field=forms.ChoiceField(
|
||||
widget=forms.Select(),
|
||||
required=False,
|
||||
label=_('Identifier'),
|
||||
label=ugettext_lazy('Identifier'),
|
||||
choices=[
|
||||
('manually', _('Set it manually')),
|
||||
('per_category', _('Numbered per category')),
|
||||
('serially_numbered', _('Serially numbered'))]))
|
||||
('manually', ugettext_lazy('Set it manually')),
|
||||
('per_category', ugettext_lazy('Numbered per category')),
|
||||
('serially_numbered', ugettext_lazy('Serially numbered'))]))
|
||||
|
||||
return ConfigPage(title=ugettext_noop('Motion'),
|
||||
url='motion',
|
||||
|
@ -10,7 +10,7 @@
|
||||
{% trans "Categories" %}
|
||||
<small class="pull-right">
|
||||
{% if perms.motion.can_manage_motion %}
|
||||
<a href="{% url 'motion_category_create' %}" class="btn btn-mini btn-primary" rel="tooltip" data-original-title="{% trans 'New motion' %}"><i class="icon-plus icon-white"></i> {% trans 'New' %}</a>
|
||||
<a href="{% url 'motion_category_create' %}" class="btn btn-mini btn-primary" rel="tooltip" data-original-title="{% trans 'New category' %}"><i class="icon-plus icon-white"></i> {% trans 'New' %}</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'motion_list' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
|
||||
</small>
|
||||
|
@ -126,11 +126,11 @@
|
||||
<input type="radio" value="{{ version.version_number }}" name="rev2">
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% model_url version %}" title="{% trans 'Show version number' %} {{ version.version_number }}" class="btn btn-mini">
|
||||
<a href="{% model_url version %}" title="{% trans 'Show' %}" class="btn btn-mini">
|
||||
<i class="icon-search"></i>
|
||||
</a>
|
||||
{# TODO: add delete version function #}
|
||||
<a href="{% model_url version 'delete' %}" title="{% trans 'Delete version number' %} {{ version.version_number }}" class="btn btn-mini">
|
||||
<a href="{% model_url version 'delete' %}" title="{% trans 'Delete' %}" class="btn btn-mini">
|
||||
<i class="icon-remove"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
@ -34,11 +34,11 @@
|
||||
<table class="table table-striped table-bordered">
|
||||
<tr>
|
||||
<td><b>{% trans "Version" %} {{ version_rev1.version_number }}</b><br>
|
||||
{% trans "created: " %} {{ version_rev1.creation_time }}<br>
|
||||
{% trans "created" %}: {{ version_rev1.creation_time }}<br>
|
||||
<h4>{{ version_rev1.title }}</h4>
|
||||
</td>
|
||||
<td><b>{% trans "Version" %} {{ version_rev2.version_number }}</b><br>
|
||||
{% trans "created: " %} {{ version_rev1.creation_time }}<br>
|
||||
{% trans "created" %}: {{ version_rev1.creation_time }}<br>
|
||||
<h4>{{ version_rev2.title }}</h4>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -31,7 +31,11 @@
|
||||
{% trans "New motion" %}
|
||||
{% endif %}
|
||||
<small class="pull-right">
|
||||
<a href="{% url 'motion_list' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
|
||||
{% if motion %}
|
||||
<a href="{% model_url motion 'view' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to motion" %}</a>
|
||||
{% else %}
|
||||
<a href="{% url 'motion_list' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
|
||||
{% endif %}
|
||||
</small>
|
||||
</h1>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if perms.motion.can_manage_motion %}
|
||||
<a href="{% url 'motion_category_list' %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'New motion' %}"><i class="icon-th-large"></i> {% trans 'Category' %}</a>
|
||||
<a href="{% url 'motion_category_list' %}" class="btn btn-mini"><i class="icon-th-large"></i> {% trans 'Categories' %}</a>
|
||||
{# <a href="{% url 'motion_import' %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Import motions' %}"><i class="icon-import"></i> {% trans 'Import' %}</a>#}
|
||||
{% endif %}
|
||||
<a href="{% url 'motion_list_pdf' %}" class="btn btn-mini" rel="tooltip" data-original-title="{% trans 'Print all motions as PDF' %}"><i class="icon-print"></i> PDF</a>
|
||||
|
@ -291,7 +291,7 @@ class VersionDiffView(DetailView):
|
||||
diff_text = htmldiff(version_rev1.text, version_rev2.text)
|
||||
diff_reason = htmldiff(version_rev1.reason, version_rev2.reason)
|
||||
except (KeyError, ValueError, MotionVersion.DoesNotExist):
|
||||
messages.error(self.request, _('At least one version number was not valid.'))
|
||||
messages.error(self.request, _('At least one version number is not valid.'))
|
||||
version_rev1 = None
|
||||
version_rev2 = None
|
||||
diff_text = None
|
||||
@ -556,7 +556,7 @@ class MotionSetStateView(SingleObjectMixin, RedirectView):
|
||||
else:
|
||||
self.object.save()
|
||||
# TODO: the state is not translated
|
||||
self.object.write_log(ugettext_noop('Changed state to %s') %
|
||||
self.object.write_log(ugettext_noop('State changed to %s') %
|
||||
self.object.state.name, self.request.user)
|
||||
messages.success(request, _('Motion status was set to: %s.'
|
||||
% html_strong(self.object.state)))
|
||||
@ -583,7 +583,7 @@ class CreateAgendaItemView(SingleObjectMixin, RedirectView):
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
"""Create the agenda item."""
|
||||
self.item = Item.objects.create(related_sid=self.object.sid)
|
||||
self.object.write_log(ugettext_noop('Created Agenda Item'), self.request.user)
|
||||
self.object.write_log(ugettext_noop('Agenda item created'), self.request.user)
|
||||
|
||||
create_agenda_item = CreateAgendaItemView.as_view()
|
||||
|
||||
@ -595,7 +595,7 @@ class MotionPDFView(SingleObjectMixin, PDFView):
|
||||
|
||||
If self.print_all_motions is False, the view returns a PDF with only one
|
||||
motion."""
|
||||
permission_required = 'motion.can_manage_motion'
|
||||
permission_required = 'motion.can_see_motion'
|
||||
model = Motion
|
||||
top_space = 0
|
||||
print_all_motions = False
|
||||
|
@ -97,7 +97,7 @@ def import_users(csv_file):
|
||||
error_messages.append(_('Ignoring malformed group id in line %d.') % (line_no + 1))
|
||||
continue
|
||||
except Group.DoesNotExist:
|
||||
error_messages.append(_('Group id %s does not exists (line %d).') % (groupid, line_no + 1))
|
||||
error_messages.append(_('Group id %(id)s does not exists (line %(line)d).') % {'id': groupid, 'line': line_no + 1})
|
||||
continue
|
||||
user.reset_password()
|
||||
count_success += 1
|
||||
|
@ -117,11 +117,11 @@ class GroupForm(forms.ModelForm, CssClassMixin):
|
||||
# Editing the anonymous-user
|
||||
if self.instance.name.lower() != data.lower():
|
||||
raise forms.ValidationError(
|
||||
ugettext_lazy('You can not edit the name for this group.'))
|
||||
_('You can not edit the name for this group.'))
|
||||
else:
|
||||
if data.lower() in ['anonymous', 'registered']:
|
||||
raise forms.ValidationError(
|
||||
ugettext_lazy('Group name "%s" is reserved for internal use.') % data)
|
||||
_('Group name "%s" is reserved for internal use.') % data)
|
||||
return data
|
||||
|
||||
class Meta:
|
||||
|
@ -14,7 +14,7 @@ from django.contrib.auth.models import User as DjangoUser, Group as DjangoGroup
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext_noop # TODO: Change this in the code
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.utils.person import PersonMixin, Person
|
||||
from openslides.utils.person.signals import receive_persons
|
||||
@ -27,32 +27,32 @@ class User(PersonMixin, Person, SlideMixin, DjangoUser):
|
||||
prefix = 'user' # This is for the slides
|
||||
person_prefix = 'user'
|
||||
GENDER_CHOICES = (
|
||||
('male', _('Male')),
|
||||
('female', _('Female')),
|
||||
('male', ugettext_lazy('Male')),
|
||||
('female', ugettext_lazy('Female')),
|
||||
)
|
||||
|
||||
django_user = models.OneToOneField(DjangoUser, editable=False, parent_link=True)
|
||||
structure_level = models.CharField(
|
||||
max_length=255, blank=True, default='', verbose_name=_("Structure level"),
|
||||
help_text=_('Will be shown after the name.'))
|
||||
max_length=255, blank=True, default='', verbose_name=ugettext_lazy("Structure level"),
|
||||
help_text=ugettext_lazy('Will be shown after the name.'))
|
||||
title = models.CharField(
|
||||
max_length=50, blank=True, default='', verbose_name=_("Titel"),
|
||||
help_text=_('Will be shown before the name.'))
|
||||
max_length=50, blank=True, default='', verbose_name=ugettext_lazy("Title"),
|
||||
help_text=ugettext_lazy('Will be shown before the name.'))
|
||||
gender = models.CharField(
|
||||
max_length=50, choices=GENDER_CHOICES, blank=True,
|
||||
verbose_name=_("Gender"), help_text=_('Only for filtering the participant list.'))
|
||||
verbose_name=ugettext_lazy("Gender"), help_text=ugettext_lazy('Only for filtering the participant list.'))
|
||||
committee = models.CharField(
|
||||
max_length=255, blank=True, default='', verbose_name=_("Committee"),
|
||||
help_text=_('Only for filtering the participant list.'))
|
||||
max_length=255, blank=True, default='', verbose_name=ugettext_lazy("Committee"),
|
||||
help_text=ugettext_lazy('Only for filtering the participant list.'))
|
||||
about_me = models.TextField(
|
||||
blank=True, default='', verbose_name=_('About me'),
|
||||
help_text=_('Your profile text'))
|
||||
blank=True, default='', verbose_name=ugettext_lazy('About me'),
|
||||
help_text=ugettext_lazy('Your profile text'))
|
||||
comment = models.TextField(
|
||||
blank=True, default='', verbose_name=_('Comment'),
|
||||
help_text=_('Only for notes.'))
|
||||
blank=True, default='', verbose_name=ugettext_lazy('Comment'),
|
||||
help_text=ugettext_lazy('Only for notes.'))
|
||||
default_password = models.CharField(
|
||||
max_length=100, blank=True, default='',
|
||||
verbose_name=_("Default password"))
|
||||
verbose_name=ugettext_lazy("Default password"))
|
||||
|
||||
@property
|
||||
def clean_name(self):
|
||||
@ -134,9 +134,9 @@ class Group(PersonMixin, Person, SlideMixin, DjangoGroup):
|
||||
|
||||
django_group = models.OneToOneField(DjangoGroup, editable=False, parent_link=True)
|
||||
group_as_person = models.BooleanField(
|
||||
default=False, verbose_name=_("Use this group as participant"),
|
||||
help_text=_('For example as submitter of a motion.'))
|
||||
description = models.TextField(blank=True, verbose_name=_("Description"))
|
||||
default=False, verbose_name=ugettext_lazy("Use this group as participant"),
|
||||
help_text=ugettext_lazy('For example as submitter of a motion.'))
|
||||
description = models.TextField(blank=True, verbose_name=ugettext_lazy("Description"))
|
||||
|
||||
@models.permalink
|
||||
def get_absolute_url(self, link='view'):
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.dispatch import receiver
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_noop, ugettext_lazy, ugettext as _
|
||||
from django.utils.translation import ugettext as _, ugettext_lazy, ugettext_noop
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
@ -35,23 +35,23 @@ def setup_participant_config_page(sender, **kwargs):
|
||||
form_field=forms.CharField(
|
||||
widget=forms.TextInput(),
|
||||
required=False,
|
||||
label=_('System URL'),
|
||||
help_text=_('Printed in PDF of first time passwords only.')))
|
||||
label=ugettext_lazy('System URL'),
|
||||
help_text=ugettext_lazy('Printed in PDF of first time passwords only.')))
|
||||
participant_pdf_welcometext = ConfigVariable(
|
||||
name='participant_pdf_welcometext',
|
||||
default_value=_('Welcome to OpenSlides!'),
|
||||
form_field=forms.CharField(
|
||||
widget=forms.Textarea(),
|
||||
required=False,
|
||||
label=_('Welcome text'),
|
||||
help_text=_('Printed in PDF of first time passwords only.')))
|
||||
label=ugettext_lazy('Welcome text'),
|
||||
help_text=ugettext_lazy('Printed in PDF of first time passwords only.')))
|
||||
participant_sort_users_by_first_name = ConfigVariable(
|
||||
name='participant_sort_users_by_first_name',
|
||||
default_value=False,
|
||||
form_field=forms.BooleanField(
|
||||
required=False,
|
||||
label=_('Sort participants by first name'),
|
||||
help_text=_('Disable for sorting by last name')))
|
||||
label=ugettext_lazy('Sort participants by first name'),
|
||||
help_text=ugettext_lazy('Disable for sorting by last name')))
|
||||
|
||||
return ConfigPage(title=ugettext_noop('Participant'),
|
||||
url='participant',
|
||||
|
@ -3,11 +3,11 @@
|
||||
{% load i18n %}
|
||||
{% load tags %}
|
||||
|
||||
{% block title %}{{ block.super }} – {{ group }}{% endblock %}
|
||||
{% block title %}{{ block.super }} – {% trans group.name %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ group }}
|
||||
<h1>{% trans group.name %}
|
||||
<small class="pull-right">
|
||||
<a href="{% url 'user_group_overview' %}" class="btn btn-mini"><i class="icon-chevron-left"></i> {% trans "Back to overview" %}</a>
|
||||
</small>
|
||||
|
@ -21,7 +21,7 @@
|
||||
{% for group in groups %}
|
||||
<tr class="{% if group.active %}activeline{% endif %}">
|
||||
<td>
|
||||
<a href="{% model_url group 'view' %}">{{ group.name }}</a>
|
||||
<a href="{% model_url group 'view' %}">{% trans group.name %}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span style="width: 1px; white-space: nowrap;">
|
||||
|
@ -14,43 +14,44 @@
|
||||
</h1>
|
||||
|
||||
|
||||
<div class="user_details">
|
||||
<fieldset>
|
||||
<legend>{% trans "Personal data" %}</legend>
|
||||
<label>{% trans "Gender" %}</label>
|
||||
{{ shown_user.get_gender_display }}
|
||||
<label>{% trans "Email" %}</label>
|
||||
{{ shown_user.email }}
|
||||
<label>{% trans "About me" %}</label>
|
||||
{{ shown_user.about_me|linebreaks }}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{% trans "Personal data" %}</legend>
|
||||
<label>{% trans "Gender" %}</label>
|
||||
{{ shown_user.get_gender_display }}
|
||||
<label>{% trans "Email" %}</label>
|
||||
{{ shown_user.email }}
|
||||
<label>{% trans "About me" %}</label>
|
||||
{{ shown_user.about_me|linebreaks }}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Event data" %}</legend>
|
||||
<label>{% trans "Structure level" %}</label>
|
||||
{{ shown_user.structure_level }}
|
||||
<label>{% trans "Committee" %}</label>
|
||||
{{ shown_user.committee }}
|
||||
<label>{% trans "Groups" %}</label>
|
||||
{% if shown_user.groups.all %}
|
||||
{{ shown_user.groups.all|join:", " }}
|
||||
{% else %}
|
||||
{% trans "The participant is not member of any group." %}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{% trans "Event data" %}</legend>
|
||||
<label>{% trans "Structure level" %}</label>
|
||||
{{ shown_user.structure_level }}
|
||||
<label>{% trans "Committee" %}</label>
|
||||
{{ shown_user.committee }}
|
||||
<label>{% trans "Groups" %}</label>
|
||||
{% if shown_user.groups.all %}
|
||||
{{ shown_user.groups.all|join:", " }}
|
||||
{% else %}
|
||||
{% trans "The participant is not member of any group." %}
|
||||
{% if perms.participant.can_manage_participant %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Administrative data" %}</legend>
|
||||
<label>{% trans "Username" %}</label>
|
||||
{{ shown_user.username }}
|
||||
<label>{% trans "Comment" %}</label>
|
||||
{{ shown_user.comment|linebreaks }}
|
||||
<label>{% trans "Last Login" %}</label>
|
||||
{% if shown_user.last_login > shown_user.date_joined %}
|
||||
{{ shown_user.last_login }}
|
||||
{% else %}
|
||||
{% trans "The participant has not logged in yet." %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
|
||||
{% if perms.participant.can_manage_participant %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Administrative data" %}</legend>
|
||||
<label>{% trans "User name" %}</label>
|
||||
{{ shown_user.username }}
|
||||
<label>{% trans "Comment" %}</label>
|
||||
{{ shown_user.comment|linebreaks }}
|
||||
<label>{% trans "Last Login" %}</label>
|
||||
{% if shown_user.last_login > shown_user.date_joined %}
|
||||
{{ shown_user.last_login }}
|
||||
{% else %}
|
||||
{% trans "The participant has not logged in yet." %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _, ugettext_noop
|
||||
from django.utils.translation import ugettext_lazy, ugettext_noop
|
||||
|
||||
from openslides.projector.api import register_slidemodel
|
||||
from openslides.projector.projector import SlideMixin
|
||||
@ -24,9 +24,9 @@ class ProjectorSlide(models.Model, SlideMixin):
|
||||
"""
|
||||
prefix = 'ProjectorSlide'
|
||||
|
||||
title = models.CharField(max_length=256, verbose_name=_("Title"))
|
||||
text = models.TextField(null=True, blank=True, verbose_name=_("Text"))
|
||||
weight = models.IntegerField(default=0, verbose_name=_("Weight"))
|
||||
title = models.CharField(max_length=256, verbose_name=ugettext_lazy("Title"))
|
||||
text = models.TextField(null=True, blank=True, verbose_name=ugettext_lazy("Text"))
|
||||
weight = models.IntegerField(default=0, verbose_name=ugettext_lazy("Weight"))
|
||||
|
||||
def slide(self):
|
||||
return {
|
||||
|
@ -13,7 +13,6 @@ from time import time
|
||||
|
||||
from django.dispatch import Signal, receiver
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy, ugettext as _
|
||||
from django.template.loader import render_to_string
|
||||
from django.core.context_processors import csrf
|
||||
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@ -77,8 +77,8 @@
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.overlay_list .form-inline {
|
||||
margin: 5px 0 0 31px;
|
||||
.overlay_list .overlayblock {
|
||||
margin: 0 0 0 31px;
|
||||
}
|
||||
|
||||
#countdown_time {
|
||||
|
@ -58,7 +58,7 @@ body{
|
||||
top:110px;
|
||||
right:40px;
|
||||
padding-left:30px;
|
||||
background: url(../img/glyphicons_054_clock.png) no-repeat scroll 0px 4px;
|
||||
background: url(../img/glyphicons_054_clock_big.png) no-repeat scroll 0px 4px;
|
||||
}
|
||||
|
||||
#currentTime.ajax_error {
|
||||
@ -73,6 +73,19 @@ body{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#overlay_list_of_speaker_box {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-radius: 0.4em;
|
||||
border: 0.1em solid #777777;
|
||||
background-color: #cccccc;
|
||||
opacity: 0.9;
|
||||
padding: 0 1em;
|
||||
margin: 1em;
|
||||
z-index: 2;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/*** CONTENT ***/
|
||||
#contentwrapper {
|
||||
@ -146,6 +159,14 @@ body{
|
||||
color: #9FA9B7;
|
||||
list-style-type: none;
|
||||
}
|
||||
.list_of_speakers li {
|
||||
font-size: 130%;
|
||||
line-height: 160%;
|
||||
}
|
||||
.last_speakers li {
|
||||
color: #9FA9B7;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Table */
|
||||
table {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="{% static 'styles/projector.css' %}">
|
||||
<link rel="shortcut icon" href="{% static 'images/favicon.png' %}" type="image/png" />
|
||||
<link rel="shortcut icon" href="{% static 'img/favicon.png' %}" type="image/png" />
|
||||
<script type="text/javascript" src="{% static 'javascript/jquery.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'javascript/projector.js' %}"></script>
|
||||
<title>{% block title %} {% get_config 'event_name' %} {% endblock %}</title>
|
||||
|
@ -3,14 +3,14 @@
|
||||
|
||||
<span>
|
||||
{% trans "Countdown for speaking time" %}:
|
||||
<div>
|
||||
<div class="input-append">
|
||||
<div class="overlayblock">
|
||||
<div class="input-append" style="margin-bottom:0;">
|
||||
<input class="projector_countdown_spinval" id="countdown_time" name="countdown_time" type="number" min="0" value="{{ countdown_time }}">
|
||||
<span class="add-on">{% trans "s" context "seconds" %}</span>
|
||||
<button id="countdown_set" class="countdown_control btn" href="{% url 'countdown_set_default' %}" title="{% trans 'Save time as default' %}" style="width: 16px;">
|
||||
<i class="icon-refresh"></i>
|
||||
</button>
|
||||
</div>
|
||||
<a id="countdown_set" class="countdown_control btn btn-mini" href="{% url 'countdown_set_default' %}" title="{% trans 'Save time as default' %}">
|
||||
<i class="icon-refresh"></i>
|
||||
</a>
|
||||
<a id="countdown_reset" class="countdown_control btn" href="{% url 'countdown_reset' %}" title="{% trans 'Reset countdown' %}">
|
||||
<i class="icon-fast-backward"></i>
|
||||
</a>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<span>
|
||||
{% trans "Message" %}:
|
||||
<form class="form-inline" id="overlay_message" action="{% url 'projector_overlay_message' %}" method="post">{% csrf_token %}
|
||||
<div class="input-append" style="width: 85%;">
|
||||
<div class="input-append overlayblock" style="width: 77%;">
|
||||
<input class="input-block-level" id="overlay_message_text" name='message_text' type='text' value="{% get_config 'projector_message' %}">
|
||||
<button type="submit" class="btn btn-primary" name="message" title="{% trans 'Apply' %}" style="width: 16px;">
|
||||
<i class="icon-ok icon-white"></i>
|
||||
|
@ -21,7 +21,7 @@ from django.db import transaction
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import redirect
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from openslides.utils.template import render_block_to_string, Tab
|
||||
from openslides.utils.views import (
|
||||
|
BIN
openslides/static/img/glyphicons_062_paperclip.png
Normal file
BIN
openslides/static/img/glyphicons_062_paperclip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
openslides/static/img/glyphicons_062_paperclip_white.png
Normal file
BIN
openslides/static/img/glyphicons_062_paperclip_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -124,22 +124,14 @@ $(document).ready(function(){
|
||||
}
|
||||
});
|
||||
// Tooltips
|
||||
$('.leftmenu').tooltip({
|
||||
selector: "a[rel=tooltip]",
|
||||
placement: 'right'
|
||||
});
|
||||
$(this).tooltip({
|
||||
selector: "a[rel=tooltip]",
|
||||
placement: 'bottom'
|
||||
});
|
||||
|
||||
$('h1').tooltip({
|
||||
selector: "a[rel=tooltip]",
|
||||
placement: 'bottom'
|
||||
});
|
||||
$('body').tooltip({
|
||||
selector: '.tooltip'
|
||||
});
|
||||
$('.tooltip-left').tooltip({
|
||||
placement: 'left'
|
||||
});
|
||||
|
@ -29,8 +29,10 @@ body {
|
||||
padding-left: 3px;
|
||||
}
|
||||
#header .title {
|
||||
font-size: 20px;
|
||||
font-size: 16px;
|
||||
color: #999999;
|
||||
position: absolute;
|
||||
margin: 8px 0 0 50px;
|
||||
}
|
||||
footer {
|
||||
margin-bottom: 20px;
|
||||
@ -117,17 +119,17 @@ tr.total td {
|
||||
.optional {
|
||||
display: auto;
|
||||
}
|
||||
fieldset {
|
||||
.user_details fieldset {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
fieldset legend {
|
||||
.user_details legend {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
fieldset label {
|
||||
.user_details label {
|
||||
font-weight: bold;
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
fieldset label:after {
|
||||
.user_details label:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
@ -164,17 +166,27 @@ legend + .control-group {
|
||||
height: 110px;
|
||||
width: auto;
|
||||
}
|
||||
#dataTableParticipants_filter input {
|
||||
width: auto;
|
||||
}
|
||||
#dataTableParticipants {
|
||||
clear: none;
|
||||
}
|
||||
#dataTableParticipants_wrapper .row-fluid:after {
|
||||
clear: none;
|
||||
}
|
||||
|
||||
|
||||
/** Left sitebar navigation **/
|
||||
.leftmenu ul {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
list-style: none;
|
||||
}
|
||||
.leftmenu ul ul {
|
||||
display: none;
|
||||
margin-left: 35px;
|
||||
margin-top: -1px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
||||
}
|
||||
.leftmenu ul li {
|
||||
display: block;
|
||||
@ -188,12 +200,11 @@ legend + .control-group {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
background-color: #ffffff;
|
||||
padding: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.leftmenu ul li:first-child a {
|
||||
border-top: 1px solid #DDDDDD;
|
||||
}
|
||||
|
||||
.leftmenu ul li a span.ico {
|
||||
display: inline-block;
|
||||
background: #f9f9f9;
|
||||
@ -230,7 +241,6 @@ legend + .control-group {
|
||||
margin-top: 5px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.leftmenu.lefticon > ul {
|
||||
width: 37px !important;
|
||||
}
|
||||
@ -254,7 +264,6 @@ legend + .control-group {
|
||||
background-position: 0 -24px;
|
||||
}
|
||||
.icon-agenda {
|
||||
/* background-position: -264px 0;*/
|
||||
background-position: 0;
|
||||
background-image: url("../img/glyphicons_045_calendar.png");
|
||||
}
|
||||
@ -292,6 +301,9 @@ legend + .control-group {
|
||||
.icon-personal_info {
|
||||
background-position: -312px -24px;
|
||||
}
|
||||
.icon-append_to_list_of_speakers {
|
||||
background-position: -48px -144px;
|
||||
}
|
||||
|
||||
/** More glyphicons free icons **/
|
||||
.status_link .icon-on, .icon-checked-new {
|
||||
@ -347,9 +359,11 @@ legend + .control-group {
|
||||
}
|
||||
.row-fluid .leftmenu {
|
||||
float: left;
|
||||
width: auto;
|
||||
}
|
||||
#content {
|
||||
margin: 0 5px 0 45px;
|
||||
width: auto;
|
||||
}
|
||||
/* hide optional column */
|
||||
.optional {
|
||||
|
@ -10,7 +10,6 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}{% get_config 'event_name' %}{% endblock %}</title>
|
||||
|
||||
<!-- styles -->
|
||||
<link href="{% static 'styles/bootstrap.min.css' %}" type="text/css" rel="stylesheet" />
|
||||
<link href="{% static 'styles/bootstrap-responsive.min.css' %}" type="text/css" rel="stylesheet" />
|
||||
@ -28,7 +27,7 @@
|
||||
<div class="span12">
|
||||
<div id="header">
|
||||
<a href="/" class="logo" title="{% trans 'Home' %}"><img src="{% static 'img/logo.png' %}" /></a>
|
||||
<!--<a class="title" href="#">{% get_config 'event_name' %}</a>-->
|
||||
<span class="title optional">{% get_config 'event_name' %} - {% get_config 'event_description' %}</span>
|
||||
{% block loginbutton %}
|
||||
<div class="btn-group pull-right">
|
||||
{% if user.is_authenticated %}
|
||||
@ -65,7 +64,7 @@
|
||||
{% for tab in tabs %}
|
||||
{% if tab.permission %}
|
||||
<li{% if tab.selected %} class="active"{% endif %}>
|
||||
<a href="{{ tab.url }}">
|
||||
<a href="{{ tab.url }}" class="tooltip-right">
|
||||
<span class="ico"><i class="icon-{{ tab.app }}"></i></span>
|
||||
<span class="text">{{ tab.title }}</span>
|
||||
</a>
|
||||
|
@ -2,7 +2,7 @@ import json
|
||||
|
||||
from django.db import models
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.forms.fields import Field
|
||||
from django.forms.util import ValidationError as FormValidationError
|
||||
|
||||
|
@ -48,6 +48,7 @@ class PersonField(models.fields.Field):
|
||||
elif isinstance(value, basestring):
|
||||
# The object is already a a person_id
|
||||
return value
|
||||
|
||||
elif hasattr(value, 'person_id'):
|
||||
# The object is a person
|
||||
return value.person_id
|
||||
|
@ -114,7 +114,7 @@ class TestSpeakerAppendView(SpeakerViewTestCase):
|
||||
|
||||
response = self.check_url('/agenda/1/speaker/', self.speaker1_client, 302)
|
||||
self.assertEqual(Speaker.objects.filter(item=self.item1).count(), 0)
|
||||
self.assertMessage(response, 'List of speakers is closed.')
|
||||
self.assertMessage(response, 'The list of speakers is closed.')
|
||||
|
||||
|
||||
class TestAgendaItemView(SpeakerViewTestCase):
|
||||
@ -155,7 +155,7 @@ class TestSpeakerSpeakView(SpeakerViewTestCase):
|
||||
def test_get(self):
|
||||
url = '/agenda/1/speaker/%s/speak/' % self.speaker1.person_id
|
||||
response = self.check_url(url, self.admin_client, 302)
|
||||
self.assertMessage(response, 'Person user:2 is not on the list of item item1.')
|
||||
self.assertMessage(response, 'user:2 is not on the list of item1.')
|
||||
|
||||
speaker = Speaker.objects.add(self.speaker1, self.item1)
|
||||
response = self.check_url(url, self.admin_client, 302)
|
||||
|
Loading…
Reference in New Issue
Block a user