Zusammenführen

This commit is contained in:
Norman Jäckel 2012-07-01 16:30:56 +02:00
commit acd9ba1fd1
13 changed files with 191 additions and 159 deletions

View File

@ -68,13 +68,21 @@ class Item(MPTTModel, SlideMixin):
"""
Return a map with all Data for the Slide
"""
if self.releated_sid:
return self.get_releated_slide().slide()
data = {
'item': self,
'title': self.get_title(),
'template': 'projector/AgendaText.html',
}
if config['presentation_argument'] == 'summary':
print 'soweit schonmal'
data = {
'title': self.get_title(),
'items': self.get_children(),
'template': 'projector/AgendaSummary.html',
}
elif self.releated_sid:
data = self.get_releated_slide().slide()
else:
data = {
'item': self,
'title': self.get_title(),
'template': 'projector/AgendaText.html',
}
return data
def set_closed(self, closed=True):

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

View File

@ -39,6 +39,9 @@
{% if perms.agenda.can_manage_agenda %}
<a href="{% model_url item 'edit' %}"><img src="{% static 'images/icons/edit.png' %}" title="{% trans 'Edit item' %}"></a>
<a href="{% model_url item 'delete' %}"><img src="{% static 'images/icons/delete.png' %}" title="{% trans 'Delete item' %}"></a>
{% if not item.is_leaf_node %}
<a class="activate_link" href="{% url projector_activate_slide item.sid 'summary' %}"><img src="{% static 'images/icons/view-list-tree.png' %}" title="{% trans 'Activate summary for this item' %}"></a>
{% endif %}
{% endif %}
</span>
</td>

View File

@ -33,6 +33,9 @@
<span class="indentation">&nbsp;</span>
{% endfor %}
<a href="{% model_url item 'view' %}">{{ item }}</a>
{% if not item.is_leaf_node %}
<a class="activate_link" href="{% url projector_activate_slide item.sid 'summary' %}"><img src="{% static 'images/icons/view-list-tree.png' %}" title="{% trans 'Activate summary for this item' %}"></a>
{% endif %}
</li>
{% empty %}
<li>{% trans 'No items available.' %}</li>

View File

@ -7,7 +7,7 @@
{% endblock %}
{% block content %}
<h1>{%trans "Agenda" %}</h1>
<h1>{% if title %}{{ title }}{% else %}{% trans "Agenda" %}{% endif %}</h1>
{% endblock %}
{% block scrollcontent %}

View File

