diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties index fe1b86a1518b8bb0aea656fdc4cd3760f2e43108..6c4967be0b07e3750b9d001abcb2499c678a85ee 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties @@ -19,6 +19,7 @@ configuration.overview=\u00DCbersicht Testkonfiguration configuration.option.yes=Ja configuration.option.no=Nein configuration.option.inherited=Vererbt +configuration.option.inherited.val=Vererbt ({0}) convert=Konvertieren convert.alien=Konvertieren convert.to=Umwandeln in\: diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties index 72aa63094f3292d28c9b1f87d90cca63dec2bfb2..402e824fbc0f2095d91c2b3c213fa72e3a65a907 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties @@ -19,6 +19,7 @@ configuration.overview=Test configuration overview configuration.option.yes=Yes configuration.option.no=No configuration.option.inherited=Inherited +configuration.option.inherited.val=Inherited ({0}) convert=Convert convert.alien=Convert convert.to=Convert to\: diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/overview/ControlObjectRow.java b/src/main/java/org/olat/ims/qti21/ui/editor/overview/ControlObjectRow.java index 52fa818358f8db798ffa8c233d84a5d7001b974f..bdf55a05b2dc1ab19166e2197601f9c14792fec7 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/overview/ControlObjectRow.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/overview/ControlObjectRow.java @@ -24,6 +24,7 @@ import java.util.List; import org.olat.ims.qti21.model.QTI21QuestionType; import org.olat.ims.qti21.model.xml.QtiNodesExtractor; +import uk.ac.ed.ph.jqtiplus.node.QtiNode; import uk.ac.ed.ph.jqtiplus.node.item.AssessmentItem; import uk.ac.ed.ph.jqtiplus.node.test.AbstractPart; import uk.ac.ed.ph.jqtiplus.node.test.AssessmentItemRef; @@ -49,10 +50,10 @@ public class ControlObjectRow { private Boolean feedbacks; private QTI21QuestionType type; - private OptionEnum review; - private OptionEnum comment; - private OptionEnum skipping; - private OptionEnum solution; + private OptionAndInheritance review; + private OptionAndInheritance comment; + private OptionAndInheritance skipping; + private OptionAndInheritance solution; private MaxAttemptOption attemptOption; public ControlObjectRow(String title, ControlObject<?> part, String iconCssClass) { @@ -127,46 +128,108 @@ public class ControlObjectRow { if(maxAttempts != null) { OptionEnum option = (maxAttempts.intValue() == 0 ? OptionEnum.no : OptionEnum.yes); row.attemptOption = MaxAttemptOption.valueOf(option, maxAttempts); + } else if(part instanceof TestPart) { + row.attemptOption = MaxAttemptOption.valueOf(OptionEnum.no, Integer.valueOf(1)); } else { - OptionEnum option = (part instanceof TestPart) ? OptionEnum.no : OptionEnum.inherited; - row.attemptOption = MaxAttemptOption.valueOf(option, Integer.valueOf(1)); + Integer inheritedMaxAttempts = inheritedAttempts(part); + row.attemptOption = MaxAttemptOption.valueOf(OptionEnum.inherited, inheritedMaxAttempts); } } + private static Integer inheritedAttempts(AbstractPart part) { + for(QtiNode parent=part.getParent(); parent != null; parent=parent.getParent()) { + if(parent instanceof AbstractPart) { + ItemSessionControl itemSessionControl = ((AbstractPart)parent).getItemSessionControl(); + if(itemSessionControl != null && itemSessionControl.getMaxAttempts() != null) { + return itemSessionControl.getMaxAttempts(); + } + } + } + return Integer.valueOf(1); + } + private static void skipping(ControlObjectRow row, AbstractPart part) { ItemSessionControl itemSessionControl = part.getItemSessionControl(); if(itemSessionControl != null && itemSessionControl.getAllowSkipping() != null) { - row.skipping = itemSessionControl.getAllowSkipping().booleanValue() ? OptionEnum.yes : OptionEnum.no; + row.skipping = itemSessionControl.getAllowSkipping().booleanValue() ? OptionAndInheritance.yes() : OptionAndInheritance.no(); } else { - row.skipping = (part instanceof TestPart) ? OptionEnum.yes : OptionEnum.inherited; + row.skipping = (part instanceof TestPart) ? OptionAndInheritance.yes() : OptionAndInheritance.inherited(inheritedSkipping(part)); + } + } + + private static OptionEnum inheritedSkipping(AbstractPart part) { + for(QtiNode parent=part.getParent(); parent != null; parent=parent.getParent()) { + if(parent instanceof AbstractPart) { + ItemSessionControl itemSessionControl = ((AbstractPart)parent).getItemSessionControl(); + if(itemSessionControl != null && itemSessionControl.getAllowSkipping() != null) { + return itemSessionControl.getAllowSkipping().booleanValue() ? OptionEnum.yes : OptionEnum.no; + } + } } + return OptionEnum.yes; } private static void comment(ControlObjectRow row, AbstractPart part) { ItemSessionControl itemSessionControl = part.getItemSessionControl(); if(itemSessionControl != null && itemSessionControl.getAllowComment() != null) { - row.comment = itemSessionControl.getAllowComment().booleanValue() ? OptionEnum.yes : OptionEnum.no; + row.comment = itemSessionControl.getAllowComment().booleanValue() ? OptionAndInheritance.yes() : OptionAndInheritance.no(); } else { - row.comment = (part instanceof TestPart) ? OptionEnum.yes : OptionEnum.inherited; + row.comment = (part instanceof TestPart) ? OptionAndInheritance.yes() : OptionAndInheritance.inherited(inheritedComment(part)); } } + private static OptionEnum inheritedComment(AbstractPart part) { + for(QtiNode parent=part.getParent(); parent != null; parent=parent.getParent()) { + if(parent instanceof AbstractPart) { + ItemSessionControl itemSessionControl = ((AbstractPart)parent).getItemSessionControl(); + if(itemSessionControl != null && itemSessionControl.getAllowComment() != null) { + return itemSessionControl.getAllowComment().booleanValue() ? OptionEnum.yes : OptionEnum.no; + } + } + } + return OptionEnum.yes; + } + private static void review(ControlObjectRow row, AbstractPart part) { ItemSessionControl itemSessionControl = part.getItemSessionControl(); if(itemSessionControl != null && itemSessionControl.getAllowReview() != null) { - row.review = itemSessionControl.getAllowReview().booleanValue() ? OptionEnum.yes : OptionEnum.no; + row.review = itemSessionControl.getAllowReview().booleanValue() ? OptionAndInheritance.yes() : OptionAndInheritance.no(); } else { - row.review = (part instanceof TestPart) ? OptionEnum.no : OptionEnum.inherited; + row.review = (part instanceof TestPart) ? OptionAndInheritance.no() : OptionAndInheritance.inherited(inheritedReview(part)); + } + } + + private static OptionEnum inheritedReview(AbstractPart part) { + for(QtiNode parent=part.getParent(); parent != null; parent=parent.getParent()) { + if(parent instanceof AbstractPart) { + ItemSessionControl itemSessionControl = ((AbstractPart)parent).getItemSessionControl(); + if(itemSessionControl != null && itemSessionControl.getAllowReview() != null) { + return itemSessionControl.getAllowReview().booleanValue() ? OptionEnum.yes : OptionEnum.no; + } + } } + return OptionEnum.no; } private static void solution(ControlObjectRow row, AbstractPart part) { ItemSessionControl itemSessionControl = part.getItemSessionControl(); if(itemSessionControl != null && itemSessionControl.getShowSolution() != null) { - row.solution = itemSessionControl.getShowSolution().booleanValue() ? OptionEnum.yes : OptionEnum.no; + row.solution = itemSessionControl.getShowSolution().booleanValue() ? OptionAndInheritance.yes() : OptionAndInheritance.no(); } else { - row.solution = (part instanceof TestPart) ? OptionEnum.no : OptionEnum.inherited; + row.solution = (part instanceof TestPart) ? OptionAndInheritance.no() : OptionAndInheritance.inherited(inheritedSolution(part)); + } + } + + private static OptionEnum inheritedSolution(AbstractPart part) { + for(QtiNode parent=part.getParent(); parent != null; parent=parent.getParent()) { + if(parent instanceof AbstractPart) { + ItemSessionControl itemSessionControl = ((AbstractPart)parent).getItemSessionControl(); + if(itemSessionControl != null && itemSessionControl.getShowSolution() != null) { + return itemSessionControl.getShowSolution().booleanValue() ? OptionEnum.yes : OptionEnum.no; + } + } } + return OptionEnum.no; } public String getTitle() { @@ -201,19 +264,19 @@ public class ControlObjectRow { return feedbacks; } - public OptionEnum getSkipping() { + public OptionAndInheritance getSkipping() { return skipping; } - public OptionEnum getComment() { + public OptionAndInheritance getComment() { return comment; } - public OptionEnum getReview() { + public OptionAndInheritance getReview() { return review; } - public OptionEnum getSolution() { + public OptionAndInheritance getSolution() { return solution; } diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/overview/MaxAttemptsCellRenderer.java b/src/main/java/org/olat/ims/qti21/ui/editor/overview/MaxAttemptsCellRenderer.java index f493aaeb508f8d398eb42da5def176834519850b..59afa46e34395b356c0748c0123019918293addc 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/overview/MaxAttemptsCellRenderer.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/overview/MaxAttemptsCellRenderer.java @@ -45,8 +45,9 @@ public class MaxAttemptsCellRenderer extends OptionCellRenderer { OptionEnum option = attempts.getOption(); if(option == OptionEnum.yes) { target.append(attempts.getMaxAttempts()); - } else { - super.render(renderer, target, option, row, source, ubu, trans); + } else if(option == OptionEnum.inherited && attempts.getMaxAttempts() != null && attempts.getMaxAttempts().intValue() > 0) { + String val = attempts.getMaxAttempts().toString(); + target.append(translator.translate("configuration.option.inherited.val", new String[] { val })); } } } diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionAndInheritance.java b/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionAndInheritance.java new file mode 100644 index 0000000000000000000000000000000000000000..6cccff66e5f86d2c37c740bca62096019e315867 --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionAndInheritance.java @@ -0,0 +1,57 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.ims.qti21.ui.editor.overview; + +/** + * + * Initial date: 7 févr. 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class OptionAndInheritance { + + private final OptionEnum option; + private final OptionEnum inheritedValue; + + private OptionAndInheritance(OptionEnum option, OptionEnum inheritedValue) { + this.option = option; + this.inheritedValue = inheritedValue; + } + + public static OptionAndInheritance yes() { + return new OptionAndInheritance(OptionEnum.yes, null); + } + + public static OptionAndInheritance no() { + return new OptionAndInheritance(OptionEnum.no, null); + } + + public static OptionAndInheritance inherited(OptionEnum inheritedValue) { + return new OptionAndInheritance(OptionEnum.inherited, inheritedValue); + } + + public OptionEnum getOption() { + return option; + } + + public OptionEnum getInheritedValue() { + return inheritedValue; + } +} diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionCellRenderer.java b/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionCellRenderer.java index 63555d8dcde51f65dddf879c3221ee45f7c49b67..8d8f9a5d735f16b4a29f67b2517720095d9a3e9e 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionCellRenderer.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/overview/OptionCellRenderer.java @@ -34,7 +34,7 @@ import org.olat.core.gui.translator.Translator; */ public class OptionCellRenderer implements FlexiCellRenderer { - private final Translator translator; + protected final Translator translator; public OptionCellRenderer(Translator translator) { this.translator = translator; @@ -43,9 +43,14 @@ public class OptionCellRenderer implements FlexiCellRenderer { @Override public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, URLBuilder ubu, Translator trans) { - if(cellValue instanceof OptionEnum) { - OptionEnum option = (OptionEnum)cellValue; - target.append(translator.translate("configuration.option.".concat(option.name()))); + if(cellValue instanceof OptionAndInheritance) { + OptionAndInheritance option = (OptionAndInheritance)cellValue; + if(option.getOption() == OptionEnum.inherited && option.getInheritedValue() != null) { + String val = translator.translate("configuration.option.".concat(option.getInheritedValue().name())); + target.append(translator.translate("configuration.option.inherited.val", new String[] { val })); + } else { + target.append(translator.translate("configuration.option.".concat(option.getOption().name()))); + } } } }