diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 408cabd90..4e8c9e452 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -19,6 +19,7 @@ django-sass-processor==0.5.4
djangorestframework==3.4.0
drfdocs==0.0.11
easy-thumbnails==2.3
+django-image-cropping==1.1.0
git+git://github.com/interlegis/trml2pdf.git
libsass==0.11.1
psycopg2==2.7.3
diff --git a/sapl/crud/base.py b/sapl/crud/base.py
index d53125249..44852d7a0 100644
--- a/sapl/crud/base.py
+++ b/sapl/crud/base.py
@@ -17,8 +17,8 @@ from django.http.response import Http404
from django.shortcuts import redirect
from django.utils.decorators import classonlymethod
from django.utils.encoding import force_text
-from django.utils.translation import ugettext_lazy as _
from django.utils.translation import string_concat
+from django.utils.translation import ugettext_lazy as _
from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
UpdateView)
from django.views.generic.base import ContextMixin
@@ -30,6 +30,7 @@ from sapl.rules.map_rules import (RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL,
from sapl.settings import BASE_DIR
from sapl.utils import normalize
+
logger = logging.getLogger(BASE_DIR.name)
ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \
@@ -39,6 +40,7 @@ ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \
def _form_invalid_message(msg):
return '%s %s' % (_('Formulário inválido.'), msg)
+
FORM_MESSAGES = {ACTION_CREATE: (_('Registro criado com sucesso!'),
_('O registro não foi criado.')),
ACTION_UPDATE: (_('Registro alterado com sucesso!'),
@@ -79,6 +81,7 @@ def make_pagination(index, num_pages):
head = from_to(1, PAGINATION_LENGTH - len(tail) - 1)
return head + [None] + tail
+
"""
variáveis do crud:
help_topic
diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py
index 77be6ac80..32a1b67de 100644
--- a/sapl/parlamentares/forms.py
+++ b/sapl/parlamentares/forms.py
@@ -13,6 +13,7 @@ from django.forms import ModelForm
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from floppyforms.widgets import ClearableFileInput
+from image_cropping.widgets import ImageCropWidget, CropWidget
from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.rules import SAPL_GROUP_VOTANTE
@@ -26,6 +27,18 @@ class ImageThumbnailFileInput(ClearableFileInput):
template_name = 'floppyforms/image_thumbnail.html'
+class CustomImageCropWidget(ImageCropWidget):
+ """
+ Custom ImageCropWidget that doesn't show the initial value of the field.
+ We use this trick, and place it right under the CropWidget so that
+ it looks like the user is seeing the image and clearing the image.
+ """
+ template_with_initial = (
+ # '%(initial_text)s: %(initial)s '
+ '%(clear_template)s
%(input_text)s: %(input)s'
+ )
+
+
def validar_datas_legislatura(eleicao, inicio, fim, pk=None):
# Verifica se data de eleição < inicio < fim
@@ -128,9 +141,12 @@ class ParlamentarForm(ModelForm):
class Meta:
model = Parlamentar
exclude = []
- widgets = {'fotografia': ImageThumbnailFileInput,
- 'biografia': forms.Textarea(
- attrs={'id': 'texto-rico'})}
+
+ widgets = {
+ 'fotografia': CustomImageCropWidget(),
+ 'cropping': CropWidget(),
+ 'biografia': forms.Textarea(
+ attrs={'id': 'texto-rico'})}
class ParlamentarCreateForm(ParlamentarForm):
diff --git a/sapl/parlamentares/migrations/0016_auto_20180202_1331.py b/sapl/parlamentares/migrations/0016_auto_20180202_1331.py
new file mode 100644
index 000000000..693660a1a
--- /dev/null
+++ b/sapl/parlamentares/migrations/0016_auto_20180202_1331.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.13 on 2018-02-02 15:31
+from __future__ import unicode_literals
+
+from django.db import migrations
+import image_cropping.fields
+import sapl.parlamentares.models
+import sapl.utils
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('parlamentares', '0015_auto_20180131_1629'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='parlamentar',
+ name='cropping',
+ field=image_cropping.fields.ImageRatioField('fotografia', '128x128', adapt_rotation=False, allow_fullsize=False, free_crop=False,
+ help_text='A configuração do Avatar é possível após a atualização da fotografia.', hide_image_field=False, size_warning=False, verbose_name='Avatar'),
+ ),
+ migrations.AlterField(
+ model_name='parlamentar',
+ name='fotografia',
+ field=image_cropping.fields.ImageCropField(blank=True, null=True, upload_to=sapl.parlamentares.models.foto_upload_path, validators=[
+ sapl.utils.restringe_tipos_de_arquivo_img], verbose_name='Fotografia'),
+ ),
+ ]
diff --git a/sapl/parlamentares/migrations/0017_auto_20180202_1528.py b/sapl/parlamentares/migrations/0017_auto_20180202_1528.py
new file mode 100644
index 000000000..89fc81314
--- /dev/null
+++ b/sapl/parlamentares/migrations/0017_auto_20180202_1528.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.13 on 2018-02-02 17:28
+from __future__ import unicode_literals
+
+from django.db import migrations
+import image_cropping.fields
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('parlamentares', '0016_auto_20180202_1331'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='parlamentar',
+ name='cropping',
+ field=image_cropping.fields.ImageRatioField('fotografia', '128x128', adapt_rotation=False, allow_fullsize=False, free_crop=False, help_text='A configuração do Avatar é possível após a atualização da fotografia.', hide_image_field=False, size_warning=True, verbose_name='Avatar'),
+ ),
+ ]
diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py
index d58102e87..239e75cab 100644
--- a/sapl/parlamentares/models.py
+++ b/sapl/parlamentares/models.py
@@ -1,9 +1,10 @@
-import reversion
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
+from image_cropping.fields import ImageCropField, ImageRatioField
from model_utils import Choices
+import reversion
from sapl.base.models import Autor
from sapl.decorators import vigencia_atual
@@ -262,12 +263,14 @@ class Parlamentar(models.Model):
blank=True, verbose_name=_('Biografia'))
# XXX Esse atribuito foi colocado aqui para não atrapalhar a migração
- fotografia = models.ImageField(
- blank=True,
- null=True,
- upload_to=foto_upload_path,
- verbose_name=_('Fotografia'),
- validators=[restringe_tipos_de_arquivo_img])
+ fotografia = ImageCropField(
+ verbose_name=_('Fotografia'), upload_to=foto_upload_path,
+ validators=[restringe_tipos_de_arquivo_img], null=True, blank=True)
+
+ cropping = ImageRatioField(
+ 'fotografia', '128x128', verbose_name=_('Avatar'), size_warning=True,
+ help_text=_('A configuração do Avatar '
+ 'é possível após a atualização da fotografia.'))
# campo conceitual de reversão genérica para o model Autor que dá a
# o meio possível de localização de tipos de autores.
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
index e708af3f5..a96873f18 100644
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -1,5 +1,5 @@
-import json
from datetime import datetime
+import json
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
@@ -33,6 +33,7 @@ from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
SituacaoMilitar, TipoAfastamento, TipoDependente, Votante)
+
CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa')
PartidoCrud = CrudAux.build(Partido, 'partidos')
SessaoLegislativaCrud = CrudAux.build(SessaoLegislativa, 'sessao_legislativa')
@@ -396,7 +397,6 @@ class ParlamentarCrud(Crud):
class BaseMixin(Crud.BaseMixin):
ordered_list = False
list_field_names = [
- 'avatar_html',
'nome_parlamentar',
'filiacao_atual',
'ativo',
@@ -421,6 +421,10 @@ class ParlamentarCrud(Crud):
class UpdateView(Crud.UpdateView):
form_class = ParlamentarForm
+ @property
+ def layout_key(self):
+ return 'ParlamentarUpdate'
+
class CreateView(Crud.CreateView):
form_class = ParlamentarCreateForm
@@ -477,8 +481,7 @@ class ParlamentarCrud(Crud):
mandato_titular=F('mandato__titular'))
def get_headers(self):
- return ['',
- _('Parlamentar'), _('Partido'),
+ return [_('Parlamentar'), _('Partido'),
_('Ativo?'), _('Titular?')]
def get_context_data(self, **kwargs):
@@ -489,54 +492,44 @@ class ParlamentarCrud(Crud):
context['legislaturas'] = legislaturas
context['legislatura_id'] = self.take_legislatura_id()
- # Tira Link do avatar_html e coloca no nome
for row in context['rows']:
- # preenche coluna foto, se vazia
- if not row[0][0]:
- img = "
{{ NO_ENTRIES_MSG }}
+ {% else %} ++ {% else %} + | + {% endif %} + {{ name }} + | + {% endfor %} +|
---|---|---|
+ + | + {% endif %} ++ {% if href %} + {{ value|safe|default:"" }} + {% else %} + {{ value|safe|default:"" }} + {% endif %} + | + {% endfor %} +