Search in sources :

Example 61 with Event

use of org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event in project OpenOLAT by OpenOLAT.

the class AssessmentTestDisplayController method processFinishLinearItem.

// public CandidateSession finishLinearItem(final CandidateSessionContext candidateSessionContext)
// throws CandidateException {
private void processFinishLinearItem(UserRequest ureq) {
    NotificationRecorder notificationRecorder = new NotificationRecorder(NotificationLevel.INFO);
    TestSessionState testSessionState = testSessionController.getTestSessionState();
    try {
        if (!testSessionController.mayAdvanceItemLinear()) {
            candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.CANNOT_FINISH_LINEAR_TEST_ITEM, null);
            logError("CANNOT_FINISH_LINEAR_TEST_ITEM", null);
            return;
        }
    } catch (QtiCandidateStateException e) {
        candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.CANNOT_FINISH_LINEAR_TEST_ITEM, e);
        logError("CANNOT_FINISH_LINEAR_TEST_ITEM", e);
        return;
    } catch (RuntimeException e) {
        candidateAuditLogger.logAndThrowCandidateException(candidateSession, CandidateExceptionReason.CANNOT_FINISH_LINEAR_TEST_ITEM, e);
        logError("CANNOT_FINISH_LINEAR_TEST_ITEM", e);
        // handleExplosion(e, candidateSession);
        return;
    }
    // Update state
    final Date requestTimestamp = ureq.getRequestTimestamp();
    final TestPlanNode nextItemNode = testSessionController.advanceItemLinear(requestTimestamp);
    // boolean terminated = nextItemNode == null && testSessionController.findNextEnterableTestPart() == null;
    // Record current result state
    final AssessmentResult assessmentResult = computeAndRecordTestAssessmentResult(requestTimestamp, testSessionState, false);
    /* If we ended the testPart and there are now no more available testParts, then finish the session now */
    if (nextItemNode == null && testSessionController.findNextEnterableTestPart() == null) {
        candidateSession = qtiService.finishTestSession(candidateSession, testSessionState, assessmentResult, requestTimestamp, getDigitalSignatureOptions(), getIdentity());
    }
    // Record and log event
    final CandidateTestEventType eventType = nextItemNode != null ? CandidateTestEventType.FINISH_ITEM : CandidateTestEventType.FINISH_FINAL_ITEM;
    final CandidateEvent candidateTestEvent = qtiService.recordCandidateTestEvent(candidateSession, testEntry, entry, eventType, null, null, testSessionState, notificationRecorder);
    this.lastEvent = candidateTestEvent;
    candidateAuditLogger.logCandidateEvent(candidateTestEvent);
}
Also used : TestPlanNode(uk.ac.ed.ph.jqtiplus.state.TestPlanNode) QtiCandidateStateException(uk.ac.ed.ph.jqtiplus.exception.QtiCandidateStateException) OLATRuntimeException(org.olat.core.logging.OLATRuntimeException) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) CandidateTestEventType(org.olat.ims.qti21.model.audit.CandidateTestEventType) NotificationRecorder(uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder) AssessmentResult(uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult) Date(java.util.Date) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent)

Example 62 with Event

use of org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event in project OpenOLAT by OpenOLAT.

the class AssessmentObjectComponentRenderer method renderExtendedTextBox.

