diff --git a/src/main/java/org/olat/ims/qti21/manager/archive/interactions/MatchInteractionArchive.java b/src/main/java/org/olat/ims/qti21/manager/archive/interactions/MatchInteractionArchive.java index d56dc018067f28ca3f8ff073cf05b35b0be8da14..f4108c2793238e809ac829b3d7e67a0f18ab1026 100644 --- a/src/main/java/org/olat/ims/qti21/manager/archive/interactions/MatchInteractionArchive.java +++ b/src/main/java/org/olat/ims/qti21/manager/archive/interactions/MatchInteractionArchive.java @@ -45,6 +45,11 @@ import uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.SimpleMatchSet; * */ public class MatchInteractionArchive extends DefaultInteractionArchive { + + private boolean isKPrim(MatchInteraction matchInteraction) { + return matchInteraction.getResponseIdentifier().toString().startsWith("KPRIM_") + || QTI21QuestionType.hasClass(matchInteraction, QTI21Constants.CSS_MATCH_KPRIM); + } @Override public int writeHeader1(AssessmentItem item, Interaction interaction, int itemNumber, int interactionNumber, Row dataRow, int col, OpenXMLWorkbook workbook) { @@ -53,7 +58,9 @@ public class MatchInteractionArchive extends DefaultInteractionArchive { dataRow.addCell(col++, header, workbook.getStyles().getHeaderStyle()); } MatchInteraction matchInteraction = (MatchInteraction)interaction; - int numOfChoices = matchInteraction.getSimpleMatchSets().get(1).getSimpleAssociableChoices().size(); + + boolean kprim = isKPrim(matchInteraction); + int numOfChoices = matchInteraction.getSimpleMatchSets().get(kprim ? 0 : 1).getSimpleAssociableChoices().size(); if(numOfChoices > 0) { col += (numOfChoices - 1); } @@ -64,11 +71,10 @@ public class MatchInteractionArchive extends DefaultInteractionArchive { public int writeHeader2(AssessmentItem item, Interaction interaction, int itemNumber, int interactionNumber, Row dataRow, int col, OpenXMLWorkbook workbook) { MatchInteraction matchInteraction = (MatchInteraction)interaction; - boolean kprim = matchInteraction.getResponseIdentifier().toString().startsWith("KPRIM_") - || QTI21QuestionType.hasClass(matchInteraction, QTI21Constants.CSS_MATCH_KPRIM); + boolean kprim = isKPrim(matchInteraction); String fix = kprim ? "_KP" : "_K"; - int numOfChoices = matchInteraction.getSimpleMatchSets().get(1).getSimpleAssociableChoices().size(); + int numOfChoices = matchInteraction.getSimpleMatchSets().get(kprim ? 0 : 1).getSimpleAssociableChoices().size(); if(numOfChoices > 0) { for(int i=0; i<numOfChoices; i++) { String header = (itemNumber + 1) + fix + (i + 1); @@ -84,89 +90,107 @@ public class MatchInteractionArchive extends DefaultInteractionArchive { public int writeInteractionData(AssessmentItem item, AssessmentResponse response, Interaction interaction, int itemNumber, Row dataRow, int col, OpenXMLWorkbook workbook) { MatchInteraction matchInteraction = (MatchInteraction)interaction; + + boolean kprim = isKPrim(matchInteraction); String stringuifiedResponse = response == null ? null : response.getStringuifiedResponse(); if(!StringHelper.containsNonWhitespace(stringuifiedResponse)) { - col += matchInteraction.getSimpleMatchSets().get(1).getSimpleAssociableChoices().size(); + col += matchInteraction.getSimpleMatchSets().get(kprim ? 0: 1).getSimpleAssociableChoices().size(); + } else if(kprim) { + col = writeKprimData(item, stringuifiedResponse, matchInteraction, dataRow, col, workbook); } else { - boolean kprim = matchInteraction.getResponseIdentifier().toString().startsWith("KPRIM_") - || QTI21QuestionType.hasClass(matchInteraction, QTI21Constants.CSS_MATCH_KPRIM); - - Set<String> correctAnswers = CorrectResponsesUtil.getCorrectDirectPairResponses(item, matchInteraction, false); - List<String> responses = CorrectResponsesUtil.parseResponses(stringuifiedResponse); + col = writeMatchData(item, stringuifiedResponse, matchInteraction, dataRow, col, workbook); + } + return col; + } + + private int writeMatchData(AssessmentItem item, String stringuifiedResponse, MatchInteraction matchInteraction, + Row dataRow, int col, OpenXMLWorkbook workbook) { + + Set<String> correctAnswers = CorrectResponsesUtil.getCorrectDirectPairResponses(item, matchInteraction, false); + List<String> responses = CorrectResponsesUtil.parseResponses(stringuifiedResponse); + + SimpleMatchSet sourceMatchSet = matchInteraction.getSimpleMatchSets().get(0); + SimpleMatchSet targetMatchSet = matchInteraction.getSimpleMatchSets().get(1); + + for(SimpleAssociableChoice choice:targetMatchSet.getSimpleAssociableChoices()) { + String choiceIdentifier = choice.getIdentifier().toString(); + Set<String> choiceResponses = new HashSet<>(); + for(String r:responses) { + if(r.endsWith(choiceIdentifier)) { + choiceResponses.add(r); + } + } - SimpleMatchSet sourceMatchSet = matchInteraction.getSimpleMatchSets().get(0); - SimpleMatchSet targetMatchSet = matchInteraction.getSimpleMatchSets().get(1); + // defined correct answers + Set<String> choiceCorrectAnswers = new HashSet<>(); + for(String a:correctAnswers) { + if(a.endsWith(choiceIdentifier)) { + choiceCorrectAnswers.add(a); + } + } - for(SimpleAssociableChoice choice:targetMatchSet.getSimpleAssociableChoices()) { - String choiceIdentifier = choice.getIdentifier().toString(); + if(!choiceResponses.isEmpty()) { + boolean correct = choiceResponses.containsAll(choiceCorrectAnswers) + && choiceCorrectAnswers.containsAll(choiceResponses); - if(kprim) { - String markerCorrect = choiceIdentifier + " correct"; - String markerWrong = choiceIdentifier + " wrong"; - - boolean isCorrectRight = correctAnswers.contains(markerCorrect); - String rightFlag = isCorrectRight ? markerCorrect : markerWrong; - String wrongFlag = isCorrectRight ? markerWrong : markerCorrect; - - String value = null; - if(stringuifiedResponse.contains(markerCorrect)) { - value = "+"; - } else if(stringuifiedResponse.contains(markerWrong)) { - value = "-"; - } - - - if(stringuifiedResponse.indexOf(rightFlag) >= 0) { - dataRow.addCell(col++, value, workbook.getStyles().getCorrectStyle()); - } else if(stringuifiedResponse.indexOf(wrongFlag) >= 0) { - dataRow.addCell(col++, value, null); - } else { - col++; - } - } else { - Set<String> choiceResponses = new HashSet<>(); - for(String r:responses) { - if(r.endsWith(choiceIdentifier)) { - choiceResponses.add(r); - } - } - - // defined correct answers - Set<String> choiceCorrectAnswers = new HashSet<>(); - for(String a:correctAnswers) { - if(a.endsWith(choiceIdentifier)) { - choiceCorrectAnswers.add(a); - } - } - - if(!choiceResponses.isEmpty()) { - boolean correct = choiceResponses.containsAll(choiceCorrectAnswers) - && choiceCorrectAnswers.containsAll(choiceResponses); - - StringBuilder value = new StringBuilder(64); - for(SimpleAssociableChoice association:sourceMatchSet.getSimpleAssociableChoices()) { - for(String choiceResponse:choiceResponses) { - if(choiceResponse.startsWith(association.getIdentifier().toString())) { - if(value.length() > 0) value.append(", "); - - String val = getContent(association); - if(val != null) { - value.append(val); - } - - } + StringBuilder value = new StringBuilder(64); + for(SimpleAssociableChoice association:sourceMatchSet.getSimpleAssociableChoices()) { + for(String choiceResponse:choiceResponses) { + if(choiceResponse.startsWith(association.getIdentifier().toString())) { + if(value.length() > 0) value.append(", "); + + String val = getContent(association); + if(val != null) { + value.append(val); } + } - - if(correct) { - dataRow.addCell(col++, value.toString(), workbook.getStyles().getCorrectStyle()); - } else { - dataRow.addCell(col++, value.toString(), null); - } - } else { - col++; } } + + if(correct) { + dataRow.addCell(col++, value.toString(), workbook.getStyles().getCorrectStyle()); + } else { + dataRow.addCell(col++, value.toString(), null); + } + } else { + col++; + } + } + + return col; + } + + private int writeKprimData(AssessmentItem item, String stringuifiedResponse, MatchInteraction matchInteraction, + Row dataRow, int col, OpenXMLWorkbook workbook) { + + Set<String> correctAnswers = CorrectResponsesUtil.getCorrectDirectPairResponses(item, matchInteraction, false); + + SimpleMatchSet sourceMatchSet = matchInteraction.getSimpleMatchSets().get(0); + + for(SimpleAssociableChoice choice:sourceMatchSet.getSimpleAssociableChoices()) { + String choiceIdentifier = choice.getIdentifier().toString(); + + String markerCorrect = choiceIdentifier + " correct"; + String markerWrong = choiceIdentifier + " wrong"; + + boolean isCorrectRight = correctAnswers.contains(markerCorrect); + String rightFlag = isCorrectRight ? markerCorrect : markerWrong; + String wrongFlag = isCorrectRight ? markerWrong : markerCorrect; + + String value = null; + if(stringuifiedResponse.contains(markerCorrect)) { + value = "+"; + } else if(stringuifiedResponse.contains(markerWrong)) { + value = "-"; + } + + if(stringuifiedResponse.indexOf(rightFlag) >= 0) { + dataRow.addCell(col++, value, workbook.getStyles().getCorrectStyle()); + } else if(stringuifiedResponse.indexOf(wrongFlag) >= 0) { + dataRow.addCell(col++, value, null); + } else { + col++; } } return col; diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java index 79698c6bf3e8894a3151c49be4b4c73a3afb8339..08e2c1a362481030174c890cbe25be19d8c5697f 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/CorrectionAssessmentItemListController.java @@ -398,18 +398,22 @@ public class CorrectionAssessmentItemListController extends FormBasicController List<AssessmentItemListEntry> reorderItemSessions = new ArrayList<>(assessedIdentities.size()); for(Identity assessedIdentity:assessedIdentities) { AssessmentTestSession testSession = model.getLastSessions().get(assessedIdentity); - if(testSession != null) { - AssessmentItemSession itemSession = testToItemSession.get(testSession); - - String title; - if(anonymous) { - title = translate("number.assessed.identity", new String[] { Integer.toString(count++)} ); - } else { - title = userManager.getUserDisplayName(assessedIdentity); - } - AssessmentItemListEntry entry = new AssessmentItemListEntry(assessedIdentity, testSession, itemSession, itemRef, title, "o_icon_user"); - if(filter.test(entry)) { - reorderItemSessions.add(entry); + TestSessionState testSessionState = model.getTestSessionStates().get(assessedIdentity); + if(testSession != null && testSessionState != null) { + List<TestPlanNode> nodes = testSessionState.getTestPlan().getNodes(itemRef.getIdentifier()); + if(nodes != null) { + AssessmentItemSession itemSession = testToItemSession.get(testSession); + + String title; + if(anonymous) { + title = translate("number.assessed.identity", new String[] { Integer.toString(count++)} ); + } else { + title = userManager.getUserDisplayName(assessedIdentity); + } + AssessmentItemListEntry entry = new AssessmentItemListEntry(assessedIdentity, testSession, itemSession, itemRef, title, "o_icon_user"); + if(filter.test(entry)) { + reorderItemSessions.add(entry); + } } } } 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()))); + } } } } diff --git a/src/main/java/org/olat/search/service/indexer/repository/CourseIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/CourseIndexer.java index fbda0ce1211903665f14804e08eddfb39d558954..331b2b95ee63a92d5a1b28deeb1d14fae467d7a1 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/CourseIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/CourseIndexer.java @@ -121,7 +121,10 @@ public class CourseIndexer extends AbstractHierarchicalIndexer { CourseNode childCourseNode = (CourseNode)node; CourseNodeIndexer courseNodeIndexer = getCourseNodeIndexer(childCourseNode); if (courseNodeIndexer != null) { - if (isLogDebugEnabled()) logDebug("courseNodeIndexer=" + courseNodeIndexer); + if (isLogDebugEnabled()) { + logDebug("courseNodeIndexer=" + courseNodeIndexer); + } + try { courseNodeIndexer.doIndex(repositoryResourceContext, course, childCourseNode, indexWriter); } catch (Exception e) { diff --git a/src/main/java/org/olat/search/service/indexer/repository/RepositoryIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/RepositoryIndexer.java index 5f1060a0ce38d2058682215bf965967f32f1be3f..2f4ed05f80cc095e0affde0359bc9548034f3c13 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/RepositoryIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/RepositoryIndexer.java @@ -235,7 +235,7 @@ public class RepositoryIndexer extends AbstractHierarchicalIndexer { } if (debug) logDebug("isOwner=" + reSecurity.isEntryAdmin() + " isAllowedToLaunch=" + isAllowedToLaunch); - if (reSecurity.isEntryAdmin() || isAllowedToLaunch) { + if (reSecurity.isEntryAdmin() || reSecurity.canLaunch() || isAllowedToLaunch) { Indexer repositoryEntryIndexer = getRepositoryEntryIndexer(repositoryEntry); if (debug) logDebug("repositoryEntryIndexer=" + repositoryEntryIndexer); if (repositoryEntryIndexer != null) {