Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java,v diff -u -r1.118.2.17 -r1.118.2.18 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java 21 Aug 2015 15:25:13 -0000 1.118.2.17 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java 25 Sep 2015 13:22:48 -0000 1.118.2.18 @@ -59,12 +59,12 @@ import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.ChosenBranchingActivity; +import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.ContributionTypes; import org.lamsfoundation.lams.learningdesign.Group; import org.lamsfoundation.lams.learningdesign.LearningDesign; import org.lamsfoundation.lams.learningdesign.OptionsWithSequencesActivity; import org.lamsfoundation.lams.learningdesign.SequenceActivity; -import org.lamsfoundation.lams.learningdesign.Transition; import org.lamsfoundation.lams.learningdesign.exception.LearningDesignException; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; @@ -1180,20 +1180,6 @@ responseJSON.put("activities", new JSONArray(activitiesMap.values())); responseJSON.put("numberPossibleLearners", lessonDetails.getNumberPossibleLearners()); - // on first fetch get transitions metadata so Monitoring can set their SVG elems IDs - if (WebUtil.readBooleanParam(request, "getTransitions", false)) { - JSONArray transitions = new JSONArray(); - for (Transition transition : (Set) learningDesign.getTransitions()) { - JSONObject transitionJSON = new JSONObject(); - transitionJSON.put("uiid", transition.getTransitionUIID()); - transitionJSON.put("fromID", transition.getFromActivity().getActivityId()); - transitionJSON.put("toID", transition.getToActivity().getActivityId()); - - transitions.put(transitionJSON); - } - responseJSON.put("transitions", transitions); - } - List contributeActivities = getContributeActivities(lessonId, true); // remove "attention required" marker for hidden activities in Flash Authoring if (contributeActivities != null) { @@ -1223,6 +1209,71 @@ return null; } + /** + * Checks if activity A is before activity B in a sequence. + */ + public ActionForward isActivityPreceding(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + long activityAid = WebUtil.readLongParam(request, "activityA"); + long activityBid = WebUtil.readLongParam(request, "activityB"); + boolean result = false; + + IMonitoringService monitoringService = MonitoringServiceProxy + .getMonitoringService(getServlet().getServletContext()); + Activity precedingActivity = monitoringService.getActivityById(activityBid); + + // move back an look for activity A + while (!result && (precedingActivity != null)) { + if (precedingActivity.getTransitionTo() != null) { + precedingActivity = precedingActivity.getTransitionTo().getFromActivity(); + } else if (precedingActivity.getParentActivity() != null) { + // this is a nested activity; move up + precedingActivity = precedingActivity.getParentActivity(); + continue; + } else { + precedingActivity = null; + } + + if ((precedingActivity != null) && !precedingActivity.isSequenceActivity()) { + if (precedingActivity.getActivityId().equals(activityAid)) { + // found it + result = true; + } else if (precedingActivity.isComplexActivity()) { + // check descendants of a complex activity + ComplexActivity complexActivity = (ComplexActivity) monitoringService + .getActivityById(precedingActivity.getActivityId()); + if (containsActivity(complexActivity, activityAid, monitoringService)) { + result = true; + } + } + } + } + + response.setContentType("text/plain;charset=utf-8"); + response.getWriter().write(Boolean.toString(result)); + return null; + } + + /** + * Checks if a complex activity or its descendats contain an activity with the given ID. + */ + private boolean containsActivity(ComplexActivity complexActivity, long targetActivityId, + IMonitoringService monitoringService) { + for (Activity childActivity : (Set) complexActivity.getActivities()) { + if (childActivity.getActivityId().equals(targetActivityId)) { + return true; + } + if (childActivity.isComplexActivity()) { + ComplexActivity childComplexActivity = (ComplexActivity) monitoringService + .getActivityById(childActivity.getActivityId()); + if (containsActivity(childComplexActivity, targetActivityId, monitoringService)) { + return true; + } + } + } + return false; + } + public ActionForward releaseGate(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { IMonitoringService monitoringService = MonitoringServiceProxy Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/includes/javascript/monitorLesson.js,v diff -u -r1.44.2.15 -r1.44.2.16 --- lams_monitoring/web/includes/javascript/monitorLesson.js 10 Sep 2015 11:03:36 -0000 1.44.2.15 +++ lams_monitoring/web/includes/javascript/monitorLesson.js 25 Sep 2015 13:22:48 -0000 1.44.2.16 @@ -822,8 +822,7 @@ data : { 'method' : 'getLessonProgress', 'lessonID' : lessonId, - 'branchingActivityID' : sequenceBranchingId, - 'getTransitions' : sequenceCanvasFirstFetch + 'branchingActivityID' : sequenceBranchingId }, success : function(response) { if (sequenceCanvasFirstFetch) { @@ -847,12 +846,6 @@ } }); - // FLA transitions have uiid but no ids; needed for forceComplete() - $.each(response.transitions, function(index, transition){ - $('g[uiid="' + transition.uiid + '"]', sequenceCanvas) - .attr('id', transition.fromID + '_to_' + transition.toID); - }); - originalSequenceCanvas = sequenceCanvas.html(); } @@ -976,26 +969,29 @@ } else { var targetActivityId = +targetActivity.attr('id'); if (currentActivityId != targetActivityId) { + var targetActivityName = targetActivity.attr('class') == 'gate' ? "Gate" : targetActivity.children('text').text(), + moveBackwards = false; - var precedingActivityId = currentActivityId, - targetActivityName = targetActivity.attr('class') == 'gate' ? "Gate" : targetActivity.children('text').text(); + // check if target activity is before current activity + if (currentActivityId) { + $.ajax({ + dataType : 'text', + url : LAMS_URL + 'monitoring/monitoring.do', + async : false, + cache : false, + data : { + 'method' : 'isActivityPreceding', + 'activityA' : targetActivityId, + 'activityB' : currentActivityId + }, + success : function(response) { + moveBackwards = response == 'true'; + } + }); + } - // find out if we are moving learner forward or backwards - while (precedingActivityId){ - // find transition line and extract activity IDs from them - // it is Batik format adopted to new SVGs - var transitionLine = $('*[id$="to_' - + precedingActivityId + '"]:not([id^="arrow"])' - , sequenceCanvas); - precedingActivityId = transitionLine.length == 1 ? - transitionLine.attr('id').split('_')[0] : null; - if (targetActivityId == precedingActivityId) { - break; - } - }; - // check if the target activity was found or we are moving the learner from end of lesson - if (!currentActivityId || precedingActivityId) { + if (moveBackwards) { // move the learner backwards $('#forceBackwardsDialog').text(LABELS.FORCE_COMPLETE_REMOVE_CONTENT .replace('[0]', learnerName).replace('[1]', targetActivityName))