/**
* <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;
import java.util.List;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.elements.TextElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.dtabs.Activateable2;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.id.context.StateEntry;
import org.olat.core.util.StringHelper;
import org.olat.ims.qti21.QTI21AssessmentResultsOptions;
import org.olat.ims.qti21.QTI21DeliveryOptions;
import org.olat.ims.qti21.QTI21DeliveryOptions.TestType;
import org.olat.ims.qti21.QTI21Module;
import org.olat.ims.qti21.QTI21Service;
import org.olat.repository.RepositoryEntry;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 05.01.2016<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class QTI21DeliveryOptionsController extends FormBasicController implements Activateable2 {
private static final String[] onKeys = new String[]{ "on" };
private static final String[] onValues = new String[]{ "" };
private static final String[] settingTypeKeys = new String[]{ "choose", TestType.summative.name(), TestType.formative.name() };
private static final String[] resultsOptionsKeys = new String[] {
QTI21AssessmentResultsOptions.METADATA, QTI21AssessmentResultsOptions.SECTION_SUMMARY,
QTI21AssessmentResultsOptions.QUESTION_SUMMARY, QTI21AssessmentResultsOptions.QUESTIONS,
QTI21AssessmentResultsOptions.USER_SOLUTIONS, QTI21AssessmentResultsOptions.CORRECT_SOLUTIONS
};
private FormLink chooseProfileButton;
private SingleSelection settingTypeEl;
private MultipleSelectionElement showTitlesEl, showMenuEl;
private MultipleSelectionElement personalNotesEl;
private MultipleSelectionElement enableCancelEl, enableSuspendEl;
private MultipleSelectionElement limitAttemptsEl, blockAfterSuccessEl;
private MultipleSelectionElement displayQuestionProgressEl, displayScoreProgressEl;
private MultipleSelectionElement allowAnonymEl;
private MultipleSelectionElement hideLmsEl;
private MultipleSelectionElement digitalSignatureEl, digitalSignatureMailEl;
private MultipleSelectionElement showResultsOnFinishEl, assessmentResultsOnFinishEl;
private TextElement maxAttemptsEl;
private boolean changes;
private final RepositoryEntry testEntry;
private final QTI21DeliveryOptions deliveryOptions;
@Autowired
private QTI21Module qtiModule;
@Autowired
private QTI21Service qtiService;
public QTI21DeliveryOptionsController(UserRequest ureq, WindowControl wControl, RepositoryEntry testEntry) {
super(ureq, wControl);
this.testEntry = testEntry;
deliveryOptions = qtiService.getDeliveryOptions(testEntry);
initForm(ureq);
applyDeliveryOptions(deliveryOptions);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("tab.options");
setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_options");
formLayout.setElementCssClass("o_sel_qti_resource_options");
setFormInfo("settings.choose.descr");
//choose profile
String profilePage = velocity_root + "/profile.html";
FormLayoutContainer profileCont = FormLayoutContainer.createCustomFormLayout("profile", getTranslator(), profilePage);
profileCont.setLabel("settings.profile", null);
formLayout.add(profileCont);
String[] settingTypeValues = new String[]{
translate("qti.form.setting.choose"), translate("qti.form.setting.summative"), translate("qti.form.setting.formative")
};
settingTypeEl = uifactory.addDropdownSingleselect("settings.type", "settings.type", null, profileCont, settingTypeKeys, settingTypeValues, null);
settingTypeEl.setDomReplacementWrapperRequired(false);
settingTypeEl.setAllowNoSelection(true);
chooseProfileButton = uifactory.addFormLink("settings.choose.profile", profileCont, Link.BUTTON);
uifactory.addSpacerElement("profile.spacer", formLayout, false);
limitAttemptsEl = uifactory.addCheckboxesHorizontal("limitAttempts", "qti.form.limit.attempts", formLayout, onKeys, onValues);
limitAttemptsEl.addActionListener(FormEvent.ONCLICK);
maxAttemptsEl = uifactory.addTextElement("maxAttempts", "qti.form.attempts", 8, "", formLayout);
maxAttemptsEl.setDisplaySize(2);
blockAfterSuccessEl = uifactory.addCheckboxesHorizontal("blockAfterSuccess", "qti.form.block.afterSuccess", formLayout, onKeys, onValues);
allowAnonymEl = uifactory.addCheckboxesHorizontal("allowAnonym", "qti.form.allow.anonym", formLayout, onKeys, onValues);
allowAnonymEl.setHelpText(translate("qti.form.allow.anonym.hint"));
allowAnonymEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_test_konf_kurs");
hideLmsEl = uifactory.addCheckboxesHorizontal("hide.lms", "qti.form.hide.lms", formLayout, onKeys, onValues);
showTitlesEl = uifactory.addCheckboxesHorizontal("showTitles", "qti.form.questiontitle", formLayout, onKeys, onValues);
showMenuEl = uifactory.addCheckboxesHorizontal("showMenu", "qti.form.menudisplay", formLayout, onKeys, onValues);
showMenuEl.setElementCssClass("o_sel_qti_show_menu");
personalNotesEl = uifactory.addCheckboxesHorizontal("personalNotes", "qti.form.auto.memofield", formLayout, onKeys, onValues);
personalNotesEl.setHelpText(translate("qti.form.auto.memofield.hint"));
personalNotesEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_test_konf_kurs");
personalNotesEl.setElementCssClass("o_sel_qti_personal_notes");
displayQuestionProgressEl = uifactory.addCheckboxesHorizontal("questionProgress", "qti.form.questionprogress", formLayout, onKeys, onValues);
displayQuestionProgressEl.setElementCssClass("o_sel_qti_progress_questions");
displayScoreProgressEl = uifactory.addCheckboxesHorizontal("scoreProgress", "qti.form.scoreprogress", formLayout, onKeys, onValues);
displayScoreProgressEl.setElementCssClass("o_sel_qti_progress_score");
enableSuspendEl = uifactory.addCheckboxesHorizontal("suspend", "qti.form.enablesuspend", formLayout, onKeys, onValues);
enableSuspendEl.setElementCssClass("o_sel_qti_enable_suspend");
enableCancelEl = uifactory.addCheckboxesHorizontal("cancel", "qti.form.enablecancel", formLayout, onKeys, onValues);
enableCancelEl.setElementCssClass("o_sel_qti_enable_cancel");
digitalSignatureEl = uifactory.addCheckboxesHorizontal("digital.signature", "digital.signature.test.option", formLayout, onKeys, onValues);
digitalSignatureEl.setVisible(qtiModule.isDigitalSignatureEnabled());
digitalSignatureEl.addActionListener(FormEvent.ONCHANGE);
digitalSignatureMailEl = uifactory.addCheckboxesHorizontal("digital.signature.mail", "digital.signature.mail.test.option", formLayout, onKeys, onValues);
showResultsOnFinishEl = uifactory.addCheckboxesHorizontal("resultOnFiniish", "qti.form.results.onfinish", formLayout, onKeys, onValues);
showResultsOnFinishEl.addActionListener(FormEvent.ONCHANGE);
showResultsOnFinishEl.setElementCssClass("o_sel_qti_show_results");
String[] resultsOptionsValues = new String[] {
translate("qti.form.summary.metadata"), translate("qti.form.summary.sections"),
translate("qti.form.summary.questions.metadata"), translate("qti.form.summary.questions"),
translate("qti.form.summary.responses"), translate("qti.form.summary.solutions")
};
assessmentResultsOnFinishEl = uifactory.addCheckboxesVertical("typeResultOnFiniish", "qti.form.summary", formLayout,
resultsOptionsKeys, resultsOptionsValues, 1);
assessmentResultsOnFinishEl.setElementCssClass("o_sel_qti_show_results_options");
assessmentResultsOnFinishEl.setHelpText(translate("qti.form.summary.help"));
assessmentResultsOnFinishEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#overview_results");
FormLayoutContainer buttonsLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
buttonsLayout.setRootForm(mainForm);
formLayout.add(buttonsLayout);
uifactory.addFormSubmitButton("save", buttonsLayout);
}
private void applyDeliveryOptions(QTI21DeliveryOptions options) {
String maxAttemptsValue = "";
int maxAttempts = options.getMaxAttempts();
if(maxAttempts > 0) {
limitAttemptsEl.select(onKeys[0], true);
maxAttemptsValue = Integer.toString(maxAttempts);
} else {
limitAttemptsEl.uncheckAll();
}
maxAttemptsEl.setValue(maxAttemptsValue);
maxAttemptsEl.setVisible(maxAttempts > 0);
applyMultipleSelection(blockAfterSuccessEl, options.isBlockAfterSuccess());
applyMultipleSelection(allowAnonymEl, options.isAllowAnonym());
applyMultipleSelection(hideLmsEl, options.isHideLms());
applyMultipleSelection(showTitlesEl, options.isShowTitles());
applyMultipleSelection(showMenuEl, options.isShowMenu());
applyMultipleSelection(personalNotesEl, options.isPersonalNotes());
applyMultipleSelection(displayQuestionProgressEl, options.isDisplayQuestionProgress());
applyMultipleSelection(displayScoreProgressEl, options.isDisplayScoreProgress());
applyMultipleSelection(enableSuspendEl, options.isEnableSuspend());
applyMultipleSelection(enableCancelEl, options.isEnableCancel());
QTI21AssessmentResultsOptions resultsOptions = options.getAssessmentResultsOptions();
if(!resultsOptions.none()) {
showResultsOnFinishEl.select(onKeys[0], true);
assessmentResultsOnFinishEl.uncheckAll();
if(resultsOptions.isMetadata()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[0], true);
}
if(resultsOptions.isSectionSummary()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[1], true);
}
if(resultsOptions.isQuestionSummary()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[2], true);
}
if(resultsOptions.isQuestions()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[3], true);
}
if(resultsOptions.isUserSolutions()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[4], true);
}
if(resultsOptions.isCorrectSolutions()) {
assessmentResultsOnFinishEl.select(resultsOptionsKeys[5], true);
}
} else {
showResultsOnFinishEl.uncheckAll();
assessmentResultsOnFinishEl.uncheckAll();
}
assessmentResultsOnFinishEl.setVisible(showResultsOnFinishEl.isAtLeastSelected(1));
boolean digitalSignature = options.isDigitalSignature();
applyMultipleSelection(digitalSignatureEl, digitalSignature);
boolean digitalSignatureSendMail = options.isDigitalSignatureMail();
applyMultipleSelection(digitalSignatureMailEl, digitalSignatureSendMail);
digitalSignatureMailEl.setVisible(qtiModule.isDigitalSignatureEnabled() && digitalSignatureEl.isAtLeastSelected(1));
}
private void applyMultipleSelection(MultipleSelectionElement element, boolean option) {
if(option) {
element.select(onKeys[0], true);
} else {
element.uncheckAll();
}
}
@Override
protected void doDispose() {
//
}
@Override
public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
//
}
public boolean hasChanges() {
return changes;
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true;
if(limitAttemptsEl.isAtLeastSelected(1)) {
maxAttemptsEl.clearError();
if(StringHelper.containsNonWhitespace(maxAttemptsEl.getValue())) {
try {
Integer.parseInt(maxAttemptsEl.getValue());
} catch(NumberFormatException e) {
maxAttemptsEl.setErrorKey("form.error.nointeger", null);
allOk &= false;
}
} else {
maxAttemptsEl.setErrorKey("form.legende.mandatory", null);
allOk &= false;
}
}
return allOk & super.validateFormLogic(ureq);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(limitAttemptsEl == source) {
maxAttemptsEl.setVisible(limitAttemptsEl.isAtLeastSelected(1));
} else if(digitalSignatureEl == source) {
digitalSignatureMailEl.setVisible(digitalSignatureEl.isAtLeastSelected(1));
} else if(showResultsOnFinishEl == source) {
assessmentResultsOnFinishEl.setVisible(showResultsOnFinishEl.isAtLeastSelected(1));
} else if(chooseProfileButton == source) {
if(settingTypeEl.isOneSelected()) {
String selectedType = settingTypeEl.getSelectedKey();
if(TestType.formative.name().equals(selectedType)) {
applyDeliveryOptions(QTI21DeliveryOptions.formativeSettings());
} else if(TestType.summative.name().equals(selectedType)) {
applyDeliveryOptions(QTI21DeliveryOptions.summativeSettings());
}
}
settingTypeEl.select("choose", true);
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void formOK(UserRequest ureq) {
if(limitAttemptsEl.isAtLeastSelected(1)) {
deliveryOptions.setMaxAttempts(Integer.parseInt(maxAttemptsEl.getValue()));
} else {
deliveryOptions.setMaxAttempts(0);
}
deliveryOptions.setBlockAfterSuccess(blockAfterSuccessEl.isAtLeastSelected(1));
deliveryOptions.setShowMenu(showMenuEl.isAtLeastSelected(1));
deliveryOptions.setShowTitles(showTitlesEl.isAtLeastSelected(1));
deliveryOptions.setPersonalNotes(personalNotesEl.isAtLeastSelected(1));
deliveryOptions.setEnableCancel(enableCancelEl.isAtLeastSelected(1));
deliveryOptions.setEnableSuspend(enableSuspendEl.isAtLeastSelected(1));
deliveryOptions.setDisplayQuestionProgress(displayQuestionProgressEl.isAtLeastSelected(1));
deliveryOptions.setDisplayScoreProgress(displayScoreProgressEl.isAtLeastSelected(1));
deliveryOptions.setAllowAnonym(allowAnonymEl.isAtLeastSelected(1));
deliveryOptions.setHideLms(hideLmsEl.isAtLeastSelected(1));
if(showResultsOnFinishEl.isAtLeastSelected(1)) {
QTI21AssessmentResultsOptions resultsOptions = new QTI21AssessmentResultsOptions(
assessmentResultsOnFinishEl.isSelected(0), assessmentResultsOnFinishEl.isSelected(1),
assessmentResultsOnFinishEl.isSelected(2), assessmentResultsOnFinishEl.isSelected(3),
assessmentResultsOnFinishEl.isSelected(4), assessmentResultsOnFinishEl.isSelected(5));
deliveryOptions.setAssessmentResultsOptions(resultsOptions);
} else {
deliveryOptions.setAssessmentResultsOptions(QTI21AssessmentResultsOptions.noOptions());
}
deliveryOptions.setShowResultsOnFinish(null);// nullify old stuff
if(qtiModule.isDigitalSignatureEnabled() && digitalSignatureEl.isAtLeastSelected(1)) {
deliveryOptions.setDigitalSignature(true);
deliveryOptions.setDigitalSignatureMail(digitalSignatureMailEl.isAtLeastSelected(1));
} else {
deliveryOptions.setDigitalSignature(false);
deliveryOptions.setDigitalSignatureMail(false);
}
qtiService.setDeliveryOptions(testEntry, deliveryOptions);
changes = true;
fireEvent(ureq, Event.DONE_EVENT);
}
}