diff --git a/compilacao/file2dispositivo.py b/compilacao/file2dispositivo.py
new file mode 100644
index 000000000..e6bbb6ae8
--- /dev/null
+++ b/compilacao/file2dispositivo.py
@@ -0,0 +1,327 @@
+import re
+
+from odf.element import Node, Text
+from odf.opendocument import load
+from odf.table import Table, TableCell, TableRow
+from odf.text import (List, ListHeader, ListItem, ListLevelStyleBullet,
+ ListLevelStyleNumber, ListStyle, Note)
+
+from sapl import utils
+
+
+class Parser(object):
+
+ parser_list = []
+
+ def parser(self, _filepath):
+
+ self.filepath = _filepath
+
+ return self.re_parser()
+
+ def re_parser(self):
+
+ self.parser_list = []
+
+ # odt identificado pela extensão ou teste caso o arquivo sem extensão
+ if self.filepath.endswith('.odt') or\
+ not re.search(r"(\w+)\.(\w+)", self.filepath):
+
+ try:
+ odtparser = OdtParser()
+
+ self.parser_list = odtparser.parser(self.filepath)
+
+ return self.parser_list
+ except Exception as e:
+ print(e)
+ # TODO: Continue para outros formatos
+ pass
+
+ # doc identificado pela extensão ou teste caso o arquivo sem extensão
+ if self.filepath.endswith(('.doc', 'docx')) or\
+ not re.search(r"(\w+)\.(\w+)", self.filepath):
+
+ try:
+ # TODO
+ return []
+ except Exception as e:
+ # TODO: Continue para outros formatos
+ pass
+
+ return []
+
+ def _reduce_terms(self, _nodes=None, level=0):
+ print(level)
+ if not _nodes:
+ nodes = self.parser_list
+ else:
+ nodes = _nodes
+
+ fstr = True
+ i = -1
+ for nd in nodes:
+ i += 1
+ # print(nd)
+
+ if not _nodes:
+ fstr = False
+ if nd[0] == 'table:table':
+ continue
+
+ if isinstance(nd, list):
+ fstr = False
+ nodes[i] = self._reduce_terms(nd, level=level + 1)
+
+ if fstr:
+ return ' '.join(nodes)
+ return nodes
+
+
+class OdtParser(Parser):
+ FNC1 = '1'
+ FNCI = 'I'
+ FNCi = 'i'
+ FNCA = 'A'
+ FNCa = 'a'
+ FNC8 = '*'
+ FNCN = 'N'
+
+ def re_parser(self):
+
+ self.textdoc = load(self.filepath)
+ self.level_list = 0
+ self.control_list = {}
+
+ # mm = ODF2MoinMoin(self.filepath)
+ # self.parser_list = [mm.toString(), ]
+
+ self.parser_list = self._import_itens(self.textdoc.text, level=0)
+
+ # self._reduce_terms()
+
+ return self.parser_list
+
+ def _import_itens(self, element, level=0):
+ try:
+ result = []
+ for el in element.childNodes:
+ print(level, el.tagName)
+ _r = ''
+ if el.tagName == 'Text':
+ _r = str(el)
+ else:
+ if el.isInstanceOf(Note):
+ continue
+ elif el.isInstanceOf(Table):
+ _r = self._import_table(el, level=level + 1)
+ elif el.isInstanceOf(List):
+ _r = self._import_list(el, level=level + 1)
+ # elif el.isInstanceOf(P):
+ # _r = [self.extractText(el),]
+ elif el.hasChildNodes():
+ _r = self._import_itens(el, level=level + 1)
+ else:
+ _r = str(el)
+
+ if _r:
+ if isinstance(_r, str):
+ result += [_r, ]
+ else:
+ result += _r
+
+ return result
+ except Exception as e:
+ print(e)
+
+ def _import_table(self, element, level=0):
+ result = ''
+ print(level)
+ try:
+ if element.isInstanceOf(Table):
+ result += '
'
+
+ for el in element.childNodes:
+ _r = ''
+ if isinstance(el, Text):
+ _r = str(el)
+ else:
+ if el.isInstanceOf(TableRow):
+ _r = self._import_table(el, level=level + 1)
+ _r = '%s ' % (''.join(_r))
+ result += ''.join(_r)
+ elif el.isInstanceOf(TableCell):
+ _r = self._import_table(el, level=level + 1)
+ if el.getAttribute('numberrowsspanned'):
+ _r = '%s ' % (
+ el.getAttribute('numberrowsspanned'),
+ ''.join(_r))
+ elif el.getAttribute('numbercolumnsspanned'):
+ _r = '%s ' % (
+ el.getAttribute('numbercolumnsspanned'),
+ ''.join(_r))
+ else:
+ _r = '%s ' % (''.join(_r))
+
+ result += ''.join(_r)
+ else:
+ _r = self.extractText(el)
+ # _r = self._reduce_terms(_r)
+ if isinstance(_r, list):
+ result += ' '.join(_r)
+ else:
+ if _r:
+ result += _r + ' '
+
+ if element.isInstanceOf(Table):
+ result += '
'
+
+ return [result, ]
+ except Exception as e:
+ print(e)
+
+ def _import_list(self, element, level=0):
+ self.level_list += 1
+ result = []
+ print(level)
+
+ numsufixo = ''
+ numformat = ''
+ startvalue = ''
+
+ count_list_item = 0
+
+ try:
+ if element.isInstanceOf(List):
+ _stylename = element.getAttribute('stylename')
+
+ if _stylename:
+ self.stylename = _stylename
+
+ liststyles = self.textdoc.getElementsByType(ListStyle)
+
+ for liststyle in liststyles:
+ if liststyle.getAttribute('name') == self.stylename:
+ break
+
+ stylesnumbers = liststyle.getElementsByType(
+ ListLevelStyleNumber)
+
+ for item in stylesnumbers:
+ if item.getAttribute('level') == str(self.level_list):
+ numsufixo = item.getAttribute('numsuffix') or ''
+ numformat = item.getAttribute('numformat') or ''
+ startvalue = item.getAttribute('startvalue') or ''
+ break
+
+ if not numformat:
+ stylesbullets = liststyle.getElementsByType(
+ ListLevelStyleBullet)
+ for item in stylesbullets:
+ if item.getAttribute('level') == str(self.level_list):
+ numformat = '*'
+ break
+
+ _id = element.getAttribute('id')
+ if _id:
+ self.id_last_list = _id
+
+ if self.id_last_list not in self.control_list:
+ self.control_list[self.id_last_list] = [0, ] * 10
+
+ if _id:
+ if not element.getAttribute('continuelist') and\
+ self.level_list == 1:
+ self.control_list[self.id_last_list] = [0, ] * 10
+
+ except Exception as e:
+ print(e)
+
+ try:
+ flag_first = True
+ for el in element.childNodes:
+ prefixo = ''
+ if isinstance(el, Text):
+ _r = [str(el), ]
+ else:
+ if el.isInstanceOf(ListHeader) or\
+ el.isInstanceOf(ListItem):
+
+ if startvalue and flag_first:
+ self.control_list[self.id_last_list][
+ self.level_list - 1] = int(startvalue) - 1
+ flag_first = False
+
+ self.control_list[self.id_last_list][
+ self.level_list - 1] += 1
+ count_list_item = self.control_list[self.id_last_list][
+ self.level_list - 1]
+
+ if numformat == OdtParser.FNC1:
+ prefixo = str(count_list_item)
+ elif numformat == OdtParser.FNCI:
+ prefixo = utils.int_to_roman(count_list_item)
+ elif numformat == OdtParser.FNCi:
+ prefixo = utils.int_to_roman(
+ count_list_item).lower()
+ elif numformat == OdtParser.FNCA:
+ prefixo = utils.int_to_letter(count_list_item)
+ elif numformat == OdtParser.FNCa:
+ prefixo = utils.int_to_letter(
+ count_list_item).lower()
+ elif numformat == OdtParser.FNC8:
+ prefixo = '*'
+ else:
+ prefixo = str(count_list_item)
+
+ prefixo += numsufixo
+
+ _r = self._import_itens(el, level=level + 1)
+
+ if _r:
+ if prefixo:
+ _r[0] = '%s %s' % (prefixo, _r[0])
+ result += _r
+ else:
+ result += _r
+
+ self.level_list -= 1
+ return result
+
+ except Exception as e:
+ print(e)
+
+ def extractText(self, odfElement):
+ """ Extract text content from an Element, with whitespace represented
+ properly. Returns the text, with tabs, spaces, and newlines
+ correctly evaluated. This method recursively descends through the
+ children of the given element, accumulating text and "unwrapping"
+ , , and elements along the way.
+ """
+ result = []
+
+ if len(odfElement.childNodes) != 0:
+ for child in odfElement.childNodes:
+ if child.nodeType == Node.TEXT_NODE:
+ result.append(child.data)
+ elif child.nodeType == Node.ELEMENT_NODE:
+ subElement = child
+ tagName = subElement.qname
+ if tagName == (u"urn:oasis:names:tc:opendocument:xmlns:" +
+ "text:1.0", u"line-break"):
+ result.append("\n")
+ elif tagName == (u"urn:oasis:names:tc:opendocument:" +
+ "xmlns:text:1.0", u"tab"):
+ result.append("\t")
+ elif tagName == (u"urn:oasis:names:tc:opendocument:" +
+ "xmlns:text:1.0", u"s"):
+ c = subElement.getAttribute('c')
+ if c:
+ spaceCount = int(c)
+ else:
+ spaceCount = 1
+
+ result.append(" " * spaceCount)
+ else:
+ result.append(self.extractText(subElement))
+ return ''.join(result)
diff --git a/compilacao/migrations/0015_auto_20151115_2310.py b/compilacao/migrations/0015_auto_20151115_2310.py
new file mode 100644
index 000000000..e0ec8b9e6
--- /dev/null
+++ b/compilacao/migrations/0015_auto_20151115_2310.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0014_auto_20151107_1836'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='tipodispositivo',
+ name='dispositivo_de_alteracao',
+ field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Dispositivo de Alteração'),
+ ),
+ migrations.AlterField(
+ model_name='tipodispositivorelationship',
+ name='filho_permitido',
+ field=models.ForeignKey(related_name='possiveis_pais', to='compilacao.TipoDispositivo'),
+ ),
+ ]
diff --git a/compilacao/migrations/0016_auto_20151119_0950.py b/compilacao/migrations/0016_auto_20151119_0950.py
new file mode 100644
index 000000000..3f417e105
--- /dev/null
+++ b/compilacao/migrations/0016_auto_20151119_0950.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import datetime
+from django.utils.timezone import utc
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0015_auto_20151115_2310'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='PerfilEstruturalTextosNormativos',
+ fields=[
+ ('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')),
+ ('nome', models.CharField(max_length=50, verbose_name='Nome')),
+ ],
+ options={
+ 'verbose_name_plural': 'Perfis Estruturais de Textos Normativos',
+ 'verbose_name': 'Perfil Estrutural de Textos Normativos',
+ },
+ ),
+ migrations.RemoveField(
+ model_name='dispositivo',
+ name='timestamp',
+ ),
+ migrations.AddField(
+ model_name='dispositivo',
+ name='created',
+ field=models.DateTimeField(default=datetime.datetime(2015, 11, 19, 11, 49, 55, 455058, tzinfo=utc), auto_now_add=True, verbose_name='created'),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='dispositivo',
+ name='modified',
+ field=models.DateTimeField(auto_now=True, default=datetime.datetime(2015, 11, 19, 11, 50, 5, 86839, tzinfo=utc), verbose_name='modified'),
+ preserve_default=False,
+ ),
+ migrations.AddField(
+ model_name='tipodispositivorelationship',
+ name='perfil',
+ field=models.ForeignKey(blank=True, related_name='+', null=True, default=None, to='compilacao.PerfilEstruturalTextosNormativos'),
+ ),
+ ]
diff --git a/compilacao/migrations/0017_auto_20151119_1035.py b/compilacao/migrations/0017_auto_20151119_1035.py
new file mode 100644
index 000000000..8a902b838
--- /dev/null
+++ b/compilacao/migrations/0017_auto_20151119_1035.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0016_auto_20151119_0950'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='perfilestruturaltextosnormativos',
+ name='padrao',
+ field=models.BooleanField(verbose_name='Padrão', choices=[(True, 'Sim'), (False, 'Não')], default=False),
+ ),
+ migrations.AlterField(
+ model_name='tipodispositivorelationship',
+ name='perfil',
+ field=models.ForeignKey(to='compilacao.PerfilEstruturalTextosNormativos'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='tipodispositivorelationship',
+ unique_together=set([('pai', 'filho_permitido', 'perfil')]),
+ ),
+ ]
diff --git a/compilacao/migrations/0018_auto_20151119_1052.py b/compilacao/migrations/0018_auto_20151119_1052.py
new file mode 100644
index 000000000..00e78daef
--- /dev/null
+++ b/compilacao/migrations/0018_auto_20151119_1052.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0017_auto_20151119_1035'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='tipodispositivo',
+ name='quantidade_permitida',
+ ),
+ migrations.AddField(
+ model_name='tipodispositivorelationship',
+ name='quantidade_permitida',
+ field=models.IntegerField(default=-1, verbose_name='Quantidade permitida nesta relação'),
+ ),
+ ]
diff --git a/compilacao/migrations/0019_auto_20151119_1120.py b/compilacao/migrations/0019_auto_20151119_1120.py
new file mode 100644
index 000000000..f5a461faf
--- /dev/null
+++ b/compilacao/migrations/0019_auto_20151119_1120.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0018_auto_20151119_1052'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='perfilestruturaltextosnormativos',
+ name='sigla',
+ field=models.CharField(max_length=10, verbose_name='Sigla', default='LC95'),
+ preserve_default=False,
+ ),
+ ]
diff --git a/compilacao/migrations/0020_auto_20151119_1126.py b/compilacao/migrations/0020_auto_20151119_1126.py
new file mode 100644
index 000000000..d63e4c8d2
--- /dev/null
+++ b/compilacao/migrations/0020_auto_20151119_1126.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0019_auto_20151119_1120'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='perfilestruturaltextosnormativos',
+ name='sigla',
+ field=models.CharField(
+ max_length=10, verbose_name='Sigla', unique=True),
+ ),
+ ]
diff --git a/compilacao/migrations/0021_auto_20151119_1617.py b/compilacao/migrations/0021_auto_20151119_1617.py
new file mode 100644
index 000000000..e378f4a60
--- /dev/null
+++ b/compilacao/migrations/0021_auto_20151119_1617.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('compilacao', '0020_auto_20151119_1126'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='perfilestruturaltextosnormativos',
+ options={'verbose_name': 'Perfil Estrutural de Textos Normativos', 'verbose_name_plural': 'Perfis Estruturais de Textos Normativos', 'ordering': ['-padrao', 'sigla']},
+ ),
+ migrations.AddField(
+ model_name='tipodispositivorelationship',
+ name='permitir_variacao',
+ field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], verbose_name='Permitir Variação Numérica', default=True),
+ ),
+ ]
diff --git a/compilacao/models.py b/compilacao/models.py
index 529c40718..b2d646eff 100644
--- a/compilacao/models.py
+++ b/compilacao/models.py
@@ -11,6 +11,17 @@ from sapl import utils
from sapl.utils import YES_NO_CHOICES
+class TimestampedMixin(models.Model):
+ created = models.DateTimeField(
+ verbose_name=_('created'),
+ editable=False, blank=True, auto_now_add=True)
+ modified = models.DateTimeField(
+ verbose_name=_('modified'), editable=False, blank=True, auto_now=True)
+
+ class Meta:
+ abstract = True
+
+
class BaseModel(models.Model):
class Meta:
@@ -77,12 +88,6 @@ class TipoVide(models.Model):
class TipoDispositivo(BaseModel):
"""
- - para class_css articulacao, omissis, ementa,
- bloco_alteracao, artigo, caput e paragrafo
- são palavras chaves usadas no código e de existência obrigatória.
-
- - apenas articulacao recebe nivel zero
-
- no attributo rotulo_prefixo_texto, caso haja um ';' (ponto e vírgula), e
só pode haver 1 ';', o método [def rotulo_padrao] considerará que o
rótulo do dispositivo deverá ser escrito com o contéudo após o ';'
@@ -200,6 +205,10 @@ class TipoDispositivo(BaseModel):
choices=YES_NO_CHOICES,
default=False,
verbose_name=_('Dispositivo de Articulação (Sem Texto)'))
+ dispositivo_de_alteracao = models.BooleanField(
+ choices=YES_NO_CHOICES,
+ default=False,
+ verbose_name=_('Dispositivo de Alteração'))
formato_variacao0 = models.CharField(
max_length=1,
choices=FORMATO_NUMERACAO_CHOICES,
@@ -238,10 +247,6 @@ class TipoDispositivo(BaseModel):
symmetrical=False,
related_name='+')
- quantidade_permitida = models.IntegerField(
- default=-1,
- verbose_name=_('Quantidade permitida dentro de uma Norma'))
-
class Meta:
verbose_name = _('Tipo de Dispositivo')
verbose_name_plural = _('Tipos de Dispositivo')
@@ -250,32 +255,86 @@ class TipoDispositivo(BaseModel):
def __str__(self):
return self.nome
- def permitido_inserir_in(self, base, excluir_autos=False):
- pp = self.possiveis_pais.filter(pai=base)
+ def permitido_inserir_in(
+ self, base, include_relative_autos=True, perfil_pk=None):
+
+ if not perfil_pk:
+ perfis = PerfilEstruturalTextosNormativos.objects.filter(
+ padrao=True)[:1]
+
+ if not perfis.exists():
+ return False
+
+ perfil_pk = perfis[0].pk
+
+ pp = self.possiveis_pais.filter(pai=base, perfil_id=perfil_pk)
if pp.exists():
- if excluir_autos:
+ if not include_relative_autos:
if pp[0].filho_de_insercao_automatica:
return False
return True
return False
+ def permitido_variacao(
+ self, base, perfil_pk=None):
+
+ if not perfil_pk:
+ perfis = PerfilEstruturalTextosNormativos.objects.filter(
+ padrao=True)[:1]
+
+ if not perfis.exists():
+ return False
+
+ perfil_pk = perfis[0].pk
+
+ pp = self.possiveis_pais.filter(pai=base, perfil_id=perfil_pk)
+ if pp.exists():
+ if pp[0].permitir_variacao:
+ return True
+ return False
+
+
+class PerfilEstruturalTextosNormativos(BaseModel):
+ sigla = models.CharField(
+ max_length=10, unique=True, verbose_name=_('Sigla'))
+ nome = models.CharField(max_length=50, verbose_name=_('Nome'))
+ padrao = models.BooleanField(
+ default=False,
+ choices=YES_NO_CHOICES, verbose_name=_('Padrão'))
+
+ class Meta:
+ verbose_name = _('Perfil Estrutural de Textos Normativos')
+ verbose_name_plural = _('Perfis Estruturais de Textos Normativos')
+
+ ordering = ['-padrao', 'sigla']
+
+ def __str__(self):
+ return self.nome
+
class TipoDispositivoRelationship(BaseModel):
pai = models.ForeignKey(TipoDispositivo, related_name='filhos_permitidos')
filho_permitido = models.ForeignKey(
TipoDispositivo,
- blank=True, null=True, default=None,
related_name='possiveis_pais')
+ perfil = models.ForeignKey(PerfilEstruturalTextosNormativos)
filho_de_insercao_automatica = models.BooleanField(
default=False,
choices=YES_NO_CHOICES, verbose_name=_('Filho de Inserção Automática'))
+ permitir_variacao = models.BooleanField(
+ default=True,
+ choices=YES_NO_CHOICES, verbose_name=_('Permitir Variação Numérica'))
+
+ quantidade_permitida = models.IntegerField(
+ default=-1,
+ verbose_name=_('Quantidade permitida nesta relação'))
class Meta:
verbose_name = _('Relação Direta Permitida')
verbose_name_plural = _('Relaçõe Diretas Permitidas')
ordering = ['pai', 'filho_permitido']
unique_together = (
- ('pai', 'filho_permitido',),)
+ ('pai', 'filho_permitido', 'perfil'),)
def __str__(self):
return '%s - %s' % (
@@ -331,7 +390,7 @@ class Publicacao(models.Model):
return '%s: %s' % (self.veiculo_publicacao, self.publicacao)
-class Dispositivo(BaseModel):
+class Dispositivo(BaseModel, TimestampedMixin):
TEXTO_PADRAO_DISPOSITIVO_REVOGADO = _('(Revogado)')
INTERVALO_ORDEM = 1000
ordem = models.PositiveIntegerField(
@@ -411,8 +470,6 @@ class Dispositivo(BaseModel):
choices=YES_NO_CHOICES,
verbose_name=_('Visibilidade na Norma Publicada'))
- timestamp = models.DateTimeField()
-
tipo_dispositivo = models.ForeignKey(
TipoDispositivo,
related_name='dispositivos_do_tipo_set',
@@ -894,11 +951,12 @@ class Dispositivo(BaseModel):
return proxima_articulacao[0]
- def is_relative_auto_insert(self):
+ def is_relative_auto_insert(self, perfil_pk):
if self.dispositivo_pai is not None:
# pp possiveis_pais
pp = self.tipo_dispositivo.possiveis_pais.filter(
- pai=self.dispositivo_pai.tipo_dispositivo)
+ pai=self.dispositivo_pai.tipo_dispositivo,
+ perfil_id=perfil_pk)
if pp.exists():
if pp[0].filho_de_insercao_automatica:
diff --git a/compilacao/templatetags/compilacao_filters.py b/compilacao/templatetags/compilacao_filters.py
index d1c1f75da..65b8abab1 100644
--- a/compilacao/templatetags/compilacao_filters.py
+++ b/compilacao/templatetags/compilacao_filters.py
@@ -46,6 +46,8 @@ def nota_automatica(dispositivo):
d = dispositivo.dispositivo_atualizador.dispositivo_pai
if dispositivo.texto == Dispositivo.TEXTO_PADRAO_DISPOSITIVO_REVOGADO:
return 'Revogado pelo %s.' % d
+ elif not dispositivo.dispositivo_substituido:
+ return 'Inclusão feita pelo %s.' % d
else:
return 'Alteração feita pelo %s.' % d
return ''
@@ -69,6 +71,16 @@ def get_sign_vigencia(value):
return signer.sign(str(string))
+@register.filter
+def select_provaveis_inserts(view, request):
+ return view.select_provaveis_inserts(request)
+
+
+@register.filter
+def is_relative_auto_insert(dpt, request):
+ return dpt.is_relative_auto_insert(request.session.perfil_estrutural)
+
+
@register.filter
def isinst(value, class_str):
classe = value.__class__.__name__
@@ -82,11 +94,11 @@ def render_actions_head(view, d_atual):
return False
# Menu
- if view.pk_view == view.pk_add and d_atual.pk == view.pk_view:
+ if view.pk_view == view.pk_edit and d_atual.pk == view.pk_view:
return True
# conteudo e menu no filho
- if view.pk_view != view.pk_add and d_atual.pk == view.pk_add:
+ if view.pk_view != view.pk_edit and d_atual.pk == view.pk_edit:
return True
return False
@@ -95,7 +107,7 @@ def render_actions_head(view, d_atual):
@register.filter
def short_string(str, length):
if len(str) > length:
- return str[:length]+'...'
+ return str[:length] + '...'
else:
return str
diff --git a/compilacao/urls.py b/compilacao/urls.py
index b3c74e3d1..d59058411 100644
--- a/compilacao/urls.py
+++ b/compilacao/urls.py
@@ -1,9 +1,9 @@
from django.conf.urls import include, url
from compilacao import views
-from compilacao.views import (tipo_dispositivo_crud, tipo_nota_crud,
- tipo_publicacao_crud, tipo_vide_crud,
- veiculo_publicacao_crud)
+from compilacao.views import (perfil_estr_txt_norm, tipo_dispositivo_crud,
+ tipo_nota_crud, tipo_publicacao_crud,
+ tipo_vide_crud, veiculo_publicacao_crud)
urlpatterns_compilacao = [
url(r'^(?P[0-9]+)/compilacao$',
@@ -37,4 +37,6 @@ urlpatterns = [
include(tipo_dispositivo_crud.urls)),
url(r'^sistema/compilacao/veiculo-publicacao/',
include(veiculo_publicacao_crud.urls)),
+ url(r'^sistema/compilacao/perfil-estrutural-textos-normativos/',
+ include(perfil_estr_txt_norm.urls)),
]
diff --git a/compilacao/views.py b/compilacao/views.py
index 3075bf275..b5972d3e7 100644
--- a/compilacao/views.py
+++ b/compilacao/views.py
@@ -2,17 +2,21 @@ from collections import OrderedDict
from datetime import datetime, timedelta
from os.path import sys
+from django import forms
from django.core.signing import Signer
from django.db.models import Q
from django.http.response import JsonResponse
+from django.shortcuts import render
from django.utils.dateparse import parse_date
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
from django.views.generic.edit import FormMixin
from django.views.generic.list import ListView
-from compilacao.models import (Dispositivo, TipoDispositivo, TipoNota,
- TipoPublicacao, TipoVide, VeiculoPublicacao)
+from compilacao.file2dispositivo import Parser
+from compilacao.models import (Dispositivo, PerfilEstruturalTextosNormativos,
+ TipoDispositivo, TipoNota, TipoPublicacao,
+ TipoVide, VeiculoPublicacao)
from norma.models import NormaJuridica
from sapl.crud import build_crud
@@ -49,6 +53,13 @@ tipo_publicacao_crud = build_crud(
[('sigla', 2), ('nome', 10)]],
])
+perfil_estr_txt_norm = build_crud(
+ PerfilEstruturalTextosNormativos, 'perfil_estrutural', [
+
+ [_('Perfil Estrutural de Textos Normativos'),
+ [('sigla', 2), ('nome', 10)]],
+ ])
+
veiculo_publicacao_crud = build_crud(
VeiculoPublicacao, 'veiculo_publicacao', [
@@ -97,10 +108,6 @@ tipo_dispositivo_crud = build_crud(
],
- [_('Outras Configurações'),
- [('quantidade_permitida', 12),
- ],
- ],
])
@@ -246,7 +253,20 @@ class DispositivoView(CompilacaoView):
return itens
-class CompilacaoEditView(CompilacaoView):
+class UpLoadImportFileForm(forms.Form):
+ import_file = forms.FileField(
+ required=True,
+ label=_('Arquivo formato ODF para Importanção'))
+
+
+def handle_uploaded_file(f, outfilepath):
+ with open(outfilepath, 'wb+') as destination:
+ for chunk in f.chunks():
+ destination.write(chunk)
+
+
+class CompilacaoEditView(CompilacaoView, FormMixin):
+
template_name = 'compilacao/edit.html'
flag_alteradora = -1
@@ -254,11 +274,60 @@ class CompilacaoEditView(CompilacaoView):
flag_nivel_ini = 0
flag_nivel_old = -1
- pk_add = 0
+ pk_edit = 0
pk_view = 0
+ def post(self, request, *args, **kwargs):
+ form = UpLoadImportFileForm(request.POST, request.FILES)
+ message = "Arquivo Submetido com sucesso"
+
+ self.object_list = self.get_queryset()
+
+ if form.is_valid():
+ try:
+ f = request.FILES['import_file']
+ outfilepath = '/tmp/' + f.name
+ handle_uploaded_file(f, outfilepath)
+
+ p = Parser()
+ p.parser(outfilepath)
+
+ except Exception as e:
+ print(e)
+
+ context = self.get_context_data(
+ object_list=self.object_list,
+ form=form,
+ message=message,
+ view=self,
+ parser_list=p.parser_list)
+ return render(request, self.template_name, context)
+ else:
+ context = self.get_context_data(
+ object_list=self.object_list,
+ form=form,
+ message=form.errors,
+ view=self)
+ return self.form_invalid(context)
+
+ return self.render_to_response({'form': form})
+
+ def form_invalid(self, context):
+ return self.render_to_response(context)
+
+ def get(self, request, *args, **kwargs):
+
+ self.object_list = self.get_queryset()
+ form_class = UpLoadImportFileForm
+ self.form = self.get_form(form_class)
+ context = self.get_context_data(
+ object_list=self.object_list,
+ form=self.form)
+
+ return self.render_to_response(context)
+
def get_queryset(self):
- self.pk_add = 0
+ self.pk_edit = 0
self.pk_view = 0
self.flag_alteradora = -1
@@ -315,8 +384,25 @@ class CompilacaoEditView(CompilacaoView):
return result
+ def set_perfil_in_session(self, request=None, perfil_id=0):
+ if not request:
+ return None
+
+ if perfil_id:
+ perfil = PerfilEstruturalTextosNormativos.objects.get(
+ pk=perfil_id)
+ request.session['perfil_estrutural'] = perfil.pk
+ else:
+ perfis = PerfilEstruturalTextosNormativos.objects.filter(
+ padrao=True)[:1]
+
+ if not perfis.exists():
+ request.session.pop('perfil_estrutural')
+ else:
+ request.session['perfil_estrutural'] = perfis[0].pk
-class DispositivoEditView(CompilacaoEditView, FormMixin):
+
+class DispositivoEditView(CompilacaoEditView):
template_name = 'compilacao/edit_bloco.html'
def post(self, request, *args, **kwargs):
@@ -357,19 +443,45 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
return JsonResponse(data, safe=False)
+ def get_queryset_perfil_estrutural(self):
+ perfis = PerfilEstruturalTextosNormativos.objects.all()
+ return perfis
+
+ def get(self, request, *args, **kwargs):
+
+ try:
+ if 'perfil_pk' in request.GET:
+ self.set_perfil_in_session(
+ request, request.GET['perfil_pk'])
+ elif 'perfil_estrutural' not in request.session:
+ self.set_perfil_in_session(request=request)
+
+ self.object_list = self.get_queryset()
+
+ self.perfil_estrutural_list = self.get_queryset_perfil_estrutural()
+
+ context = self.get_context_data(
+ object_list=self.object_list,
+ perfil_estrutural_list=self.perfil_estrutural_list
+ )
+ except Exception as e:
+ print(e)
+
+ return self.render_to_response(context)
+
def get_queryset(self):
self.flag_alteradora = -1
self.flag_nivel_ini = 0
self.flag_nivel_old = -1
try:
- self.pk_add = int(self.request.GET['pkadd'])
+ self.pk_edit = int(self.request.GET['edit'])
except:
- self.pk_add = 0
+ self.pk_edit = 0
self.pk_view = int(self.kwargs['dispositivo_id'])
try:
- if self.pk_add == self.pk_view:
+ if self.pk_edit == self.pk_view:
bloco = Dispositivo.objects.get(
pk=self.kwargs['dispositivo_id'])
else:
@@ -381,7 +493,7 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
self.flag_nivel_old = bloco.nivel - 1
self.flag_nivel_ini = bloco.nivel
- if self.pk_add == self.pk_view:
+ if self.pk_edit == self.pk_view:
return [bloco, ]
proximo_bloco = Dispositivo.objects.filter(
@@ -402,14 +514,20 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
).select_related(*DISPOSITIVO_SELECT_RELATED)
return itens
- def select_provaveis_inserts(self):
+ def select_provaveis_inserts(self, request=None):
try:
+
+ if request and 'perfil_estrutural' not in request.session:
+ self.set_perfil_in_session(request)
+
+ perfil_pk = request.session['perfil_estrutural']
+
# Não salvar d_base
- if self.pk_add == 0:
+ if self.pk_edit == 0:
base = Dispositivo.objects.get(pk=self.pk_view)
else:
- base = Dispositivo.objects.get(pk=self.pk_add)
+ base = Dispositivo.objects.get(pk=self.pk_edit)
prox_possivel = Dispositivo.objects.filter(
ordem__gt=base.ordem,
@@ -444,14 +562,15 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
if dp.nivel >= nivel:
continue
- if dp.is_relative_auto_insert():
+ if dp.is_relative_auto_insert(perfil_pk):
continue
if prox_possivel and \
dp.tipo_dispositivo != base.tipo_dispositivo and\
dp.nivel < prox_possivel.nivel and\
not prox_possivel.tipo_dispositivo.permitido_inserir_in(
- dp.tipo_dispositivo):
+ dp.tipo_dispositivo,
+ perfil_pk=perfil_pk):
if dp.tipo_dispositivo != prox_possivel.tipo_dispositivo:
continue
@@ -469,6 +588,13 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
dp.tipo_dispositivo.nome,),
'dispositivo_base': base.pk})
+ if dp.dispositivo_pai:
+ flag_pv = dp.tipo_dispositivo.permitido_variacao(
+ dp.dispositivo_pai.tipo_dispositivo,
+ perfil_pk=perfil_pk)
+ else:
+ flag_pv = False
+
r = []
flag_direcao = 1
flag_variacao = 0
@@ -491,8 +617,12 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
'dispositivo_base': base.pk})
flag_direcao = -1
+
r.reverse()
+ if not flag_pv:
+ r = [r[0], ]
+
if len(r) > 0 and dp.tipo_dispositivo.formato_variacao0 == \
TipoDispositivo.FNCN:
r = [r[0], ]
@@ -530,7 +660,9 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
for td in otds:
if paradentro and not td.permitido_inserir_in(
- tipb, excluir_autos=True):
+ tipb,
+ include_relative_autos=False,
+ perfil_pk=perfil_pk):
continue
base.tipo_dispositivo = td
@@ -540,29 +672,32 @@ class DispositivoEditView(CompilacaoEditView, FormMixin):
flag_insercao = False
for possivelpai in parents:
if td.permitido_inserir_in(
- possivelpai.tipo_dispositivo,
- excluir_autos=True):
+ possivelpai.tipo_dispositivo,
+ include_relative_autos=False,
+ perfil_pk=perfil_pk):
flag_insercao = True
break
if not flag_insercao:
continue
- if possivelpai.is_relative_auto_insert():
+ if possivelpai.is_relative_auto_insert(perfil_pk):
continue
if prox_possivel:
if prox_possivel.nivel == base.nivel:
if prox_possivel.tipo_dispositivo != td and\
not prox_possivel.tipo_dispositivo.\
- permitido_inserir_in(td):
+ permitido_inserir_in(
+ td, perfil_pk=perfil_pk):
continue
else:
if possivelpai.tipo_dispositivo != \
prox_possivel.tipo_dispositivo and\
not prox_possivel.tipo_dispositivo.\
permitido_inserir_in(
- possivelpai.tipo_dispositivo) and \
+ possivelpai.tipo_dispositivo,
+ perfil_pk=perfil_pk) and \
possivelpai.nivel < \
prox_possivel.nivel:
continue
@@ -610,17 +745,33 @@ class ActionsEditMixin(object):
def render_to_json_response(self, context, **response_kwargs):
- if context['action'] == 'add_next':
- return JsonResponse(self.add_next(context), safe=False)
- elif context['action'] == 'add_in':
- return JsonResponse(self.add_in(context), safe=False)
- elif context['action'] == 'add_prior':
- return JsonResponse(self.add_prior(context), safe=False)
+ test = getattr(self, context['action'])
+ return JsonResponse(test(context), safe=False)
+
+ def delete_item_dispositivo(self, context):
+ return self.delete_bloco_dispositivo(context)
+
+ def delete_bloco_dispositivo(self, context):
+ base = Dispositivo.objects.get(pk=context['dispositivo_id'])
+
+ base_anterior = Dispositivo.objects.order_by('-ordem').filter(
+ norma_id=base.norma_id,
+ ordem__lt=base.ordem
+ )[:1]
+ base.delete()
+
+ if base_anterior.exists():
+ if base_anterior[0].dispositivo_pai_id:
+ data = {'pk': base_anterior[0].pk, 'pai': [
+ base_anterior[0].dispositivo_pai_id, ]}
+ else:
+ data = {'pk': base_anterior[0].pk, 'pai': [-1, ]}
+ return data
else:
- return JsonResponse({}, safe=False)
+ return {}
def add_prior(self, context):
- pass
+ return {}
def add_in(self, context):
return self.add_next(context, local_add='add_in')
@@ -637,7 +788,7 @@ class ActionsEditMixin(object):
count_auto_insert = 0
for tipoauto in tipos_dp_auto_insert:
- qtdp = tipoauto.filho_permitido.quantidade_permitida
+ qtdp = tipoauto.quantidade_permitida
if qtdp >= 0:
qtdp -= Dispositivo.objects.filter(
norma_id=base.norma_id,
@@ -657,7 +808,9 @@ class ActionsEditMixin(object):
if dp.tipo_dispositivo == tipo:
dp_irmao = dp
break
- if tipo.permitido_inserir_in(dp.tipo_dispositivo):
+ if tipo.permitido_inserir_in(
+ dp.tipo_dispositivo,
+ perfil_pk=context['perfil_pk']):
dp_pai = dp
break
dp_pai = dp
@@ -723,30 +876,33 @@ class ActionsEditMixin(object):
antes da inserção atual e que são inferiores a dp,
redirecionando para o novo pai'''
- possiveis_filhos = Dispositivo.objects.filter(
- ordem__gt=dp.ordem,
- norma_id=dp.norma_id)
-
nivel = sys.maxsize
flag_niveis = False
- for filho in possiveis_filhos:
- if filho.nivel > nivel:
- continue
+ if not dp.tipo_dispositivo.dispositivo_de_alteracao:
+ possiveis_filhos = Dispositivo.objects.filter(
+ ordem__gt=dp.ordem,
+ norma_id=dp.norma_id)
- if filho.dispositivo_pai.ordem >= dp.ordem:
- continue
+ for filho in possiveis_filhos:
- nivel = filho.nivel
+ if filho.nivel > nivel:
+ continue
- if not filho.tipo_dispositivo.permitido_inserir_in(
- dp.tipo_dispositivo):
- continue
+ if filho.dispositivo_pai.ordem >= dp.ordem:
+ continue
- filho.dispositivo_pai = dp
- filho.clean()
- filho.save()
- flag_niveis = True
+ nivel = filho.nivel
+
+ if not filho.tipo_dispositivo.permitido_inserir_in(
+ dp.tipo_dispositivo,
+ perfil_pk=context['perfil_pk']):
+ continue
+
+ filho.dispositivo_pai = dp
+ filho.clean()
+ filho.save()
+ flag_niveis = True
if flag_niveis:
dp.organizar_niveis()
@@ -795,7 +951,7 @@ class ActionsEditMixin(object):
contagem continua, caso a inserção seja uma articulação'''
numtipos = {}
- if tipo.class_css == 'articulacao':
+ if dp.nivel == 0:
proxima_articulacao = Dispositivo.objects.filter(
ordem__gt=dp.ordem,
@@ -894,6 +1050,14 @@ class ActionsEditView(ActionsEditMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
context['action'] = self.request.GET['action']
- context['tipo_pk'] = self.request.GET['tipo_pk']
- context['variacao'] = self.request.GET['variacao']
+
+ if 'tipo_pk' in self.request.GET:
+ context['tipo_pk'] = self.request.GET['tipo_pk']
+
+ if 'variacao' in self.request.GET:
+ context['variacao'] = self.request.GET['variacao']
+
+ if 'perfil_estrutural' in self.request.session:
+ context['perfil_pk'] = self.request.session['perfil_estrutural']
+
return self.render_to_json_response(context, **response_kwargs)
diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index 80547dc4c..7d7abaf98 100644
--- a/requirements/requirements.txt
+++ b/requirements/requirements.txt
@@ -9,6 +9,7 @@ django-crispy-forms
django-extra-views
django-vanilla-views
git+git://github.com/interlegis/django-sass-processor.git
+git+git://github.com/LeandroRoberto/odfpy.git
libsass
psycopg2
pytz
diff --git a/static/js/compilacao.js b/static/js/compilacao.js
index f5ff95468..30e8551a0 100644
--- a/static/js/compilacao.js
+++ b/static/js/compilacao.js
@@ -63,12 +63,14 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
var _action = __action;
var _variacao = '';
var _tipo_pk = '';
+ var _perfil_pk = '';
if (event != null) {
pk_refresh = event.currentTarget.getAttribute('pk');
_action = $(this).attr('action');
_variacao = $(this).attr('variacao');
_tipo_pk = $(this).attr('tipo_pk');
+ _perfil_pk = $(this).attr('perfil_pk');
}
if (pk_edit == null)
@@ -78,20 +80,22 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
if (_action == '')
return;
else if ( _action == null) {
- url = pk_refresh+'/refresh?pkadd='+pk_edit;
+ url = pk_refresh+'/refresh?edit='+pk_edit;
}
else if (_action.startsWith('refresh')) {
-
var str = _action.split(':');
if (str.length > 1) {
- editortype = str[1];
- SetCookie("editortype", editortype, 30)
-
+ if(_action.endsWith('perfil')) {
+ url = '&perfil_pk='+_perfil_pk;
+ }
+ else {
+ editortype = str[1];
+ SetCookie("editortype", editortype, 30)
+ }
}
- url = pk_refresh+'/refresh?pkadd='+pk_edit+url;
- $("#message_block").css("display", "block");
+ url = pk_refresh+'/refresh?edit='+pk_edit+url;
}
- else {
+ else if (_action.startsWith('add_')) {
url = pk_refresh+'/actions?action='+_action;
url += '&tipo_pk='+_tipo_pk;
@@ -100,11 +104,14 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
$("#message_block").css("display", "block");
}
+ else if (_action.startsWith('delete_')) {
+ url = pk_refresh+'/actions?action='+_action;
+ $("#message_block").css("display", "block");
+ }
$.get(url).done(function( data ) {
if ( _action == null || _action.startsWith('refresh')) {
-
if (flag_refresh_all) {
if (flag_actions_vibible)
clearEditSelected();
@@ -165,6 +172,16 @@ var clickUpdateDispositivo = function(event, __pk_refresh, __pk_edit, __action,
alert('Erro na inserção!');
}
}
+ else if (_action.startsWith('delete_')) {
+ $("#message_block").css("display", "block");
+ clearEditSelected();
+ if (data.pk != null) {
+ refreshScreenFocusPk(data);
+ }
+ else {
+ alert('Erro exclusão!');
+ }
+ }
else {
clearEditSelected();
reloadFunctionClicks();
@@ -196,11 +213,11 @@ function clearEditSelected() {
}
function reloadFunctionClicks() {
- $('.dpt .de, .btn-action, .btn-inserts, .btn-edit').off();
+ $('.dpt .de, .btn-action, .btn-edit').off();
$('.dpt .de, .btn-edit').on('click', clickEditDispositivo);
- $('.btn-action, .btn-inserts').on('click', clickUpdateDispositivo);
+ $('.btn-action').on('click', clickUpdateDispositivo);
$('#editdi_texto').focus();
}
diff --git a/static/styles/compilacao.scss b/static/styles/compilacao.scss
index ddd0c06f6..c1ca8d044 100644
--- a/static/styles/compilacao.scss
+++ b/static/styles/compilacao.scss
@@ -17,6 +17,7 @@ $color_actions_border: #CCC;
border-radius: $radius;
}
+
@mixin li_flutuante() {
& > ul {
@@ -34,19 +35,26 @@ $color_actions_border: #CCC;
a {
border-right: 0px !important;
}
- }
- &::before {
- border-width: 0.375rem;
- border-style: inset inset solid;
- content: "";
- display: block;
- height: 0px;
- width: 0px;
- border-color: transparent transparent #3385CA;
- position: absolute;
- top: -0.75rem;
- left: 0.9375rem;
+
+ &:first-child {
+
+ &::before {
+ border-width: 0.375rem;
+ border-style: inset inset solid;
+ content: "";
+ display: block;
+ height: 0px;
+ width: 0px;
+ border-color: transparent transparent #3385CA;
+ position: absolute;
+ top: -0.75rem;
+ left: 0.9375rem;
+ }
+ &:hover::before {
+ border-color: transparent transparent #0A5EA4;
+ }
+ }
}
// This bridges the gap between the top bar and a dropdown.
&::after {
@@ -74,7 +82,9 @@ $color_actions_border: #CCC;
}
}
-
+.test_import:nth-child(even) {
+ background-color: #ccc;
+}
#message_block {
display: block;
position: fixed;
@@ -267,7 +277,31 @@ $color_actions_border: #CCC;
}
.fixed{
+
z-index:98;
+ opacity: 0.2;
+ transition: all 2s ease-in-out;
+ -webkit-transition-delay: 3s; /* Safari */
+ transition-delay: 3s;
+
+ &:hover {
+ -webkit-transition-delay: 0s; /* Safari */
+ transition-delay: 0s;
+ transition: all 0.3s ease-in-out;
+ opacity: 0.9;
+
+ &::-webkit-scrollbar {
+ width: 10px;
+ height: 10px;
+ }
+
+
+ &::-webkit-scrollbar-thumb:vertical {
+ height: 30px;
+ background-color: rgba(0, 0, 0, 0.1);
+ }
+
+ }
}
} /* end cp */
@@ -297,7 +331,7 @@ $color_actions_border: #CCC;
& > .actions_left {
color: #fff;
position: absolute;
- left: -2em;
+ left: -2.6em;
opacity: 0;
transition: all 0.4s ease-in-out;
a {
@@ -360,13 +394,10 @@ $color_actions_border: #CCC;
@extend .articulacao;
margin: 0;
padding-top: 3em;
+ padding-left: 0em;
background: #ddd;
&::before {
content: "Bloco de Alteração";
- position:absolute;
- left: 0;
- right: 0;
- top: 0;
display: block;
}
@@ -407,11 +438,6 @@ $color_actions_border: #CCC;
}
- .bloco_alteracao {
- &::before {
- display: none;
- }
- }
& > .bloco {
padding: 1em 0;
@@ -466,7 +492,6 @@ $color_actions_border: #CCC;
& > a {
text-shadow: 0 0 5px #777;
color: #ff0;
- font-weight: bold;
}
}
}
@@ -661,14 +686,16 @@ $color_actions_border: #CCC;
}
&.add_prior {
@include li_flutuante();
- display: block;
+ table-layout: fixed;
}
&.opc_excluir {
@include li_flutuante();
- display: block;
+ table-layout: fixed;
+ position: static;
& > ul {
+ right: 0.5em;
li {
a {
background-color: #A70808;
@@ -676,10 +703,16 @@ $color_actions_border: #CCC;
background: #c70808;
}
}
- }
-
- &::before {
- border-color: transparent transparent #A70808;
+ &:first-child {
+ &::before {
+ border-color: transparent transparent #A70808;
+ right: 10%;
+ left: auto;
+ }
+ &:hover::before {
+ border-color: transparent transparent #c70808;
+ }
+ }
}
}
@@ -692,6 +725,21 @@ $color_actions_border: #CCC;
.menu_flutuante {
& > li {
@include li_flutuante();
+
+
+ &.opc_excluir {
+ & > ul {
+ li {
+ &:first-child {
+ &::before {
+ right: auto;
+ left: 0.9375rem;
+ }
+ }
+ }
+ }
+
+ }
}
}
@@ -803,7 +851,7 @@ $color_actions_border: #CCC;
left: 1em !important;
right: 1em !important;
margin-left: 0;
- &::before {
+ li:first-child::before {
left: 37%;
}
}
@@ -816,18 +864,18 @@ $color_actions_border: #CCC;
right: 0 !important;
margin-left: 0;
margin-right: 0.5em;
- &::before {
+ li:first-child::before {
right: 42%;
left: auto;
}
}
&.opc_excluir > ul {
- left: 30% !important;
+ left: 10% !important;
right: 0 !important;
margin-left: 0;
margin-right: 0.5em;
- &::before {
- right: 35%;
+ li:first-child::before {
+ right: 27%;
left: auto;
}
}
diff --git a/templates/compilacao/edit.html b/templates/compilacao/edit.html
index acc76a8ad..5781ca373 100644
--- a/templates/compilacao/edit.html
+++ b/templates/compilacao/edit.html
@@ -3,6 +3,8 @@
{% load compilacao_filters %}
{% load staticfiles %}
{% load sass_tags %}
+{% load crispy_forms_tags %}
+
{% block head_content %}{{block.super}}
@@ -22,4 +24,33 @@
{% include 'compilacao/edit_bloco.html'%}
+
+{% if user.is_authenticated and False %}
+
+
+{% for parser in parser_list %}
+
+ {{ parser|safe}}
+
+{% endfor %}
+{% endif%}
+
+
+
{% endblock base_content %}
diff --git a/templates/compilacao/edit_bloco.html b/templates/compilacao/edit_bloco.html
index e0aa78341..5febac519 100644
--- a/templates/compilacao/edit_bloco.html
+++ b/templates/compilacao/edit_bloco.html
@@ -35,40 +35,40 @@
-
-
- BB
- BB
+
@@ -97,11 +97,13 @@
{% endif%}
- {% if view.pk_view == 0 and view.pk_add == 0 or view.pk_add != view.pk_view %}
-
+ {% if view.pk_view == 0 and view.pk_edit == 0 or view.pk_edit != view.pk_view %}
+ {% if not dpt.rotulo and not dpt.texto %}
+
+ {% endif %}