/*
	  <xsl:template match="qti:extendedTextInteraction" mode="multibox">
	    <xsl:param name="responseInput" as="element(qw:responseInput)?"/>
	    <xsl:param name="checkJavaScript" as="xs:string?"/>
	    <xsl:param name="stringsCount" as="xs:integer"/>
	    <xsl:param name="allowCreate" select="false()" as="xs:boolean"/>
	    <xsl:variable name="interaction" select="." as="element(qti:extendedTextInteraction)"/>
	    <xsl:for-each select="1 to $stringsCount">
	      <xsl:variable name="i" select="." as="xs:integer"/>
	      <xsl:apply-templates select="$interaction" mode="singlebox">
	        <xsl:with-param name="responseInputString" select="$responseInput/qw:string[position()=$i]"/>
	        <xsl:with-param name="checkJavaScript" select="$checkJavaScript"/>
	        <xsl:with-param name="allowCreate" select="$allowCreate and $i=$stringsCount"/>
	      </xsl:apply-templates>
	      <br />
	    </xsl:for-each>
	  </xsl:template>
	  
	  <xsl:template match="qti:extendedTextInteraction" mode="singlebox">
	    <xsl:param name="responseInputString" as="xs:string?"/>
	    <xsl:param name="checkJavaScript" as="xs:string?"/>
	    <xsl:param name="allowCreate" select="false()" as="xs:boolean"/>
	    <xsl:variable name="is-bad-response" select="qw:is-bad-response(@responseIdentifier)" as="xs:boolean"/>
	    <xsl:variable name="is-invalid-response" select="qw:is-invalid-response(@responseIdentifier)" as="xs:boolean"/>
	    <textarea cols="72" rows="6" name="qtiworks_response_{@responseIdentifier}">
	      <xsl:if test="$isItemSessionEnded">
	        <xsl:attribute name="disabled">disabled</xsl:attribute>
	      </xsl:if>
	      <xsl:if test="$is-bad-response or $is-invalid-response">
	        <xsl:attribute name="class" select="'badResponse'"/>
	      </xsl:if>
	      <xsl:if test="@expectedLines">
	        <xsl:attribute name="rows" select="@expectedLines"/>
	      </xsl:if>
	      <xsl:if test="@expectedLines and @expectedLength">
	        <xsl:attribute name="cols" select="ceiling(@expectedLength div @expectedLines)"/>
	      </xsl:if>
	      <xsl:if test="$checkJavaScript">
	        <xsl:attribute name="onchange" select="$checkJavaScript"/>
	      </xsl:if>
	      <xsl:if test="$allowCreate">
	        <xsl:attribute name="onkeyup" select="'QtiWorksRendering.addNewTextBox(this)'"/>
	      </xsl:if>
	      <xsl:value-of select="$responseInputString"/>
	    </textarea>
	  </xsl:template>
	*/
protected void renderExtendedTextBox(AssessmentRenderer renderer, StringOutput sb, AssessmentObjectComponent component, AssessmentItem assessmentItem, ItemSessionState itemSessionState, ExtendedTextInteraction interaction, String responseInputString) {
    String responseUniqueId = component.getResponseUniqueIdentifier(itemSessionState, interaction);
    boolean ended = component.isItemSessionEnded(itemSessionState, renderer.isSolutionMode());
    int expectedLines = interaction.getExpectedLines() == null ? 6 : interaction.getExpectedLines().intValue();
    if (ended) {
        sb.append("<div id='oo_").append(responseUniqueId).append("' style='min-height:").append(expectedLines * 1.5).append("em;' class='form-control textarea_disabled o_disabled o_form_element_disabled");
    } else {
        sb.append("<textarea id='oo_").append(responseUniqueId).append("' name='qtiworks_response_").append(responseUniqueId).append("'");
        if (StringHelper.containsNonWhitespace(interaction.getPlaceholderText())) {
            sb.append(" placeholder=\"").append(StringHelper.escapeHtml(interaction.getPlaceholderText())).append("\"");
        }
        sb.append(" rows='").append(expectedLines).append("'");
        if (interaction.getExpectedLength() == null) {
            sb.append(" cols='72'");
        } else {
            int cols = interaction.getExpectedLength().intValue() / expectedLines;
            sb.append(" cols='").append(cols).append("'");
        }
        ResponseDeclaration responseDeclaration = getResponseDeclaration(assessmentItem, interaction.getResponseIdentifier());
        String checkJavascript = checkJavaScript(responseDeclaration, interaction.getPatternMask());
        if (StringHelper.containsNonWhitespace(checkJavascript)) {
            sb.append(" onchange=\"").append(checkJavascript).append("\"");
        }
        sb.append(" class='form-control");
    }
    if (isBadResponse(itemSessionState, interaction.getResponseIdentifier()) || isInvalidResponse(itemSessionState, interaction.getResponseIdentifier())) {
        sb.append(" badResponse");
    }
    sb.append("'>");
    if (renderer.isSolutionMode()) {
        String placeholder = interaction.getPlaceholderText();
        if (StringHelper.containsNonWhitespace(placeholder)) {
            sb.append(placeholder);
        }
    } else if (StringHelper.containsNonWhitespace(responseInputString)) {
        sb.append(responseInputString);
    }
    if (ended) {
        sb.append("</div>");
    } else {
        sb.append("</textarea>");
        FormJSHelper.appendFlexiFormDirty(sb, component.getQtiItem().getRootForm(), "oo_" + responseUniqueId);
        sb.append(FormJSHelper.getJSStartWithVarDeclaration("oo_" + responseUniqueId)).append("oo_").append(responseUniqueId).append(".on('keypress', function(event, target){if (13 == event.keyCode) {event.stopPropagation()} })").append(FormJSHelper.getJSEnd());
        Form form = component.getQtiItem().getRootForm();
        sb.append(FormJSHelper.getJSStart()).append("jQuery(function() {\n").append(" jQuery('#").append("oo_").append(responseUniqueId).append("').qtiAutosave({\n").append("  responseUniqueId:'").append(responseUniqueId).append("',\n").append("  formName:'").append(form.getFormName()).append("',\n").append("  dispIdField:'").append(form.getDispatchFieldId()).append("',\n").append("  dispId:'").append(component.getQtiItem().getFormDispatchId()).append("',\n").append("  eventIdField:'").append(form.getEventFieldId()).append("'\n").append(" }).tabOverride();\n").append("})\n").append(FormJSHelper.getJSEnd());
    }
}
Also used : Form(org.olat.core.gui.components.form.flexible.impl.Form) AssessmentRenderFunctions.contentAsString(org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.contentAsString) ResponseDeclaration(uk.ac.ed.ph.jqtiplus.node.item.response.declaration.ResponseDeclaration) AssessmentRenderFunctions.getResponseDeclaration(org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.getResponseDeclaration)

