|
@@ -1,9 +1,22 @@
|
|
|
from django import forms
|
|
|
+from django.urls import reverse
|
|
|
+from django.utils.safestring import mark_safe
|
|
|
from django.utils.translation import gettext_lazy, ngettext
|
|
|
|
|
|
from wagtail.core.models import Locale, Page
|
|
|
|
|
|
|
|
|
+class CheckboxSelectMultipleWithDisabledOptions(forms.CheckboxSelectMultiple):
|
|
|
+ option_template_name = "simple_translation/admin/input_option.html"
|
|
|
+ disabled_values = []
|
|
|
+
|
|
|
+ def create_option(self, *args, **kwargs):
|
|
|
+ option = super().create_option(*args, **kwargs)
|
|
|
+ if option["value"] in self.disabled_values:
|
|
|
+ option["attrs"]["disabled"] = True
|
|
|
+ return option
|
|
|
+
|
|
|
+
|
|
|
class SubmitTranslationForm(forms.Form):
|
|
|
# Note: We don't actually use select_all in Python, it is just the
|
|
|
# easiest way to add the widget to the form. It's controlled in JS.
|
|
@@ -11,7 +24,7 @@ class SubmitTranslationForm(forms.Form):
|
|
|
locales = forms.ModelMultipleChoiceField(
|
|
|
label=gettext_lazy("Locales"),
|
|
|
queryset=Locale.objects.none(),
|
|
|
- widget=forms.CheckboxSelectMultiple,
|
|
|
+ widget=CheckboxSelectMultipleWithDisabledOptions,
|
|
|
)
|
|
|
include_subtree = forms.BooleanField(
|
|
|
required=False, help_text=gettext_lazy("All child pages will be created.")
|
|
@@ -21,6 +34,7 @@ class SubmitTranslationForm(forms.Form):
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
hide_include_subtree = True
|
|
|
+ self.show_submit = True
|
|
|
|
|
|
if isinstance(instance, Page):
|
|
|
descendant_count = instance.get_descendants().count()
|
|
@@ -36,13 +50,69 @@ class SubmitTranslationForm(forms.Form):
|
|
|
if hide_include_subtree:
|
|
|
self.fields["include_subtree"].widget = forms.HiddenInput()
|
|
|
|
|
|
- self.fields["locales"].queryset = Locale.objects.exclude(
|
|
|
+ untranslated_locales = Locale.objects.exclude(
|
|
|
id__in=instance.get_translations(inclusive=True).values_list(
|
|
|
"locale_id", flat=True
|
|
|
)
|
|
|
)
|
|
|
+ self.fields["locales"].queryset = untranslated_locales
|
|
|
|
|
|
+ # For snippets, hide select all if there is one option.
|
|
|
# Using len() instead of count() here as we're going to evaluate this queryset
|
|
|
# anyway and it gets cached so it'll only have one query in the end.
|
|
|
- if len(self.fields["locales"].queryset) < 2:
|
|
|
+ hide_select_all = len(untranslated_locales) < 2
|
|
|
+
|
|
|
+ if isinstance(instance, Page):
|
|
|
+ parent = instance.get_parent()
|
|
|
+
|
|
|
+ # Find allowed locale options.
|
|
|
+ if parent.is_root():
|
|
|
+ # All locale options are allowed.
|
|
|
+ allowed_locale_ids = Locale.objects.all().values_list("id", flat=True)
|
|
|
+ else:
|
|
|
+ # Only the locale options that have a translated parent are allowed.
|
|
|
+ allowed_locale_ids = (
|
|
|
+ instance.get_parent()
|
|
|
+ .get_translations(inclusive=True)
|
|
|
+ .values_list("locale_id", flat=True)
|
|
|
+ )
|
|
|
+
|
|
|
+ # Get and set the locale options that are disabled.
|
|
|
+ disabled_locales = Locale.objects.exclude(
|
|
|
+ id__in=allowed_locale_ids
|
|
|
+ ).values_list("id", flat=True)
|
|
|
+ self.fields["locales"].widget.disabled_values = disabled_locales
|
|
|
+
|
|
|
+ if disabled_locales:
|
|
|
+ # Display a help text.
|
|
|
+ url = reverse(
|
|
|
+ "simple_translation:submit_page_translation", args=[parent.id]
|
|
|
+ )
|
|
|
+ help_text = ngettext(
|
|
|
+ "A locale is disabled because a parent page is not translated.",
|
|
|
+ "Some locales are disabled because some parent pages are not translated.",
|
|
|
+ len(disabled_locales),
|
|
|
+ )
|
|
|
+ help_text += "<br>"
|
|
|
+ help_text += '<a href="{}">'.format(url)
|
|
|
+ help_text += ngettext(
|
|
|
+ "Translate the parent page.",
|
|
|
+ "Translate the parent pages.",
|
|
|
+ len(disabled_locales),
|
|
|
+ )
|
|
|
+ help_text += "</a>"
|
|
|
+ self.fields["locales"].help_text = mark_safe(help_text)
|
|
|
+
|
|
|
+ # For pages, if there is one locale or all locales are disabled.
|
|
|
+ hide_select_all = (
|
|
|
+ len(untranslated_locales) == 1
|
|
|
+ or len(untranslated_locales) - len(disabled_locales) == 0
|
|
|
+ )
|
|
|
+
|
|
|
+ # Hide the submit if all untranslated locales are disabled.
|
|
|
+ # This property is used in the template.
|
|
|
+ if len(untranslated_locales) == len(disabled_locales):
|
|
|
+ self.show_submit = False
|
|
|
+
|
|
|
+ if hide_select_all:
|
|
|
self.fields["select_all"].widget = forms.HiddenInput()
|