clean up the projector App
This commit is contained in:
parent
eb3adcd8ca
commit
15621b7702
@ -17,6 +17,9 @@ from openslides.projector.projector import SLIDE, Slide, Widget
|
||||
|
||||
|
||||
def split_sid(sid):
|
||||
"""
|
||||
Slit a SID in the model-part and in the model-id
|
||||
"""
|
||||
try:
|
||||
data = sid.split('-')
|
||||
except AttributeError:
|
||||
@ -34,6 +37,11 @@ def split_sid(sid):
|
||||
|
||||
|
||||
def get_slide_from_sid(sid, element=False):
|
||||
"""
|
||||
Return the Slide for an given sid.
|
||||
If element== False, return the slide-dict,
|
||||
else, return the object.
|
||||
"""
|
||||
try:
|
||||
key, id = split_sid(sid)
|
||||
except TypeError:
|
||||
@ -56,10 +64,10 @@ def get_slide_from_sid(sid, element=False):
|
||||
def get_active_slide(only_sid=False):
|
||||
"""
|
||||
Returns the active slide. If no slide is active, or it can not find an Item,
|
||||
it raise an error
|
||||
return None
|
||||
|
||||
if only_sid is True, returns only the id of this item. Returns None if not Item
|
||||
is active. Does not Raise Item.DoesNotExist
|
||||
if only_sid is True, returns only the id of this item. Returns None if not
|
||||
Item is active.
|
||||
"""
|
||||
sid = config["presentation"]
|
||||
|
||||
@ -69,12 +77,18 @@ def get_active_slide(only_sid=False):
|
||||
|
||||
|
||||
def set_active_slide(sid, argument=None):
|
||||
"""
|
||||
Set the active Slide.
|
||||
"""
|
||||
config["presentation"] = sid
|
||||
config['presentation_argument'] = argument
|
||||
|
||||
|
||||
def register_slidemodel(model, model_name=None, control_template=None, weight=0):
|
||||
#TODO: Warn if there already is a slide with this prefix
|
||||
def register_slidemodel(model, model_name=None, control_template=None,
|
||||
weight=0):
|
||||
"""
|
||||
Register a Model as a slide.
|
||||
"""
|
||||
if model_name is None:
|
||||
model_name = model.prefix
|
||||
|
||||
@ -94,7 +108,9 @@ def register_slidemodel(model, model_name=None, control_template=None, weight=0)
|
||||
|
||||
|
||||
def register_slidefunc(key, func, control_template=None, weight=0, name=''):
|
||||
#TODO: Warn if there already is a slide with this prefix
|
||||
"""
|
||||
Register a function for as a slide.
|
||||
"""
|
||||
if control_template is None:
|
||||
control_template = 'projector/default_control_slidefunc.html'
|
||||
category = func.__module__.split('.')[0]
|
||||
@ -110,6 +126,10 @@ def register_slidefunc(key, func, control_template=None, weight=0, name=''):
|
||||
|
||||
|
||||
def projector_message_set(message, sid=None):
|
||||
"""
|
||||
Set the overlay-message.
|
||||
if sid is set, only show the message on the sid-slide.
|
||||
"""
|
||||
from models import ProjectorOverlay
|
||||
config['projector_message'] = message
|
||||
try:
|
||||
@ -121,4 +141,7 @@ def projector_message_set(message, sid=None):
|
||||
|
||||
|
||||
def projector_message_delete():
|
||||
"""
|
||||
Delete the overlay-message.
|
||||
"""
|
||||
config['projector_message'] = ''
|
||||
|
@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
openslides.projector.models
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Models for the projector app.
|
||||
|
||||
@ -12,22 +12,25 @@
|
||||
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
|
||||
from openslides.config.signals import default_config_value
|
||||
|
||||
from api import register_slidemodel
|
||||
from projector import SlideMixin
|
||||
from openslides.projector.api import register_slidemodel
|
||||
from openslides.projector.projector import SlideMixin
|
||||
|
||||
from openslides.config.models import config
|
||||
|
||||
from config.models import config
|
||||
from utils.translation_ext import ugettext as _
|
||||
|
||||
|
||||
class ProjectorSlide(models.Model, SlideMixin):
|
||||
"""
|
||||
Model for Slides, only for the projector. Also called custom slides.
|
||||
"""
|
||||
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"))
|
||||
|
||||
def slide(self):
|
||||
return {
|
||||
@ -46,12 +49,19 @@ class ProjectorSlide(models.Model, SlideMixin):
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('can_manage_projector', _("Can manage the projector", fixstr=True)),
|
||||
('can_see_projector', _("Can see projector", fixstr=True)),
|
||||
('can_manage_projector', ugettext_noop("Can manage the projector")),
|
||||
('can_see_projector', ugettext_noop("Can see projector")),
|
||||
)
|
||||
|
||||
|
||||
register_slidemodel(ProjectorSlide,
|
||||
control_template='projector/control_customslide.html')
|
||||
|
||||
|
||||
class ProjectorOverlay(models.Model):
|
||||
"""
|
||||
Save information for a overlay.
|
||||
"""
|
||||
active = models.BooleanField(verbose_name=_('Active'))
|
||||
def_name = models.CharField(max_length=64)
|
||||
sid = models.CharField(max_length=64, null=True, blank=True)
|
||||
@ -62,9 +72,6 @@ class ProjectorOverlay(models.Model):
|
||||
return self.def_name
|
||||
|
||||
|
||||
register_slidemodel(ProjectorSlide, control_template='projector/control_customslide.html')
|
||||
|
||||
|
||||
@receiver(default_config_value, dispatch_uid="projector_default_config")
|
||||
def default_config(sender, key, **kwargs):
|
||||
return {
|
||||
|
@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
openslides.projector.projector
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Slide functions for the projector app.
|
||||
|
||||
@ -29,7 +29,7 @@ class SlideMixin(object):
|
||||
|
||||
def slide(self):
|
||||
"""
|
||||
Return a map with all Data for a Slide
|
||||
Return a map with all Data for the Slide.
|
||||
"""
|
||||
return {
|
||||
'slide': self,
|
||||
@ -47,19 +47,22 @@ class SlideMixin(object):
|
||||
@property
|
||||
def active(self):
|
||||
"""
|
||||
Return True, if the the slide is the active one.
|
||||
Return True, if the the slide is the active slide.
|
||||
"""
|
||||
from api import get_active_slide
|
||||
return True if get_active_slide(only_sid=True) == self.sid else False
|
||||
return get_active_slide(only_sid=True) == self.sid
|
||||
|
||||
def set_active(self):
|
||||
"""
|
||||
Appoint this item as the active one.
|
||||
Appoint this item as the active slide.
|
||||
"""
|
||||
config["presentation"] = "%s-%d" % (self.prefix, self.id)
|
||||
set_active_slide(self.sid)
|
||||
|
||||
|
||||
class Slide(object):
|
||||
"""
|
||||
Represents a Slide for the projector. Can be a modelinstanz, or a function.
|
||||
"""
|
||||
def __init__(self, model_slide=False, func=None, model=None, category=None,
|
||||
key=None, model_name='', control_template='', weight=0, name=''):
|
||||
"""
|
||||
@ -82,10 +85,16 @@ class Slide(object):
|
||||
|
||||
@property
|
||||
def active(self):
|
||||
"""
|
||||
Return True if the Slide is active, else: False.
|
||||
"""
|
||||
from api import get_active_slide
|
||||
return get_active_slide(True) == self.key
|
||||
|
||||
def get_items(self):
|
||||
"""
|
||||
If the Slide is a Slide from a Model, return all Objects.
|
||||
"""
|
||||
try:
|
||||
return self.model.objects.all()
|
||||
except AttributeError:
|
||||
@ -93,6 +102,9 @@ class Slide(object):
|
||||
|
||||
|
||||
class Widget(object):
|
||||
"""
|
||||
Class for a Widget for the Projector-Tab.
|
||||
"""
|
||||
def __init__(self, name, html=None, template=None, context={}):
|
||||
self.name = name
|
||||
if html is not None:
|
||||
|
@ -13,5 +13,3 @@
|
||||
from django.dispatch import Signal
|
||||
|
||||
projector_overlays = Signal(providing_args=['register', 'call'])
|
||||
|
||||
projector_control_box = Signal()
|
||||
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
openslides.projector.tests
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Unit tests for the projector app.
|
||||
|
||||
:copyright: 2011, 2012 by OpenSlides team, see AUTHORS.
|
||||
:license: GNU GPL, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
openslides.projector.urls
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
URL list for the projector app.
|
||||
|
||||
@ -10,11 +10,8 @@
|
||||
:license: GNU GPL, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
from openslides.utils.views import CreateView
|
||||
|
||||
from openslides.projector.models import ProjectorSlide
|
||||
from openslides.projector.views import (ControlView, ActivateView,
|
||||
CustomSlideCreateView, CustomSlideUpdateView, CustomSlideDeleteView,
|
||||
CountdownEdit, ProjectorEdit, Projector, ActivateOverlay)
|
||||
@ -104,12 +101,6 @@ urlpatterns = patterns('projector.views',
|
||||
name='projector_clean',
|
||||
),
|
||||
|
||||
# TODO: Merge the following lines with this one:
|
||||
## url(r'^countdown/(?P<command>[^/]*)/$',
|
||||
## CountdownEdit.as_view(),
|
||||
## name='countdown_edit',
|
||||
## ),
|
||||
|
||||
url(r'^countdown/reset/$',
|
||||
CountdownEdit.as_view(),
|
||||
{'command': 'reset'},
|
||||
|
@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
openslides.projector.views
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Views for the projector app.
|
||||
|
||||
@ -13,41 +13,48 @@
|
||||
from datetime import datetime
|
||||
from time import time
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.db.models import Q
|
||||
from django.dispatch import receiver
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.importlib import import_module
|
||||
from django.dispatch import receiver
|
||||
from django.db.models import Q
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from openslides.utils.template import render_block_to_string, Tab
|
||||
from openslides.utils.utils import html_strong
|
||||
from openslides.utils.views import (TemplateView, RedirectView, CreateView,
|
||||
UpdateView, DeleteView, AjaxMixin)
|
||||
from openslides.utils.template import render_block_to_string, Tab
|
||||
|
||||
from openslides.config.models import config
|
||||
|
||||
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.projector import SLIDE, Widget
|
||||
from openslides.projector.signals import projector_overlays
|
||||
|
||||
|
||||
class ControlView(TemplateView, AjaxMixin):
|
||||
"""
|
||||
Overview over all possible slides, the overlays and a liveview.
|
||||
"""
|
||||
template_name = 'projector/control.html'
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
|
||||
def get_projector_overlays(self):
|
||||
overlays = []
|
||||
for receiver, name in projector_overlays.send(sender='registerer', register=True):
|
||||
for receiver, name in projector_overlays.send(sender='registerer',
|
||||
register=True):
|
||||
if name is not None:
|
||||
try:
|
||||
projector_overlay = ProjectorOverlay.objects.get(def_name=name)
|
||||
projector_overlay = ProjectorOverlay.objects.get(
|
||||
def_name=name)
|
||||
except ProjectorOverlay.DoesNotExist:
|
||||
active = name == 'Message'
|
||||
projector_overlay = ProjectorOverlay(def_name=name, active=active)
|
||||
projector_overlay = ProjectorOverlay(def_name=name,
|
||||
active=active)
|
||||
projector_overlay.save()
|
||||
overlays.append(projector_overlay)
|
||||
return overlays
|
||||
@ -57,13 +64,6 @@ class ControlView(TemplateView, AjaxMixin):
|
||||
projector_message_set(request.POST['message_text'])
|
||||
elif 'message-clean' in request.POST:
|
||||
projector_message_delete()
|
||||
else:
|
||||
for overlay in self.get_projector_overlays():
|
||||
if overlay.def_name in request.POST:
|
||||
overlay.active = True
|
||||
else:
|
||||
overlay.active = False
|
||||
overlay.save()
|
||||
if request.is_ajax():
|
||||
return self.ajax_get(request, *args, **kwargs)
|
||||
return self.get(request, *args, **kwargs)
|
||||
@ -101,87 +101,10 @@ class ControlView(TemplateView, AjaxMixin):
|
||||
return context
|
||||
|
||||
|
||||
class ActivateOverlay(RedirectView):
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
|
||||
@property
|
||||
def overlay(self):
|
||||
try:
|
||||
return self._overlay
|
||||
except AttributeError:
|
||||
self._overlay = ProjectorOverlay.objects.get(def_name=self.kwargs['name'])
|
||||
return self._overlay
|
||||
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
if kwargs['activate']:
|
||||
self.overlay.active = True
|
||||
else:
|
||||
self.overlay.active = False
|
||||
self.overlay.save()
|
||||
|
||||
def get_ajax_context(self, **kwargs):
|
||||
return {
|
||||
'active': self.overlay.active,
|
||||
'def_name': self.overlay.def_name,
|
||||
}
|
||||
|
||||
|
||||
class ActivateView(RedirectView):
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
try:
|
||||
set_active_slide(kwargs['sid'], kwargs['argument'])
|
||||
except KeyError:
|
||||
set_active_slide(kwargs['sid'])
|
||||
config['up'] = 0
|
||||
config['bigger'] = 100
|
||||
|
||||
|
||||
class CustomSlideCreateView(CreateView):
|
||||
permission_required = 'agenda.can_manage_agenda'
|
||||
template_name = 'projector/new.html'
|
||||
model = ProjectorSlide
|
||||
context_object_name = 'customslide'
|
||||
success_url = 'projector_control'
|
||||
apply_url = 'customslide_edit'
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, _("Custom slide <b>%s</b> was successfully created.") % self.request.POST['title'])
|
||||
if 'apply' in self.request.POST:
|
||||
return reverse(self.get_apply_url(), args=[self.object.id])
|
||||
return reverse(super(CreateView, self).get_success_url())
|
||||
|
||||
|
||||
class CustomSlideUpdateView(UpdateView):
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
template_name = 'projector/new.html'
|
||||
model = ProjectorSlide
|
||||
context_object_name = 'customslide'
|
||||
success_url = 'projector_control'
|
||||
apply_url = 'customslide_edit'
|
||||
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, _("Custom slide <b>%s</b> was successfully modified.") % self.request.POST['title'])
|
||||
if 'apply' in self.request.POST:
|
||||
return ''
|
||||
return reverse(super(UpdateView, self).get_success_url())
|
||||
|
||||
|
||||
class CustomSlideDeleteView(DeleteView):
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
model = ProjectorSlide
|
||||
url = 'projector_control'
|
||||
|
||||
def pre_post_redirect(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
self.object.delete()
|
||||
messages.success(request, _("Custom slide <b>%s</b> was successfully deleted.") % self.object)
|
||||
|
||||
|
||||
class Projector(TemplateView, AjaxMixin):
|
||||
"""
|
||||
The Projector-Page.
|
||||
"""
|
||||
permission_required = 'projector.can_see_projector'
|
||||
|
||||
@property
|
||||
@ -211,8 +134,11 @@ class Projector(TemplateView, AjaxMixin):
|
||||
|
||||
# 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):
|
||||
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
|
||||
@ -227,8 +153,10 @@ class Projector(TemplateView, AjaxMixin):
|
||||
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)
|
||||
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)
|
||||
content_hash = hash(content)
|
||||
@ -250,8 +178,27 @@ class Projector(TemplateView, AjaxMixin):
|
||||
return super(Projector, self).get(request, *args, **kwargs)
|
||||
|
||||
|
||||
class ActivateView(RedirectView):
|
||||
"""
|
||||
Activate a Slide.
|
||||
"""
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
try:
|
||||
set_active_slide(kwargs['sid'], kwargs['argument'])
|
||||
except KeyError:
|
||||
set_active_slide(kwargs['sid'])
|
||||
config['up'] = 0
|
||||
config['bigger'] = 100
|
||||
|
||||
|
||||
class ProjectorEdit(RedirectView):
|
||||
"""
|
||||
Scale or scroll the projector.
|
||||
"""
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
@ -273,6 +220,9 @@ class ProjectorEdit(RedirectView):
|
||||
|
||||
|
||||
class CountdownEdit(RedirectView):
|
||||
"""
|
||||
Start, stop or reset the countdown.
|
||||
"""
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
@ -293,8 +243,8 @@ class CountdownEdit(RedirectView):
|
||||
start_stamp = config['countdown_start_stamp']
|
||||
pause_stamp = config['countdown_pause_stamp']
|
||||
now = time()
|
||||
|
||||
config['countdown_start_stamp'] = now - (pause_stamp - start_stamp)
|
||||
config['countdown_start_stamp'] = now - \
|
||||
(pause_stamp - start_stamp)
|
||||
else:
|
||||
config['countdown_start_stamp'] = time()
|
||||
|
||||
@ -306,7 +256,8 @@ class CountdownEdit(RedirectView):
|
||||
config['countdown_state'] = 'paused'
|
||||
elif command == 'set-default':
|
||||
try:
|
||||
config['countdown_time'] = int(self.request.GET['countdown_time'])
|
||||
config['countdown_time'] = \
|
||||
int(self.request.GET['countdown_time'])
|
||||
except ValueError:
|
||||
pass
|
||||
except AttributeError:
|
||||
@ -319,7 +270,74 @@ class CountdownEdit(RedirectView):
|
||||
}
|
||||
|
||||
|
||||
class ActivateOverlay(RedirectView):
|
||||
"""
|
||||
Activate or deactivate an overlay.
|
||||
"""
|
||||
url = 'projector_control'
|
||||
allow_ajax = True
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
|
||||
@property
|
||||
def overlay(self):
|
||||
try:
|
||||
return self._overlay
|
||||
except AttributeError:
|
||||
self._overlay = ProjectorOverlay.objects.get(
|
||||
def_name=self.kwargs['name'])
|
||||
return self._overlay
|
||||
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
if kwargs['activate']:
|
||||
self.overlay.active = True
|
||||
else:
|
||||
self.overlay.active = False
|
||||
self.overlay.save()
|
||||
|
||||
def get_ajax_context(self, **kwargs):
|
||||
return {
|
||||
'active': self.overlay.active,
|
||||
'def_name': self.overlay.def_name,
|
||||
}
|
||||
|
||||
|
||||
class CustomSlideCreateView(CreateView):
|
||||
"""
|
||||
Create a custom slide.
|
||||
"""
|
||||
permission_required = 'agenda.can_manage_agenda'
|
||||
template_name = 'projector/new.html'
|
||||
model = ProjectorSlide
|
||||
context_object_name = 'customslide'
|
||||
success_url = 'projector_control'
|
||||
apply_url = 'customslide_edit'
|
||||
|
||||
|
||||
class CustomSlideUpdateView(UpdateView):
|
||||
"""
|
||||
Update a custom slide.
|
||||
"""
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
template_name = 'projector/new.html'
|
||||
model = ProjectorSlide
|
||||
context_object_name = 'customslide'
|
||||
success_url = 'projector_control'
|
||||
apply_url = 'customslide_edit'
|
||||
|
||||
|
||||
class CustomSlideDeleteView(DeleteView):
|
||||
"""
|
||||
Delete a custom slide.
|
||||
"""
|
||||
permission_required = 'projector.can_manage_projector'
|
||||
model = ProjectorSlide
|
||||
url = 'projector_control'
|
||||
|
||||
|
||||
def register_tab(request):
|
||||
"""
|
||||
Register the projector tab.
|
||||
"""
|
||||
selected = True if request.path.startswith('/projector/') else False
|
||||
return Tab(
|
||||
title=_('Projector'),
|
||||
@ -330,6 +348,9 @@ def register_tab(request):
|
||||
|
||||
|
||||
def get_widgets(request):
|
||||
"""
|
||||
Return the custom slide widget.
|
||||
"""
|
||||
return [
|
||||
Widget(
|
||||
name='projector',
|
||||
|
@ -52,7 +52,7 @@ from django.views.generic.list import TemplateResponseMixin
|
||||
|
||||
from openslides.config.models import config
|
||||
|
||||
from openslides.utils.utils import render_to_forbitten
|
||||
from openslides.utils.utils import render_to_forbitten, html_strong
|
||||
from openslides.utils.signals import template_manipulation
|
||||
from openslides.utils.pdf import firstPage, laterPages
|
||||
|
||||
@ -164,6 +164,7 @@ class FormView(PermissionMixin, _FormView):
|
||||
|
||||
class UpdateView(PermissionMixin, _UpdateView):
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, self.get_success_message())
|
||||
if 'apply' in self.request.POST:
|
||||
return ''
|
||||
return reverse(super(UpdateView, self).get_success_url())
|
||||
@ -177,9 +178,13 @@ class UpdateView(PermissionMixin, _UpdateView):
|
||||
messages.error(self.request, _('Please check the form for errors.'))
|
||||
return super(UpdateView, self).form_invalid(form)
|
||||
|
||||
def get_success_message(self):
|
||||
return _('%s was successfully modified.') % html_strong(self.object)
|
||||
|
||||
|
||||
class CreateView(PermissionMixin, _CreateView):
|
||||
def get_success_url(self):
|
||||
messages.success(self.request, self.get_success_message())
|
||||
if 'apply' in self.request.POST:
|
||||
return reverse(self.get_apply_url(), args=[self.object.id])
|
||||
return reverse(super(CreateView, self).get_success_url())
|
||||
@ -197,13 +202,16 @@ class CreateView(PermissionMixin, _CreateView):
|
||||
messages.error(self.request, _('Please check the form for errors.'))
|
||||
return super(CreateView, self).form_invalid(form)
|
||||
|
||||
def get_success_message(self):
|
||||
return _('%s was successfully created.') % html_strong(self.object)
|
||||
|
||||
|
||||
class DeleteView(RedirectView, SingleObjectMixin):
|
||||
def get_confirm_question(self):
|
||||
return _('Do you really want to delete <b>%s</b>?') % self.object
|
||||
return _('Do you really want to delete %s?') % html_strong(self.object)
|
||||
|
||||
def get_success_message(self):
|
||||
return _('Item <b>%s</b> was successfully deleted.') % self.object
|
||||
return _('%s was successfully deleted.') % html_strong(self.object)
|
||||
|
||||
def pre_redirect(self, request, *args, **kwargs):
|
||||
self.confirm_form(request, self.object)
|
||||
|
Loading…
Reference in New Issue
Block a user