Example 63 with Event

use of org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event in project OpenOLAT by OpenOLAT.

the class AssessmentTestComponentRenderer method render.

@Override
public void render(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, RenderResult renderResult, String[] args) {
    AssessmentTestComponent cmp = (AssessmentTestComponent) source;
    TestSessionController testSessionController = cmp.getTestSessionController();
    if (testSessionController.getTestSessionState().isEnded()) {
        renderTerminated(sb, translator);
    } else {
        /* Create appropriate options that link back to this controller */
        TestSessionState testSessionState = testSessionController.getTestSessionState();
        CandidateSessionContext candidateSessionContext = cmp.getCandidateSessionContext();
        final AssessmentTestSession candidateSession = candidateSessionContext.getCandidateSession();
        if (candidateSession.isExploded()) {
            renderExploded(sb, translator);
        } else if (candidateSessionContext.isTerminated()) {
            renderTerminated(sb, translator);
        } else {
            /* Touch the session's duration state if appropriate */
            if (testSessionState.isEntered() && !testSessionState.isEnded()) {
                final Date timestamp = candidateSessionContext.getCurrentRequestTimestamp();
                testSessionController.touchDurations(timestamp);
            }
            /* Render event */
            AssessmentRenderer renderHints = new AssessmentRenderer(renderer);
            renderTestEvent(testSessionController, renderHints, sb, cmp, ubu, translator);
        }
    }
}
Also used : CandidateSessionContext(org.olat.ims.qti21.ui.CandidateSessionContext) AssessmentTestSession(org.olat.ims.qti21.AssessmentTestSession) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) TestSessionController(uk.ac.ed.ph.jqtiplus.running.TestSessionController) Date(java.util.Date)

Example 64 with Event

use of org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event in project OpenOLAT by OpenOLAT.

the class AssessmentTreeComponentRenderer method renderAssessmentItemLink.

/**
 * @param sb
 * @param component
 * @param itemNode
 * @return The event used or null
 */