@ -18,18 +18,18 @@ from django.utils.translation import ugettext as _
from django.core.context_processors import csrf
from django.views.generic.detail import SingleObjectMixin
from utils.pdf import stylesheet
from utils.views import (TemplateView, RedirectView, UpdateView, CreateView,
from openslides.utils.pdf import stylesheet
from openslides.utils.views import (TemplateView, RedirectView, UpdateView, CreateView,
DeleteView, PDFView, FormView, DetailView)
from utils.template import Tab
from openslides.utils.template import Tab
from config.models import config
from openslides.config.models import config
from projector.api import get_active_slide, set_active_slide
from projector.projector import Widget, SLIDE
from openslides.projector.api import get_active_slide, set_active_slide
from openslides.projector.projector import Widget, SLIDE
from agenda.models import Item
from agenda.forms import ItemOrderForm, ItemForm, ConfigForm
from openslides.agenda.models import Item
from openslides.agenda.forms import ItemOrderForm, ItemForm, ConfigForm
class Overview(TemplateView):

View File

@ -10,15 +10,15 @@
:license: GNU GPL, see LICENSE for more details.
"""
from django.forms import ModelForm, Form, CharField, Textarea, TextInput, ModelMultipleChoiceField, ModelChoiceField, BooleanField, FileField, FileInput, IntegerField, ChoiceField, Select
from django import forms
from django.contrib.auth.models import User
from utils.forms import CssClassMixin
from utils.translation_ext import ugettext as _
from application.models import Application
from openslides.utils.forms import CssClassMixin
from openslides.utils.translation_ext import ugettext as _
from openslides.application.models import Application
class UserModelChoiceField(ModelChoiceField):
class UserModelChoiceField(forms.ModelChoiceField):
"""
Extend ModelChoiceField for users so that the choices are
listed as 'first_name last_name' instead of just 'username'.
@ -27,7 +27,7 @@ class UserModelChoiceField(ModelChoiceField):
return obj.get_full_name()
class UserModelMultipleChoiceField(ModelMultipleChoiceField):
class UserModelMultipleChoiceField(forms.ModelMultipleChoiceField):
"""
Extend ModelMultipleChoiceField for users so that the choices are
listed as 'first_name last_name' instead of just 'username'.
@ -36,18 +36,18 @@ class UserModelMultipleChoiceField(ModelMultipleChoiceField):
return obj.get_full_name()
class ApplicationForm(Form, CssClassMixin):
title = CharField(widget=TextInput(), label=_("Title"))
text = CharField(widget=Textarea(), label=_("Text"))
reason = CharField(widget=Textarea(), required=False, label=_("Reason"))
class ApplicationForm(forms.Form, CssClassMixin):
title = forms.CharField(widget=forms.TextInput(), label=_("Title"))
text = forms.CharField(widget=forms.Textarea(), label=_("Text"))
reason = forms.CharField(widget=forms.Textarea(), required=False, label=_("Reason"))
class ApplicationFormTrivialChanges(ApplicationForm):
trivial_change = BooleanField(required=False, label=_("Trivial change"),
trivial_change = forms.BooleanField(required=False, label=_("Trivial change"),
help_text=_("Trivial changes don't create a new version."))
class ApplicationManagerForm(ModelForm, CssClassMixin):
class ApplicationManagerForm(forms.ModelForm, CssClassMixin):
submitter = UserModelChoiceField(
queryset=User.objects.all().exclude(profile=None).order_by("first_name"),
label=_("Submitter"),
@ -65,27 +65,34 @@ class ApplicationManagerFormSupporter(ApplicationManagerForm):
)
class ApplicationImportForm(Form, CssClassMixin):
csvfile = FileField(widget=FileInput(attrs={'size':'50'}), label=_("CSV File"))
import_permitted = BooleanField(required=False, label=_("Import applications with status \"permitted\""), help_text=_("Set the initial status for each application to \"permitted\""))
class ApplicationImportForm(forms.Form, CssClassMixin):
csvfile = forms.FileField(
widget=forms.FileInput(attrs={'size':'50'}),
label=_("CSV File"),
)
import_permitted = forms.BooleanField(
required=False,
label=_("Import applications with status \"permitted\""),
help_text=_("Set the initial status for each application to \"permitted\""),
)
class ConfigForm(Form, CssClassMixin):
application_min_supporters = IntegerField(
widget=TextInput(attrs={'class':'small-input'}),
class ConfigForm(forms.Form, CssClassMixin):
application_min_supporters = forms.IntegerField(
widget=forms.TextInput(attrs={'class':'small-input'}),
label=_("Number of (minimum) required supporters for a application"),
initial=4,
min_value=0,
max_value=8,
help_text=_("Choose 0 to disable the supporting system"),
)
application_preamble = CharField(
widget=TextInput(),
application_preamble = forms.CharField(
widget=forms.TextInput(),
required=False,
label=_("Application preamble")
)
application_pdf_ballot_papers_selection = ChoiceField(
widget=Select(),
application_pdf_ballot_papers_selection = forms.ChoiceField(
widget=forms.Select(),
required=False,
label=_("Number of ballot papers (selection)"),
choices=[
@ -94,24 +101,24 @@ class ConfigForm(Form, CssClassMixin):
("CUSTOM_NUMBER", _("Use the following custom number")),
]
)
application_pdf_ballot_papers_number = IntegerField(
widget=TextInput(attrs={'class':'small-input'}),
application_pdf_ballot_papers_number = forms.IntegerField(
widget=forms.TextInput(attrs={'class':'small-input'}),
required=False,
min_value=1,
label=_("Custom number of ballot papers")
)
application_pdf_title = CharField(
widget=TextInput(),
application_pdf_title = forms.CharField(
widget=forms.TextInput(),
required=False,
label=_("Title for PDF document (all applications)")
)
application_pdf_preamble = CharField(
widget=Textarea(),
application_pdf_preamble = forms.CharField(
widget=forms.Textarea(),
required=False,
label=_("Preamble text for PDF document (all applications)")
)
application_allow_trivial_change = BooleanField(
application_allow_trivial_change = forms.BooleanField(
label=_("Allow trivial changes"),
help_text=_('Warning: Trivial changes undermine the application permission system.'),
required=False,

View File

@ -34,26 +34,28 @@ from django.core.context_processors import csrf
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.db import transaction
from django.conf import settings
from config.models import config
from openslides.config.models import config
from settings import SITE_ROOT
from openslides.utils.pdf import stylesheet
from openslides.utils.views import PDFView, RedirectView, DeleteView, FormView
from utils.pdf import stylesheet
from utils.views import PDFView, RedirectView, DeleteView, FormView
from utils.utils import template, permission_required, \
from openslides.utils.utils import template, permission_required, \
render_to_forbitten, del_confirm_form, gen_confirm_form
from utils.template import Tab
from openslides.utils.template import Tab
from projector.projector import Widget
from openslides.projector.projector import Widget
from poll.views import PollFormView
from openslides.poll.views import PollFormView
from agenda.models import Item
from openslides.participant.models import Profile
from openslides.participant.api import gen_username, gen_password
from application.models import Application, AVersion, ApplicationPoll
from application.forms import (
from openslides.agenda.models import Item
from openslides.application.models import Application, AVersion, ApplicationPoll
from openslides.application.forms import (
ApplicationForm,
ApplicationFormTrivialChanges,
ApplicationManagerForm,
@ -62,9 +64,6 @@ from application.forms import (
ConfigForm,
)
from participant.models import Profile
from participant.api import gen_username, gen_password
@permission_required('application.can_see_application')
@template('application/overview.html')
@ -853,7 +852,7 @@ class ApplicationPollPDF(PDFView):
pdf_document.build(story)
def append_to_pdf(self, story):
imgpath = os.path.join(SITE_ROOT, 'static/images/circle.png')
imgpath = os.path.join(settings.SITE_ROOT, 'static/images/circle.png')
circle = "<img src='%s' width='15' height='15'/>&nbsp;&nbsp;" % imgpath
cell = []
cell.append(Spacer(0,0.8*cm))

View File

@ -12,8 +12,8 @@
from django.template.loader import render_to_string
from config.models import config
from projector import SLIDE, Slide, Widget
from openslides.config.models import config
from openslides.projector.projector import SLIDE, Slide, Widget
def split_sid(sid):
@ -68,8 +68,9 @@ def get_active_slide(only_sid=False):
return get_slide_from_sid(sid)
def set_active_slide(sid):
def set_active_slide(sid, argument=None):
config["presentation"] = sid
config['presentation_argument'] = argument
def register_slidemodel(model, model_name=None, control_template=None, weight=0):
@ -115,7 +116,6 @@ def projector_message_set(message, sid=None):
overlay = ProjectorOverlay.objects.get(def_name='Message')
except ProjectorOverlay.DoesNotExist:
overlay = ProjectorOverlay(def_name='Message', active=True)
print "hier mal ein ", sid
overlay.sid=sid
overlay.save()

View File

@ -15,7 +15,7 @@ from time import time
from django.dispatch import receiver
from django.template.loader import render_to_string
from config.models import config
from openslides.config.models import config
from openslides.projector.signals import projector_overlays
@ -42,10 +42,7 @@ class SlideMixin(object):
"""
Return the sid from this Slide
"""
for key, value in SLIDE.iteritems():
if type(self) == value.model:
return "%s-%d" % (key, self.id)
return None
return "%s-%d" % (self.prefix, self.id)
@property
def active(self):

View File

@ -17,18 +17,19 @@ from openslides.utils.views import CreateView
from openslides.projector.models import ProjectorSlide
from openslides.projector.views import (ControlView, ActivateView,
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
CountdownEdit, ProjectorEdit)
CountdownEdit, ProjectorEdit, Projector)
urlpatterns = patterns('projector.views',
url(r'^$', 'active_slide',
url(r'^$',
Projector.as_view(),
{'sid': None},
name='projector_show',
),
url(r'^preview/(?P<sid>[^/]*)/$',
'active_slide',
Projector.as_view(),
name='projctor_preview_slide',
),
@ -42,10 +43,9 @@ urlpatterns = patterns('projector.views',
name='projector_activate_slide',
),
url(r'^activate/(?P<sid>[^/]*)/summary/$',
url(r'^activate/(?P<sid>[^/]*)/(?P<argument>[^/]*)/$',
ActivateView.as_view(),
{'summary': True},
name='projector_activate_summary',
name='projector_activate_slide',
),
url(r'^new/$',

View File

@ -14,30 +14,25 @@ from datetime import datetime
from time import time
from django.contrib import messages
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.utils.datastructures import SortedDict
from django.utils.importlib import import_module
from django.dispatch import receiver
from django.template.loader import render_to_string
from django.db.models import Q
from django.conf import settings
from openslides.utils.views import (TemplateView, RedirectView, CreateView,
UpdateView, DeleteView, AjaxMixin)
from openslides.utils.template import render_block_to_string, Tab
from utils.views import TemplateView, RedirectView, CreateView, UpdateView, DeleteView
from utils.utils import (template, permission_required, del_confirm_form,
ajax_request)
from utils.template import render_block_to_string, Tab
from openslides.utils.signals import template_manipulation
from openslides.config.models import config
from config.models import config
import settings
from api import get_active_slide, set_active_slide, projector_message_set, projector_message_delete, get_slide_from_sid
from projector import SLIDE, Widget
from models import ProjectorOverlay, ProjectorSlide
from openslides.projector.signals import projector_overlays, projector_control_box
from openslides.projector.api import (get_active_slide, set_active_slide,
projector_message_set, projector_message_delete, get_slide_from_sid)
from openslides.projector.projector import SLIDE, Widget
from openslides.projector.models import ProjectorOverlay, ProjectorSlide
from openslides.projector.signals import projector_overlays
class ControlView(TemplateView):
@ -104,7 +99,10 @@ class ActivateView(RedirectView):
allow_ajax = True
def pre_redirect(self, request, *args, **kwargs):
set_active_slide(kwargs['sid'])
try:
set_active_slide(kwargs['sid'], kwargs['argument'])
except KeyError:
set_active_slide(kwargs['sid'])
config['up'] = 0
config['bigger'] = 100
@ -150,59 +148,72 @@ class CustomSlideDeleteView(DeleteView):
messages.success(request, _("Custom slide <b>%s</b> was successfully deleted.") % self.object)
@permission_required('projector.can_see_projector')
def active_slide(request, sid=None):
"""
Shows the active Slide.
"""
if sid is None:
class Projector(TemplateView, AjaxMixin):
permission_required = 'projector.can_see_projector'
@property
def data(self):
try:
data = get_active_slide()
except AttributeError: #TODO: It has to be an Slide.DoesNotExist
data = None
ajax = 'on'
else:
data = get_slide_from_sid(sid)
ajax = 'off'
return self._data
except AttributeError:
pass
sid = self.kwargs['sid']
if sid is None:
try:
data = get_active_slide()
except AttributeError: #TODO: It has to be an Slide.DoesNotExist
data = None
ajax = 'on'
else:
data = get_slide_from_sid(sid)
ajax = 'off'
if data is None:
data = {
'title': config['event_name'],
'template': 'projector/default.html',
}
data['overlays'] = []
data['overlay'] = ''
data['ajax'] = ajax
if data is None:
data = {
'title': config['event_name'],
'template': 'projector/default.html',
}
data['overlays'] = []
data['ajax'] = ajax
# Projector Overlays
sid = get_active_slide(True)
active_defs = ProjectorOverlay.objects.filter(active=True).filter(Q(sid=sid) | Q(sid=None)).values_list('def_name', flat=True)
for receiver, response in projector_overlays.send(sender=sid, register=False, call=active_defs):
if response is not None:
data['overlays'].append(response)
# Projector Overlays
if self.kwargs['sid'] is None:
active_defs = ProjectorOverlay.objects.filter(active=True).filter(Q(sid=sid) | Q(sid=None)).values_list('def_name', flat=True)
for receiver, response in projector_overlays.send(sender=sid, register=False, call=active_defs):
if response is not None:
data['overlays'].append(response)
self._data = data
return data
def get_template_names(self):
return [self.data['template']]
template_manipulation.send(sender='projector', request=request, context=data)
if request.is_ajax():
content = render_block_to_string(data['template'], 'content', data)
scrollcontent = render_block_to_string(data['template'], 'scrollcontent', data)
jsondata = {
def get_context_data(self, **kwargs):
context = super(Projector, self).get_context_data(**kwargs)
context.update(self.data)
return context
def get_ajax_context(self, **kwargs):
content = render_block_to_string(self.get_template_names()[0], 'content', self.data)
scrollcontent = render_block_to_string(self.get_template_names()[0], 'scrollcontent', self.data)
context = super(Projector, self).get_ajax_context(**kwargs)
context.update({
'content': content,
'scrollcontent': scrollcontent,
'overlays': data['overlays'],
'title': data['title'],
'time': datetime.now().strftime('%H:%M'),
'overlays': self.data['overlays'],
'title': self.data['title'],
'bigger': config['bigger'],
'up': config['up'],
'overlay': data['overlay']
}
return ajax_request(jsondata)
else:
return render_to_response(
data['template'],
data,
context_instance=RequestContext(request)
)
})
return context
def get(self, request, *args, **kwargs):
if request.is_ajax():
return self.ajax_get(request, *args, **kwargs)
return super(Projector, self).get(request, *args, **kwargs)
class ProjectorEdit(RedirectView):

View File

@ -13,27 +13,31 @@
try:
import json
except ImportError:
# for python 2.5 support
import simplejson as json
try:
from cStringIO import StringIO
except ImportError:
# Is this exception realy necessary?
from StringIO import StringIO
from reportlab.platypus import SimpleDocTemplate, Paragraph, Frame, PageBreak, Spacer, Table, LongTable, TableStyle, Image
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Frame, PageBreak,
Spacer, Table, LongTable, TableStyle, Image)
from reportlab.lib.units import cm
from django.conf import settings
from django.contrib import messages
from django.utils.translation import ugettext as _
from django.http import HttpResponseServerError, HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.conf import settings
from django.dispatch import receiver
from django.http import HttpResponseServerError, HttpResponse, HttpResponseRedirect
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.utils.importlib import import_module
from django.template import loader, RequestContext
from django.template.loader import render_to_string
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.dispatch import receiver
from django.utils.importlib import import_module
from django.views.generic import (
TemplateView as _TemplateView,
RedirectView as _RedirectView,
@ -45,14 +49,12 @@ from django.views.generic import (
)
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.list import TemplateResponseMixin
from django.utils.importlib import import_module
from django.core.context_processors import csrf
import settings
from utils import render_to_forbitten
from openslides.config.models import config
from openslides.utils.utils import render_to_forbitten
from openslides.utils.signals import template_manipulation
from pdf import firstPage, laterPages
from config.models import config
from openslides.utils.pdf import firstPage, laterPages
NO_PERMISSION_REQUIRED = 'No permission required'
@ -93,6 +95,14 @@ class PermissionMixin(object):
return _View.dispatch(self, request, *args, **kwargs)
class AjaxMixin(object):
def get_ajax_context(self, **kwargs):
return {}
def ajax_get(self, request, *args, **kwargs):
return HttpResponse(json.dumps(self.get_ajax_context(**kwargs)))
class TemplateView(PermissionMixin, _TemplateView):
def get_context_data(self, **kwargs):
context = super(TemplateView, self).get_context_data(**kwargs)
@ -107,15 +117,12 @@ class ListView(PermissionMixin, SetCookieMixin, _ListView):
return context
class AjaxView(PermissionMixin, View):
class AjaxView(PermissionMixin, AjaxMixin, View):
def get(self, request, *args, **kwargs):
return HttpResponse(json.dumps(self.get_ajax_context(**kwargs)))
def get_ajax_context(self, **kwargs):
return {}
return self.ajax_get(request, *args, **kwargs)
class RedirectView(PermissionMixin, _RedirectView):
class RedirectView(PermissionMixin, AjaxMixin, _RedirectView):
permanent = False
allow_ajax = False
@ -132,15 +139,12 @@ class RedirectView(PermissionMixin, _RedirectView):
self.pre_post_redirect(request, *args, **kwargs)
if self.request.is_ajax() and self.allow_ajax:
return HttpResponse(json.dumps(self.get_ajax_context(**kwargs)))
return self.ajax_get(request, *args, **kwargs)
return super(RedirectView, self).get(request, *args, **kwargs)
def get_redirect_url(self, **kwargs):
return reverse(super(RedirectView, self).get_redirect_url(**kwargs))
def get_ajax_context(self, **kwargs):
return {}
class FormView(PermissionMixin, _FormView):
def get_success_url(self):