diff --git a/src/c3nav/editor/models/change.py b/src/c3nav/editor/models/change.py
index 22c29b20..6691791b 100644
--- a/src/c3nav/editor/models/change.py
+++ b/src/c3nav/editor/models/change.py
@@ -6,10 +6,10 @@ from django.apps import apps
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models
-from django.db.models import Q, FieldDoesNotExist
+from django.db.models import FieldDoesNotExist, Q
from django.utils.translation import ugettext_lazy as _
-from c3nav.editor.utils import is_created_pk, get_current_obj
+from c3nav.editor.utils import get_current_obj, is_created_pk
from c3nav.editor.wrappers import ModelInstanceWrapper
@@ -214,6 +214,47 @@ class Change(models.Model):
return True
+ def check_has_no_effect(self):
+ if self.discarded_by_id is not None or self.action in ('create', 'restore'):
+ return False
+
+ if self.action == 'delete':
+ if is_created_pk(self.obj_pk):
+ return False
+
+ try:
+ current_obj = get_current_obj(self.model_class, self.obj_pk)
+ except (LookupError, ObjectDoesNotExist):
+ return not is_created_pk(self.obj_pk)
+
+ if self.action == 'delete':
+ return False
+
+ if self.field_name.startswith('title_'):
+ return self.field_value == current_obj.titles.get(self.field_name[6:], '')
+
+ try:
+ field = self.field
+ except FieldDoesNotExist:
+ return True
+
+ if self.action == 'update':
+ if field.many_to_one:
+ return self.field_value == getattr(current_obj, field.attname)
+ if field.is_relation:
+ raise NotImplementedError
+ return self.field_value == field.get_prep_value(getattr(current_obj, field.name))
+
+ if self.action == 'm2m_add':
+ if is_created_pk(self.field_value):
+ return False
+ return getattr(current_obj, field.name).filter(pk=self.field_value).exists()
+
+ if self.action == 'm2m_remove':
+ if is_created_pk(self.field_value):
+ return True
+ return not getattr(current_obj, field.name).filter(pk=self.field_value).exists()
+
def save(self, *args, **kwargs):
if self.pk is not None:
raise TypeError('change objects can not be edited (use update to set discarded_by)')
diff --git a/src/c3nav/editor/static/editor/css/editor.css b/src/c3nav/editor/static/editor/css/editor.css
index 2f9b2cee..4a9edd29 100644
--- a/src/c3nav/editor/static/editor/css/editor.css
+++ b/src/c3nav/editor/static/editor/css/editor.css
@@ -171,16 +171,22 @@ form button.invisiblesubmit {
.change-group tr td:last-child .btn {
margin-top: -6px;
margin-bottom: -2px;
- margin-right: -5px;
margin-left: 5px;
+ margin-right: -3px;
+}
+.change-group tr td:last-child .btn:last-child {
+ margin-right: -5px;
}
.change-group .glyphicon-share-alt {
transform: scale(-1, 1);
-webkit-transform: scale(-1, 1);
}
-.change-group tr td:last-child>i {
+.change-group tr td:last-child>i:last-child {
margin-right: -2px;
}
+.change-group tr td:last-child>i {
+ margin-left: 5px;
+}
/* Styles inside leaflet */
.leaflet-container {
diff --git a/src/c3nav/editor/templates/editor/fragment_change_groups.html b/src/c3nav/editor/templates/editor/fragment_change_groups.html
index 91b68def..e7920192 100644
--- a/src/c3nav/editor/templates/editor/fragment_change_groups.html
+++ b/src/c3nav/editor/templates/editor/fragment_change_groups.html
@@ -35,14 +35,14 @@
{% if change.author and change.author != changeset.author %}
{% endif %}
- {% if change.created %}
-
- {% endif %}
{% if change.can_restore %}
{% endif %}
+ {% if change.created %}
+
+ {% endif %}
{% endfor %}
diff --git a/src/c3nav/editor/views/changes.py b/src/c3nav/editor/views/changes.py
index 39f0e20f..a3aac488 100644
--- a/src/c3nav/editor/views/changes.py
+++ b/src/c3nav/editor/views/changes.py
@@ -121,17 +121,14 @@ def group_changes(changeset, can_edit=False, show_history=False):
'pk': change.pk,
'author': change.author,
'discarded': change.discarded_by_id is not None,
+ 'apply_problem': change.check_apply_problem(),
+ 'has_no_effect': change.check_has_no_effect(),
+ 'can_restore': change.can_restore,
}
if show_history:
change_data.update({
'created': _('created at %(datetime)s') % {'datetime': date_format(change.created, 'DATETIME_FORMAT')},
})
- else:
- change_data.update({
- 'apply_problem': change.check_apply_problem(),
- 'has_no_effect': change.check_has_no_effect(),
- 'can_restore': change.can_restore,
- })
changes.append(change_data)
if change.action == 'create':