private Event renderAssessmentItemLink(StringOutput sb, AssessmentTreeComponent component, TestPlanNode itemNode, Translator translator) {
    String key = itemNode.getKey().toString();
    Form form = component.getQtiItem().getRootForm();
    String dispatchId = component.getQtiItem().getFormDispatchId();
    TestSessionController testSessionController = component.getTestSessionController();
    TestSessionState testSessionState = testSessionController.getTestSessionState();
    TestPart testPart = testSessionController.getCurrentTestPart();
    TestPlanNodeKey currentTestPartKey = testSessionState.getCurrentTestPartKey();
    TestPartSessionState currentTestPartSessionState = testSessionState.getTestPartSessionStates().get(currentTestPartKey);
    Event event;
    if (testPart == null || testPart.getNavigationMode() == NavigationMode.NONLINEAR) {
        if (testSessionState.isEnded() || currentTestPartSessionState.isEnded()) {
            if (itemNode.getEffectiveItemSessionControl().isAllowReview() || itemNode.getEffectiveItemSessionControl().isShowFeedback()) {
                event = Event.reviewItem;
            } else {
                event = null;
            }
        } else {
            event = Event.selectItem;
        }
    } else {
        event = null;
    }
    if (event == null) {
        sb.append("<span class='o_assessmentitem_nav_disabled'>");
    } else {
        sb.append("<a href='javascript:;' onclick=\"").append(FormJSHelper.getXHRFnCallFor(form, dispatchId, 1, true, true, new NameValuePair("cid", event.name()), new NameValuePair("item", key))).append(";\" class='o_sel_assessmentitem'>");
    }
    String title;
    if (component.isShowTitles()) {
        title = StringHelper.escapeHtml(itemNode.getSectionPartTitle());
    } else {
        int num = component.getCandidateSessionContext().getNumber(itemNode);
        title = translator.translate("question.title", new String[] { Integer.toString(num) });
    }
    sb.append("<span class='questionTitle'>").append(title).append("</span>");
    if (event == null) {
        sb.append("</span>");
    } else {
        sb.append("</a>");
    }
    return event;
}
Also used : NameValuePair(org.olat.core.gui.components.form.flexible.impl.NameValuePair) TestSessionState(uk.ac.ed.ph.jqtiplus.state.TestSessionState) Form(org.olat.core.gui.components.form.flexible.impl.Form) TestPart(uk.ac.ed.ph.jqtiplus.node.test.TestPart) TestSessionController(uk.ac.ed.ph.jqtiplus.running.TestSessionController) Event(org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event) CandidateEvent(org.olat.ims.qti21.model.audit.CandidateEvent) TestPartSessionState(uk.ac.ed.ph.jqtiplus.state.TestPartSessionState) TestPlanNodeKey(uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)

Example 65 with Event

use of org.olat.ims.qti21.ui.QTIWorksAssessmentTestEvent.Event in project OpenOLAT by OpenOLAT.

the class AssessmentTestComposerController method event.

