use of org.olat.ims.qti.editor.beecom.objects.Question in project OpenOLAT by OpenOLAT.
the class QTIEditorMainController method createChangeMessage.
/**
* helper method to create the change log message
*
* @return
*/
private String createChangeMessage() {
// FIXME:pb:break down into smaller pieces
final StringBuilder result = new StringBuilder();
if (isRestrictedEdit()) {
Visitor v = new Visitor() {
/*
* a history key is built as follows
* sectionkey+"/"+itemkey+"/"+questionkey+"/"+responsekey
*/
String sectionKey = null;
Map<String, String> itemMap = new HashMap<>();
public void visit(INode node) {
if (node instanceof AssessmentNode) {
AssessmentNode an = (AssessmentNode) node;
String key = "null/null/null/null";
if (history.containsKey(key)) {
// some assessment top level data changed
Memento mem = history.get(key);
result.append("---+ Changes in test " + formatVariable(startedWithTitle) + ":");
result.append(an.createChangeMessage(mem));
}
} else if (node instanceof SectionNode) {
SectionNode sn = (SectionNode) node;
String tmpKey = ((Section) sn.getUnderlyingQTIObject()).getIdent();
String key = tmpKey + "/null/null/null";
if (history.containsKey(key)) {
// some section only data changed
Memento mem = history.get(key);
result.append("\n---++ Section " + formatVariable(sn.getAltText()) + " changes:");
result.append(sn.createChangeMessage(mem));
}
} else if (node instanceof ItemNode) {
ItemNode in = (ItemNode) node;
SectionNode sn = (SectionNode) in.getParent();
String parentSectkey = ((Section) ((SectionNode) in.getParent()).getUnderlyingQTIObject()).getIdent();
Item item = (Item) in.getUnderlyingQTIObject();
Question question = item.getQuestion();
String itemKey = item.getIdent();
String prefixKey = "null/" + itemKey;
String questionIdent = question != null ? question.getQuestion().getId() : "null";
String key = prefixKey + "/" + questionIdent + "/null";
StringBuilder changeMessage = new StringBuilder();
boolean hasChanges = false;
if (!itemMap.containsKey(itemKey)) {
Memento questMem = null;
Memento respMem = null;
if (history.containsKey(key)) {
// question changed!
questMem = history.get(key);
hasChanges = true;
}
// if(!hasChanges){
// check if a response changed
// new prefix for responses
prefixKey += "/null/";
// list contains org.olat.ims.qti.editor.beecom.objects.Response
List<Response> responses = question != null ? question.getResponses() : null;
if (responses != null && responses.size() > 0) {
// check for changes in each response
for (Iterator<Response> iter = responses.iterator(); iter.hasNext(); ) {
Response resp = iter.next();
if (history.containsKey(prefixKey + resp.getIdent())) {
// this response changed!
Memento tmpMem = history.get(prefixKey + resp.getIdent());
if (respMem != null) {
respMem = respMem.getTimestamp() > tmpMem.getTimestamp() ? tmpMem : respMem;
} else {
hasChanges = true;
respMem = tmpMem;
}
}
}
}
// output message
if (hasChanges) {
Memento mem = null;
if (questMem != null && respMem != null) {
// use the earlier memento
mem = questMem.getTimestamp() > respMem.getTimestamp() ? respMem : questMem;
} else if (questMem != null) {
mem = questMem;
} else if (respMem != null) {
mem = respMem;
}
changeMessage.append(in.createChangeMessage(mem));
itemMap.put(itemKey, itemKey);
if (!parentSectkey.equals(sectionKey)) {
// either this item belongs to a new section or no section
// is active
result.append("\n---++ Section " + formatVariable(sn.getAltText()) + " changes:");
result.append("\n").append(changeMessage);
sectionKey = parentSectkey;
} else {
result.append("\n").append(changeMessage);
}
}
}
}
}
private String formatVariable(String var) {
if (StringHelper.containsNonWhitespace(var)) {
return var;
}
return "[no entry]";
}
};
TreeVisitor tv = new TreeVisitor(v, menuTreeModel.getRootNode(), false);
tv.visitAll();
}
/*
*
*/
return result.toString();
}
use of org.olat.ims.qti.editor.beecom.objects.Question in project OpenOLAT by OpenOLAT.
the class ItemMetadataFormController method initForm.
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer,
* org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest)
*/
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("fieldset.legend.metadata");
int t = item.getQuestion().getType();
if (!isSurvey && t == Question.TYPE_ESSAY) {
setFormWarning("warning.essay.test");
}
if (isSurvey) {
setFormContextHelp("Test and Questionnaire Editor in Detail#details_testeditor_test_konf_frage");
} else {
setFormContextHelp("Test and Questionnaire Editor in Detail#details_testeditor_test_konf_frage");
}
// Title
title = uifactory.addTextElement("title", "form.imd.title", -1, item.getTitle(), formLayout);
title.setMandatory(true);
title.setNotEmptyCheck("form.imd.error.empty.title");
// Question Type
String typeName = getType();
uifactory.addStaticTextElement("type", "form.imd.type", typeName, formLayout);
// Description
desc = uifactory.addRichTextElementForStringData("desc", "form.imd.descr", item.getObjectives(), 8, -1, true, null, null, formLayout, ureq.getUserSession(), getWindowControl());
desc.getEditorConfiguration().setFigCaption(false);
RichTextConfiguration richTextConfig = desc.getEditorConfiguration();
// set upload dir to the media dir
richTextConfig.setFileBrowserUploadRelPath("media");
// Layout/Alignment
Question q = item.getQuestion();
// alignment of KPRIM is only horizontal
if (q instanceof ChoiceQuestion && item.getQuestion().getType() != Question.TYPE_KPRIM) {
String[] layoutKeys = new String[] { "h", "v" };
String[] layoutValues = new String[] { translate("form.imd.layout.horizontal"), translate("form.imd.layout.vertical") };
// layout = uifactory.addDropdownSingleselect("form.imd.layout", formLayout, layoutKeys, layoutValues, null);
layout = uifactory.addRadiosHorizontal("layout", "form.imd.layout", formLayout, layoutKeys, layoutValues);
layout.select(((ChoiceQuestion) q).getFlowLabelClass().equals(ChoiceQuestion.BLOCK) ? "h" : "v", true);
}
if (!isSurvey) {
String[] yesnoKeys = new String[] { "y", "n" };
String[] yesnoValues = new String[] { translate("yes"), translate("no") };
// Attempts
limitAttempts = uifactory.addRadiosHorizontal("form.imd.limittries", formLayout, yesnoKeys, yesnoValues);
limitAttempts.setEnabled(!isRestrictedEditMode);
// Radios/Checkboxes need onclick because of IE bug OLAT-5753
limitAttempts.addActionListener(FormEvent.ONCLICK);
attempts = uifactory.addIntegerElement("form.imd.tries", 0, formLayout);
attempts.setEnabled(!isRestrictedEditMode);
attempts.setDisplaySize(3);
if (item.getMaxattempts() > 0) {
limitAttempts.select("y", true);
attempts.setIntValue(item.getMaxattempts());
} else {
limitAttempts.select("n", true);
attempts.setVisible(false);
}
// Time Limit
limitTime = uifactory.addRadiosHorizontal("form.imd.limittime", formLayout, yesnoKeys, yesnoValues);
// Radios/Checkboxes need onclick because of IE bug OLAT-5753
limitTime.addActionListener(FormEvent.ONCLICK);
limitTime.setEnabled(!isRestrictedEditMode);
timeMin = uifactory.addIntegerElement("form.imd.time.min", 0, formLayout);
timeMin.setEnabled(!isRestrictedEditMode);
timeMin.setDisplaySize(3);
timeSec = uifactory.addIntegerElement("form.imd.time.sek", 0, formLayout);
timeSec.setEnabled(!isRestrictedEditMode);
timeSec.setDisplaySize(3);
if (item.getDuration() != null && item.getDuration().isSet()) {
limitTime.select("y", true);
timeMin.setIntValue(item.getDuration().getMin());
timeSec.setIntValue(item.getDuration().getSec());
} else {
limitTime.select("n", true);
timeMin.setVisible(false);
timeSec.setVisible(false);
}
// Shuffle Answers
shuffle = uifactory.addRadiosHorizontal("shuffle", "form.imd.shuffle", formLayout, yesnoKeys, yesnoValues);
shuffle.setEnabled(!isRestrictedEditMode);
shuffle.setVisible(t != Question.TYPE_ESSAY && t != Question.TYPE_FIB);
if (item.getQuestion().isShuffle()) {
shuffle.select("y", true);
} else {
shuffle.select("n", true);
}
// Hints
Control itemControl = item.getItemcontrols().get(0);
showHints = uifactory.addRadiosHorizontal("showHints", "form.imd.solutionhints.show", formLayout, yesnoKeys, yesnoValues);
showHints.setEnabled(!isRestrictedEditMode);
// Radios/Checkboxes need onclick because of IE bug OLAT-5753
showHints.addActionListener(FormEvent.ONCLICK);
showHints.setVisible(t != Question.TYPE_ESSAY);
hint = uifactory.addRichTextElementForStringData("hint", "form.imd.solutionhints", item.getQuestion().getHintText(), 8, -1, true, qti.getBaseDir(), null, formLayout, ureq.getUserSession(), getWindowControl());
hint.setEnabled(!isRestrictedEditMode);
hint.getEditorConfiguration().setFigCaption(false);
// set upload dir to the media dir
hint.getEditorConfiguration().setFileBrowserUploadRelPath("media");
if (itemControl.isHint()) {
showHints.select("y", true);
} else {
showHints.select("n", true);
hint.setVisible(false);
}
// Solution
showSolution = uifactory.addRadiosHorizontal("showSolution", "form.imd.correctsolution.show", formLayout, yesnoKeys, yesnoValues);
showSolution.setEnabled(!isRestrictedEditMode);
// Radios/Checkboxes need onclick because of IE bug OLAT-5753
showSolution.addActionListener(FormEvent.ONCLICK);
boolean essay = (q.getType() == Question.TYPE_ESSAY);
String solLabel = essay ? "form.imd.correctsolution.word" : "form.imd.correctsolution";
solution = uifactory.addRichTextElementForStringData("solution", solLabel, item.getQuestion().getSolutionText(), 8, -1, true, qti.getBaseDir(), null, formLayout, ureq.getUserSession(), getWindowControl());
solution.setEnabled(!isRestrictedEditMode);
solution.getEditorConfiguration().setFigCaption(false);
// set upload dir to the media dir
solution.getEditorConfiguration().setFileBrowserUploadRelPath("media");
if (itemControl.isSolution()) {
showSolution.select("y", true);
} else {
showSolution.select("n", true);
showSolution.setVisible(!essay);
// solution always visible for essay
solution.setVisible(essay);
}
}
// Submit Button
uifactory.addFormSubmitButton("submit", formLayout);
}
use of org.olat.ims.qti.editor.beecom.objects.Question in project OpenOLAT by OpenOLAT.
the class QTI12To21Converter method convertItemBasics.
private void convertItemBasics(Item item, AssessmentItemBuilder itemBuilder) {
AssessmentItem assessmentItem = itemBuilder.getAssessmentItem();
if (StringHelper.containsNonWhitespace(item.getTitle())) {
assessmentItem.setTitle(item.getTitle());
}
if (StringHelper.containsNonWhitespace(item.getLabel())) {
assessmentItem.setLabel(item.getLabel());
}
Question question = item.getQuestion();
String questionText = question.getQuestion().renderAsHtmlForEditor();
questionText = blockedHtml(questionText);
if (StringHelper.isHtml(questionText)) {
itemBuilder.setQuestion(questionText);
} else {
itemBuilder.setQuestion("<p>" + questionText + "</p>");
}
String hintText = question.getHintText();
if (StringHelper.containsNonWhitespace(hintText)) {
ModalFeedbackBuilder hint = itemBuilder.createHint();
Translator translator = Util.createPackageTranslator(QTIModule.class, locale);
hint.setTitle(translator.translate("render.hint"));
hint.setText(hintText);
}
String solutionText = question.getSolutionText();
if (StringHelper.containsNonWhitespace(solutionText)) {
ModalFeedbackBuilder solution = itemBuilder.createCorrectSolutionFeedback();
solutionText = blockedHtml(solutionText);
solution.setText(solutionText);
}
String feedbackMastery = QTIEditHelper.getFeedbackMasteryText(item);
if (StringHelper.containsNonWhitespace(feedbackMastery)) {
ModalFeedbackBuilder feedback = itemBuilder.createCorrectFeedback();
feedbackMastery = blockedHtml(feedbackMastery);
feedback.setText(feedbackMastery);
}
String feedbackFail = QTIEditHelper.getFeedbackFailText(item);
if (StringHelper.containsNonWhitespace(feedbackFail)) {
ModalFeedbackBuilder feedback = itemBuilder.createIncorrectFeedback();
feedbackFail = blockedHtml(feedbackFail);
feedback.setText(feedbackFail);
}
}
use of org.olat.ims.qti.editor.beecom.objects.Question in project OpenOLAT by OpenOLAT.
the class QTI12To21Converter method convertFeedbackPerAnswers.
private void convertFeedbackPerAnswers(Item item, AssessmentItemBuilder itemBuilder, Map<String, Identifier> identToIdentifier) {
Question question = item.getQuestion();
List<ModalFeedbackBuilder> additionalFeedbacks = new ArrayList<>();
for (Response response : question.getResponses()) {
if (response instanceof ChoiceResponse) {
Material responseFeedbackMat = QTIEditHelper.getFeedbackOlatRespMaterial(item, response.getIdent());
if (responseFeedbackMat != null) {
String feedbackCondition = responseFeedbackMat.renderAsHtmlForEditor();
feedbackCondition = blockedHtml(feedbackCondition);
ModalFeedbackCondition condition = new ModalFeedbackCondition();
condition.setVariable(Variable.response);
condition.setOperator(Operator.equals);
condition.setValue(identToIdentifier.get(response.getIdent()).toString());
List<ModalFeedbackCondition> conditions = new ArrayList<>(1);
conditions.add(condition);
ModalFeedbackBuilder feedback = new ModalFeedbackBuilder(itemBuilder.getAssessmentItem(), ModalFeedbackType.additional);
feedback.setFeedbackConditions(conditions);
feedback.setText(feedbackCondition);
additionalFeedbacks.add(feedback);
}
}
}
itemBuilder.setAdditionalFeedbackBuilders(additionalFeedbacks);
}
use of org.olat.ims.qti.editor.beecom.objects.Question in project OpenOLAT by OpenOLAT.
the class QTI12To21Converter method convertMultipleChoice.
private AssessmentItemBuilder convertMultipleChoice(Item item) {
MultipleChoiceAssessmentItemBuilder itemBuilder = new MultipleChoiceAssessmentItemBuilder("Multiple choice", "New answer", qtiSerializer);
convertItemBasics(item, itemBuilder);
itemBuilder.clearMapping();
itemBuilder.clearSimpleChoices();
ChoiceInteraction interaction = itemBuilder.getChoiceInteraction();
Question question = item.getQuestion();
itemBuilder.setShuffle(question.isShuffle());
convertOrientation(question, itemBuilder);
boolean hasNegative = false;
List<Response> responses = question.getResponses();
for (Response response : responses) {
if (response.getPoints() < 0.0f) {
hasNegative = true;
}
}
boolean singleCorrect = question.isSingleCorrect();
Map<String, Identifier> identToIdentifier = new HashMap<>();
for (Response response : responses) {
String responseText = response.getContent().renderAsHtmlForEditor();
responseText = blockedHtml(responseText);
SimpleChoice newChoice;
if (StringHelper.isHtml(responseText)) {
newChoice = AssessmentItemFactory.createSimpleChoice(interaction, "", itemBuilder.getQuestionType().getPrefix());
htmlBuilder.appendHtml(newChoice, responseText);
} else {
newChoice = AssessmentItemFactory.createSimpleChoice(interaction, responseText, itemBuilder.getQuestionType().getPrefix());
}
itemBuilder.addSimpleChoice(newChoice);
identToIdentifier.put(response.getIdent(), newChoice.getIdentifier());
double score = response.getPoints();
if (singleCorrect) {
if (response.isCorrect()) {
itemBuilder.addCorrectAnswer(newChoice.getIdentifier());
}
if (score > 0.0f) {
itemBuilder.setMaxScore(score);
}
} else {
if ((hasNegative && response.getPoints() >= 0.0f) || (!hasNegative && response.getPoints() > 0.0f)) {
itemBuilder.addCorrectAnswer(newChoice.getIdentifier());
}
itemBuilder.setMapping(newChoice.getIdentifier(), score);
}
}
convertFeedbackPerAnswers(item, itemBuilder, identToIdentifier);
if (singleCorrect) {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.allCorrectAnswers);
} else {
itemBuilder.setScoreEvaluationMode(ScoreEvaluation.perAnswer);
if (question instanceof ChoiceQuestion) {
ChoiceQuestion choice = (ChoiceQuestion) question;
itemBuilder.setMinScore(new Double(choice.getMinValue()));
itemBuilder.setMaxScore(new Double(choice.getMaxValue()));
}
}
return itemBuilder;
}
Aggregations