@Override
protected void event(UserRequest ureq, Component source, Event event) {
    if (menuTree == source) {
        if (event instanceof TreeEvent) {
            TreeEvent te = (TreeEvent) event;
            String cmd = te.getCommand();
            if (MenuTree.COMMAND_TREENODE_CLICKED.equals(cmd)) {
                TreeNode selectedNode = menuTree.getTreeModel().getNodeById(te.getNodeId());
                partEditorFactory(ureq, selectedNode);
            }
        } else if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_DROP)) {
            TreeDropEvent tde = (TreeDropEvent) event;
            doDrop(ureq, tde.getDroppedNodeId(), tde.getTargetNodeId(), tde.isAsChild());
        }
    } else if (newSectionLink == source) {
        doNewSection(ureq, menuTree.getSelectedNode());
    } else if (newTestPartLink == source) {
        doNewTestPart(ureq);
    } else if (newSingleChoiceLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new SingleChoiceAssessmentItemBuilder(translate("new.sc"), translate("new.answer"), qtiService.qtiSerializer()));
    } else if (newMultipleChoiceLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MultipleChoiceAssessmentItemBuilder(translate("new.mc"), translate("new.answer"), qtiService.qtiSerializer()));
    } else if (newKPrimLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new KPrimAssessmentItemBuilder(translate("new.kprim"), translate("new.answer"), qtiService.qtiSerializer()));
    } else if (newMatchLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.match"), QTI21Constants.CSS_MATCH_MATRIX, qtiService.qtiSerializer()));
    } else if (newMatchDragAndDropLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.matchdraganddrop"), QTI21Constants.CSS_MATCH_DRAG_AND_DROP, qtiService.qtiSerializer()));
    } else if (newMatchTrueFalseLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.matchtruefalse"), QTI21Constants.CSS_MATCH_TRUE_FALSE, translate("match.unanswered"), translate("match.true"), translate("match.false"), qtiService.qtiSerializer()));
    } else if (newFIBLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new FIBAssessmentItemBuilder(translate("new.fib"), EntryType.text, qtiService.qtiSerializer()));
    } else if (newNumericalLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new FIBAssessmentItemBuilder(translate("new.fib.numerical"), EntryType.numerical, qtiService.qtiSerializer()));
    } else if (newHotspotLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new HotspotAssessmentItemBuilder(translate("new.hotspot"), qtiService.qtiSerializer()));
    } else if (newHottextLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new HottextAssessmentItemBuilder(translate("new.hottext"), translate("new.hottext.start"), translate("new.hottext.text"), qtiService.qtiSerializer()));
    } else if (newEssayLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new EssayAssessmentItemBuilder(translate("new.essay"), qtiService.qtiSerializer()));
    } else if (newUploadLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new UploadAssessmentItemBuilder(translate("new.upload"), qtiService.qtiSerializer()));
    } else if (newDrawingLink == source) {
        doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new DrawingAssessmentItemBuilder(translate("new.drawing"), qtiService.qtiSerializer()));
    } else if (importFromPoolLink == source) {
        doSelectQItem(ureq);
    } else if (importFromTableLink == source) {
        doImportTable(ureq);
    } else if (exportToPoolLink == source) {
        doExportPool();
    } else if (exportToDocxLink == source) {
        doExportDocx(ureq);
    } else if (deleteLink == source) {
        doConfirmDelete(ureq);
    } else if (copyLink == source) {
        doCopy(ureq);
    } else if (reloadInCacheLink == source) {
        doForceReloadFiles(ureq);
    }
}
Also used : HottextAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.HottextAssessmentItemBuilder) SingleChoiceAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder) EssayAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.EssayAssessmentItemBuilder) MultipleChoiceAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBuilder) MatchAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.MatchAssessmentItemBuilder) TreeEvent(org.olat.core.gui.components.tree.TreeEvent) FIBAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.FIBAssessmentItemBuilder) KPrimAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.KPrimAssessmentItemBuilder) TreeNode(org.olat.core.gui.components.tree.TreeNode) GenericTreeNode(org.olat.core.gui.components.tree.GenericTreeNode) HotspotAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.HotspotAssessmentItemBuilder) TreeDropEvent(org.olat.core.gui.components.tree.TreeDropEvent) UploadAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.UploadAssessmentItemBuilder) DrawingAssessmentItemBuilder(org.olat.ims.qti21.model.xml.interactions.DrawingAssessmentItemBuilder)

Aggregations

CandidateEvent (org.olat.ims.qti21.model.audit.CandidateEvent)46 Date (java.util.Date)36 NotificationRecorder (uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder)32 TestSessionState (uk.ac.ed.ph.jqtiplus.state.TestSessionState)32 ItemSessionState (uk.ac.ed.ph.jqtiplus.state.ItemSessionState)22 AssessmentResult (uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult)20 QtiCandidateStateException (uk.ac.ed.ph.jqtiplus.exception.QtiCandidateStateException)19 OLATRuntimeException (org.olat.core.logging.OLATRuntimeException)18 TestPlanNodeKey (uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey)16 TestPlanNode (uk.ac.ed.ph.jqtiplus.state.TestPlanNode)14 HashMap (java.util.HashMap)12 List (java.util.List)10 RetrieveAssessmentTestSessionEvent (org.olat.ims.qti21.ui.event.RetrieveAssessmentTestSessionEvent)10 OLATResourceable (org.olat.core.id.OLATResourceable)8 AssessmentResponse (org.olat.ims.qti21.AssessmentResponse)8 AssessmentTestSession (org.olat.ims.qti21.AssessmentTestSession)8 StringInput (org.olat.ims.qti21.ui.ResponseInput.StringInput)8 FileResponseData (uk.ac.ed.ph.jqtiplus.types.FileResponseData)8 Identifier (uk.ac.ed.ph.jqtiplus.types.Identifier)8 ResponseData (uk.ac.ed.ph.jqtiplus.types.ResponseData)8