Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rc46a8e8187c1ca4e546ed2952192e63606d95c68 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision c46a8e8187c1ca4e546ed2952192e63606d95c68) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -649,5 +649,13 @@ authoring.fla.page.svg.generator.title =SVG Generator authoring.fla.tool.groups.all =All +authoring.fla.liveedit.cancel.confirm =Do you want to cancel changes made in Live Edit? +authoring.fla.liveedit.readonly.activity.error =The activity can not be modified. It is read-only. +authoring.fla.liveedit.readonly.move.parent.error =The activity can not be moved outside its parent. It is read-only. +authoring.fla.liveedit.readonly.remove.activity.error =The activity can not be removed. It is read-only. +authoring.fla.liveedit.readonly.remove.parent.error =The activity can not be removed. Its parent activity is read-only. +authoring.fla.liveedit.readonly.remove.child.error =The activity can not be removed. It has read-only child activities. +authoring.fla.liveedit.readonly.remove.transition.error =The transition can not be removed. It is read-only. + #======= End labels: Exported 438 labels for en AU ===== Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java =================================================================== diff -u -r5a60c8d2319e06b012ed869471a65e4e88ceb7d0 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 5a60c8d2319e06b012ed869471a65e4e88ceb7d0) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -774,12 +774,31 @@ gate.setTransitionTo(fromTransition); // set x / y position for Gate - Integer x1 = activity.getXcoord() == null ? 0 : activity.getXcoord(); - Integer x2 = toActivity.getXcoord() == null ? 0 : toActivity.getXcoord(); - gate.setXcoord(((x1.intValue() + 123 + x2.intValue()) / 2) - 13); + Integer x1 = null; + Integer x2 = null; + Integer y1 = null; + Integer y2 = null; - Integer y1 = activity.getYcoord() == null ? 0 : activity.getYcoord(); - Integer y2 = toActivity.getYcoord() == null ? 0 : toActivity.getYcoord(); + // Braching and plain Tools position is described differently + if (activity.isBranchingActivity()) { + BranchingActivity branchingActivity = (BranchingActivity) activity; + x1 = branchingActivity.getEndXcoord(); + y1 = branchingActivity.getEndYcoord(); + } else { + x1 = activity.getXcoord() == null ? 0 : activity.getXcoord(); + y1 = activity.getYcoord() == null ? 0 : activity.getYcoord(); + } + + if (toActivity.isBranchingActivity()) { + BranchingActivity branchingActivity = (BranchingActivity) toActivity; + x2 = branchingActivity.getEndXcoord(); + y2 = branchingActivity.getEndYcoord(); + } else { + x2 = toActivity.getXcoord() == null ? 0 : toActivity.getXcoord(); + y2 = toActivity.getYcoord() == null ? 0 : toActivity.getYcoord(); + } + + gate.setXcoord(((x1.intValue() + 123 + x2.intValue()) / 2) - 13); gate.setYcoord((y1.intValue() + 50 + y2.intValue()) / 2); } } Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/EditOnFlyProcessor.java =================================================================== diff -u -ra3249210e9a22e8f54ece275f8243a8f3f3e7217 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/EditOnFlyProcessor.java (.../EditOnFlyProcessor.java) (revision a3249210e9a22e8f54ece275f8243a8f3f3e7217) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/EditOnFlyProcessor.java (.../EditOnFlyProcessor.java) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -24,7 +24,6 @@ package org.lamsfoundation.lams.authoring.service; -import org.apache.log4j.Logger; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.LearningDesign; @@ -34,8 +33,6 @@ import org.lamsfoundation.lams.learningdesign.exception.LearningDesignProcessorException; public class EditOnFlyProcessor extends LearningDesignProcessor { - private static Logger log = Logger.getLogger(EditOnFlyProcessor.class); - public Activity lastReadOnlyActivity = null; // were there any activities added after the Gate? public Activity firstAddedActivity = null; @@ -67,7 +64,10 @@ @Override public void endSimpleActivity(SimpleActivity activity) throws LearningDesignProcessorException { if (activity.isActivityReadOnly()) { - lastReadOnlyActivity = activity; + // skip Floating Activity as it is not in the main flow + if ((activity.getParentActivity() == null) || !activity.getParentActivity().isFloatingActivity()) { + lastReadOnlyActivity = activity; + } } else if (firstAddedActivity == null) { firstAddedActivity = activity; } Index: lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java =================================================================== diff -u -r9bb68cb1df5f57c18e966963fd308e9a82743671 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java (.../HomeAction.java) (revision 9bb68cb1df5f57c18e966963fd308e9a82743671) +++ lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java (.../HomeAction.java) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -247,6 +247,12 @@ public ActionForward author(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws IOException { String url = Configuration.get(ConfigurationKeys.SERVER_URL) + "authoring/author.do?method=openAuthoring"; + Long learningDesignID = WebUtil.readLongParam(req, "learningDesignID", true); + + if (learningDesignID != null) { + url += "&learningDesignID=" + learningDesignID; + } + res.sendRedirect(url); return null; } Index: lams_central/web/authoring/authoring.jsp =================================================================== diff -u -r3cb3801500488954bd62323a52ee854c2a002155 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision 3cb3801500488954bd62323a52ee854c2a002155) +++ lams_central/web/authoring/authoring.jsp (.../authoring.jsp) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -74,7 +74,12 @@ CIRCULAR_SEQUENCE_ERROR : decoderDiv.html('').text(), ACTIVITY_IN_CONTAINER_ERROR : decoderDiv.html('').text(), + + LIVEEDIT_READONLY_ACTIVITY_ERROR : '', + + LIVEEDIT_READONLY_MOVE_PARENT_ERROR : '', + // DecorationLib DEFAULT_ANNOTATION_LABEL_TITLE : '', @@ -120,6 +125,8 @@ SAVE_SEQUENCE_TITLE_PROMPT : decoderDiv.html('').text(), IMPORT_PART_CHOOSE_PROMPT : decoderDiv.html('').text(), + + LIVEEDIT_CANCEL_CONFIRM : '', FOLDER_NOT_SELECTED_ERROR : decoderDiv.html('').text(), @@ -138,7 +145,15 @@ // HandlerLib TRANSITION_FROM_EXISTS_ERROR : decoderDiv.html('').text(), - + + LIVEEDIT_REMOVE_ACTIVITY_ERROR : '', + + LIVEEDIT_REMOVE_PARENT_ERROR : '', + + LIVEEDIT_REMOVE_CHILD_ERROR : '', + + LIVEEDIT_REMOVE_TRANSITION_ERROR : '', + // MenuLib EXPORT_IMAGE_DIALOG_TITLE : '', @@ -313,6 +328,9 @@ +
+ +
@@ -471,7 +489,7 @@ <%-- This will be moved to dialog's button pane using JS --%>
- +
Index: lams_central/web/css/authoring.css =================================================================== diff -u -rc46a8e8187c1ca4e546ed2952192e63606d95c68 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/css/authoring.css (.../authoring.css) (revision c46a8e8187c1ca4e546ed2952192e63606d95c68) +++ lams_central/web/css/authoring.css (.../authoring.css) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -326,6 +326,10 @@ padding-left: 25px; } +#cancelLiveEditButton { + display: none; +} + td#templateContainerCell { width: 150px; vertical-align: top; Index: lams_central/web/includes/javascript/authoring/authoringActivity.js =================================================================== diff -u -r6f765690f68ed125b45563796ce4501e2e002417 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision 6f765690f68ed125b45563796ce4501e2e002417) +++ lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -10,7 +10,7 @@ /** * Either branching (start) or converge (end) point. */ - BranchingEdgeActivity : function(id, uiid, x, y, title, branchingType, branchingActivity) { + BranchingEdgeActivity : function(id, uiid, x, y, title, readOnly, branchingType, branchingActivity) { this.transitions = { 'from' : [], 'to' : [] @@ -23,7 +23,7 @@ } else { // this is the branching point this.isStart = true; - branchingActivity = new ActivityDefs.BranchingActivity(id, uiid, this); + branchingActivity = new ActivityDefs.BranchingActivity(id, uiid, this, readOnly); branchingActivity.branchingType = branchingType || 'chosen'; branchingActivity.title = title || LABELS.DEFAULT_BRANCHING_TITLE; } @@ -41,10 +41,11 @@ /** * Represents a set of branches. It is not displayed on canvas, but holds all the vital data. */ - BranchingActivity : function(id, uiid, branchingEdgeStart) { + BranchingActivity : function(id, uiid, branchingEdgeStart, readOnly) { this.id = +id || null; this.uiid = +uiid || ++layout.ld.maxUIID; this.start = branchingEdgeStart; + this.readOnly = readOnly; this.branches = []; // mapping between groups and branches, if applicable this.groupsToBranches = []; @@ -92,11 +93,12 @@ /** * Constructor for a Gate Activity. */ - GateActivity : function(id, uiid, x, y, title, description, gateType, startTimeOffset, gateActivityCompletionBased) { + GateActivity : function(id, uiid, x, y, title, description, readOnly, gateType, startTimeOffset, gateActivityCompletionBased) { this.id = +id || null; this.uiid = +uiid || ++layout.ld.maxUIID; this.title = title; this.description = description; + this.readOnly = readOnly; this.gateType = gateType || 'permission'; if (gateType == 'schedule') { var day = 24*60; @@ -126,13 +128,14 @@ /** * Constructor for a Grouping Activity. */ - GroupingActivity : function(id, uiid, x, y, title, groupingID, groupingUIID, groupingType, groupDivide, + GroupingActivity : function(id, uiid, x, y, title, readOnly, groupingID, groupingUIID, groupingType, groupDivide, groupCount, learnerCount, equalSizes, viewLearners, groups) { this.id = +id || null; this.groupingID = +groupingID || null; this.groupingUIID = +groupingUIID || ++layout.ld.maxUIID; this.uiid = +uiid || ++layout.ld.maxUIID; this.title = title || LABELS.DEFAULT_GROUPING_TITLE; + this.readOnly = readOnly; this.groupingType = groupingType || 'random'; this.groupDivide = groupDivide || 'groups'; this.groupCount = +groupCount || layout.conf.defaultGroupingGroupCount; @@ -157,11 +160,12 @@ /** * Constructor for an Optional Activity. */ - OptionalActivity : function(id, uiid, x, y, title, minOptions, maxOptions) { + OptionalActivity : function(id, uiid, x, y, title, readOnly, minOptions, maxOptions) { DecorationDefs.Container.call(this, id, uiid, title || LABELS.DEFAULT_OPTIONAL_ACTIVITY_TITLE); this.id = +id || null; this.uiid = +uiid || ++layout.ld.maxUIID; + this.readOnly = readOnly; this.minOptions = minOptions || 0; this.maxOptions = maxOptions || 0; this.transitions = { @@ -180,11 +184,12 @@ /** * Constructor for a Parallel (double) Activity */ - ParallelActivity : function(id, uiid, learningLibraryID, x, y, title, childActivities){ + ParallelActivity : function(id, uiid, learningLibraryID, x, y, title, readOnly, childActivities){ DecorationDefs.Container.call(this, id, uiid, title); this.id = +id || null; this.uiid = +uiid || ++layout.ld.maxUIID; + this.readOnly = readOnly; this.learningLibraryID = +learningLibraryID; this.transitions = { 'from' : [], @@ -206,14 +211,15 @@ /** * Constructor for a Tool Activity. */ - ToolActivity : function(id, uiid, toolContentID, toolID, learningLibraryID, authorURL, x, y, title) { + ToolActivity : function(id, uiid, toolContentID, toolID, learningLibraryID, authorURL, x, y, title, readOnly) { this.id = +id || null; this.uiid = +uiid || ++layout.ld.maxUIID; this.toolContentID = toolContentID; this.toolID = +toolID; this.learningLibraryID = +learningLibraryID; this.authorURL = authorURL; this.title = title; + this.readOnly = readOnly; this.transitions = { 'from' : [], 'to' : [] @@ -271,8 +277,8 @@ branching : function(x, y) { if (x == undefined || y == undefined) { // just redraw the activity - x = this.items.getBBox().x; - y = this.items.getBBox().y; + x = this.items.shape.getBBox().x; + y = this.items.shape.getBBox().y; } if (this.items) { @@ -297,6 +303,9 @@ .attr(layout.defaultTextAttributes); this.items = paper.g(shape, label); + if (this.readOnly) { + this.items.attr('filter', layout.conf.readOnlyFilter); + } if (this.isStart) { // uiid is needed in Monitoring this.items.attr('uiid', this.branchingActivity.uiid); @@ -384,6 +393,9 @@ .attr('stroke', layout.colors.gateText); this.items = paper.g(shape, label); + if (this.readOnly) { + this.items.attr('filter', layout.conf.readOnlyFilter); + } // uiid is needed in Monitoring this.items.attr('uiid', this.uiid); this.items.shape = shape; @@ -422,6 +434,9 @@ .attr(layout.defaultTextAttributes); this.items = paper.g(shape, icon, label); + if (this.readOnly) { + this.items.attr('filter', layout.conf.readOnlyFilter); + } // uiid is needed in Monitoring this.items.attr('uiid', this.uiid); this.items.shape = shape; @@ -559,7 +574,7 @@ // activity colour depends on its category ID .attr({ 'stroke' : layout.colors.activityBorder, - 'fill' : layout.colors.activity[layout.toolMetadata[this.learningLibraryID].activityCategoryID] + 'fill' : layout.colors.activity[layout.toolMetadata[this.learningLibraryID].activityCategoryID] }), // check for icon in the library icon = paper.image(layout.toolMetadata[this.learningLibraryID].iconPath, x + 47, y + 3, 30, 30), @@ -568,6 +583,9 @@ .attr('fill', layout.colors.activityText); this.items = paper.g(shape, icon, label); + if (this.readOnly) { + this.items.attr('filter', layout.conf.readOnlyFilter); + } // uiid is needed in Monitoring this.items.attr('uiid', this.uiid); this.items.shape = shape; @@ -664,8 +682,8 @@ // set all the handlers activity.items.attr('cursor', 'pointer') .mousedown(HandlerActivityLib.activityMousedownHandler) - .click(HandlerLib.itemClickHandler) - .dblclick(HandlerActivityLib.activityDblclickHandler); + .click(HandlerLib.itemClickHandler) + .dblclick(HandlerActivityLib.activityDblclickHandler); if (activity instanceof ActivityDefs.BranchingEdgeActivity && activity.branchingActivity.end) { @@ -1057,8 +1075,17 @@ if (!(activity instanceof ActivityDefs.OptionalActivity || activity instanceof ActivityDefs.FloatingActivity)) { // check if it was removed from an Optional or Floating Activity if (activity.parentActivity && activity.parentActivity instanceof DecorationDefs.Container) { - var childActivities = DecorationLib.getChildActivities(activity.parentActivity.items.shape); + var existingChildActivities = activity.parentActivity.childActivities, + childActivities = DecorationLib.getChildActivities(activity.parentActivity.items.shape); if ($.inArray(activity, childActivities) == -1) { + if (activity.readOnly || activity.parentActivity.readOnly) { + // put the activity back + activity.parentActivity.childActivities = existingChildActivities; + + alert(LABELS.LIVEEDIT_READONLY_MOVE_PARENT_ERROR); + return false; + } + activity.parentActivity.draw(); ActivityLib.redrawTransitions(activity.parentActivity); activity.parentActivity = null; @@ -1086,22 +1113,29 @@ alert(LABELS.ACTIVITY_IN_CONTAINER_ERROR); return false; } + if (activity.readOnly || container.readOnly) { + alert(LABELS.LIVEEDIT_READONLY_ACTIVITY_ERROR); + return false; + } + $.each(activity.transitions.from, function(){ + ActivityLib.removeTransition(this); + }); + $.each(activity.transitions.to, function(){ + ActivityLib.removeTransition(this); + }); + + // for properties dialog to reload + ActivityLib.removeSelectEffect(container); + + // check if the activity is already detected by the container + // if not, add it manually + var childActivities = DecorationLib.getChildActivities(container.items.shape); if ($.inArray(activity, container.childActivities) == -1) { - $.each(activity.transitions.from, function(){ - ActivityLib.removeTransition(this); - }); - $.each(activity.transitions.to, function(){ - ActivityLib.removeTransition(this); - }); - - // for properties dialog to reload - ActivityLib.removeSelectEffect(container); - - container.childActivities.push(activity); - container.draw(null, null, null, null, childActivities); - ActivityLib.redrawTransitions(container); + childActivities.push(activity); } + container.draw(null, null, null, null, childActivities); + ActivityLib.redrawTransitions(container); } } @@ -1366,7 +1400,7 @@ // remove child activities if (activity instanceof DecorationDefs.Container) { - $.each(activity.childActivities, function(){ + $.each(activity.childActivities.slice(), function(){ ActivityLib.removeActivity(this); }); } Index: lams_central/web/includes/javascript/authoring/authoringDecoration.js =================================================================== diff -u -r2f6c67e31d0c35ddcfb8b4ae9f53d162c6472f4c -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringDecoration.js (.../authoringDecoration.js) (revision 2f6c67e31d0c35ddcfb8b4ae9f53d162c6472f4c) +++ lams_central/web/includes/javascript/authoring/authoringDecoration.js (.../authoringDecoration.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -77,6 +77,9 @@ // the label this.items = paper.g(); + if (this.readOnly) { + this.items.attr('filter', layout.conf.readOnlyFilter); + } // uiid is needed in Monitoring this.items.attr('uiid', this.uiid); if (this.title) { Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== diff -u -r9bb68cb1df5f57c18e966963fd308e9a82743671 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 9bb68cb1df5f57c18e966963fd308e9a82743671) +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -40,6 +40,8 @@ layout = { // draw mode prevents some handlers (click, mouseover etc.) from triggering 'drawMode' : false, + // is the LD being live edited? + 'liveEdit' : false, // should the sequence be saved before exiting? 'modified' : false, // list of all dialogs, so they can be easily closed all at once @@ -84,7 +86,10 @@ 'groupingEffectPadding' : 5, 'selectEffectPadding' : 7, - 'supportsDownloadAttribute' : typeof $('')[0].download != 'undefined' + 'supportsDownloadAttribute' : typeof $('')[0].download != 'undefined', + + // will be initialised when paper gets created + 'readOnlyFilter' : null }, 'colors' : { @@ -273,9 +278,9 @@ childActivities.push(childActivity); }); - activity = new ActivityDefs.ParallelActivity(null, null, learningLibraryID, x, y, label, childActivities); + activity = new ActivityDefs.ParallelActivity(null, null, learningLibraryID, x, y, label, false, childActivities); } else { - activity = new ActivityDefs.ToolActivity(null, null, null, toolID, learningLibraryID, null, x, y, label); + activity = new ActivityDefs.ToolActivity(null, null, null, toolID, learningLibraryID, null, x, y, label, false); } layout.activities.push(activity); @@ -821,10 +826,10 @@ if (activity.isStart) { var branchingActivity = activity.branchingActivity, branchingEdge = addActivity = new ActivityDefs.BranchingEdgeActivity( - null, branchingActivity.uiid, 0, 0, branchingActivity.title, branchingActivity.branchingType); + null, branchingActivity.uiid, 0, 0, branchingActivity.title, false, branchingActivity.branchingType); branchingEdge = new ActivityDefs.BranchingEdgeActivity( - null, null, 0, 0, null, null, branchingEdge.branchingActivity); + null, null, 0, 0, null, null, false, branchingEdge.branchingActivity); addActivities.push(branchingEdge); if (branchingActivity.branchingType == 'optional'){ @@ -839,17 +844,17 @@ addActivity = new ActivityDefs.FloatingActivity(null, activity.uiid, 0, 0); } else if (activity instanceof frameActivityDefs.GateActivity) { addActivity = new ActivityDefs.GateActivity( - null, activity.uiid, 0, 0, activity.title, activity.description, activity.gateType, + null, activity.uiid, 0, 0, activity.title, activity.description, false, activity.gateType, activity.startTimeoffset, activity.gateActivityCompletionBased ); } else if (activity instanceof frameActivityDefs.GroupingActivity) { addActivity = new ActivityDefs.GroupingActivity( - null, activity.uiid, 0, 0, activity.title, null, null, activity.groupingType, activity.groupDivide, + null, activity.uiid, 0, 0, activity.title, false, null, null, activity.groupingType, activity.groupDivide, activity.groupCount, activity.learnerCount, activity.equalSizes, activity.viewLearners, null ); } else if (activity instanceof frameActivityDefs.OptionalActivity) { addActivity = new ActivityDefs.OptionalActivity( - null, activity.uiid, 0, 0, activity.title, activity.minOptions, activity.maxOptions + null, activity.uiid, 0, 0, activity.title, false, activity.minOptions, activity.maxOptions ); } else if (activity instanceof frameActivityDefs.ParallelActivity) { addActivity = new ActivityDefs.ParallelActivity( @@ -1360,6 +1365,30 @@ }, + /** + * Tells the backend to remove the system gate. + */ + cancelLiveEdit : function(){ + if (GeneralLib.canClose() || confirm(LABELS.LIVEEDIT_CANCEL_CONFIRM)) { + $.ajax({ + type : 'POST', + async : false, + cache : false, + url : LAMS_URL + 'authoring/author.do', + data : { + 'method' : 'finishLearningDesignEdit', + 'learningDesignID' : layout.ld.learningDesignID, + 'cancelled' : 'true' + }, + success : function() { + GeneralLib.setModified(false); + window.parent.closeDialog('dialogFlashlessAuthoring'); + } + }); + } + }, + + canClose : function(){ return !(layout.modified && (layout.activities.length > 0 @@ -1426,6 +1455,8 @@ paper = Snap(canvas.width() - 5, canvas.height() - 5); canvas.append(paper.node); } + // initialise filter for read-only activities in Live Edit + layout.conf.readOnlyFilter = paper.filter(Snap.filter.grayscale(1)); GeneralLib.resizePaper(); } else { @@ -1491,6 +1522,8 @@ } var arrangeNeeded = false, + // if system gate is found, it is Live Edit + systemGate = null, branchToBranching = {}, // helper for finding last activity in a branch branchToActivityDefs = {}; @@ -1519,7 +1552,8 @@ + '&contentFolderID=' + layout.ld.contentFolderID, activityData.xCoord ? activityData.xCoord : 1, activityData.yCoord ? activityData.yCoord : 1, - activityData.activityTitle); + activityData.activityTitle, + activityData.readOnly); // for later reference activityData.activity = activity; break; @@ -1565,6 +1599,7 @@ activityData.xCoord, activityData.yCoord, activityData.activityTitle, + activityData.readOnly, groupingData.groupingID, groupingData.groupingUIID, groupingType, @@ -1584,6 +1619,7 @@ case 3: var gateType = 'sync'; case 4: var gateType = gateType || 'schedule'; case 5: var gateType = gateType || 'permission'; + case 9: var gateType = gateType || 'system'; case 14: var gateType = gateType || 'condition'; activity = new ActivityDefs.GateActivity( @@ -1593,9 +1629,14 @@ activityData.yCoord, activityData.activityTitle, activityData.description, + activityData.readOnly, gateType, activityData.gateStartTimeOffset, activityData.gateActivityCompletionBased); + + if (gateType == 'system'){ + systemGate = activity; + }; break; // Parallel Activity @@ -1606,7 +1647,8 @@ activityData.learningLibraryID, activityData.xCoord, activityData.yCoord, - activityData.activityTitle); + activityData.activityTitle, + activityData.readOnly); break; // Optional Activity @@ -1617,6 +1659,7 @@ activityData.xCoord, activityData.yCoord, activityData.activityTitle, + activityData.readOnly, activityData.minOptions, activityData.maxOptions); break; @@ -1635,6 +1678,7 @@ arrangeNeeded ? 0 : activityData.startXCoord, arrangeNeeded ? 0 : activityData.startYCoord, activityData.activityTitle, + activityData.readOnly, branchingType); layout.activities.push(branchingEdge); // for later reference @@ -1645,7 +1689,8 @@ null, null, arrangeNeeded ? 0 : activityData.endXCoord, arrangeNeeded ? 0 : activityData.endYCoord, - null, null, branchingEdge.branchingActivity); + null, null, null, + branchingEdge.branchingActivity); layout.activities.push(branchingEdge); branchingEdge.branchingActivity.defaultActivityUIID = activityData.defaultActivityUIID; @@ -1948,12 +1993,22 @@ } }); - if (arrangeNeeded) { GeneralLib.arrangeActivities(); } else { GeneralLib.resizePaper(); } + + + if (systemGate) { + // if system gate exists, it is Live Edit + layout.liveEdit = true; + + // remove unnecessary buttons, show Cancel, move Open after Save and Cancel + $('#newButton, #importSequenceButton, #saveAsButton, #exportLamsButton, #exportImsButton, #previewButton').remove(); + $('#cancelLiveEditButton').show() + .after($('#openButton').parent().parent()); + } GeneralLib.setModified(false); GeneralLib.updateAccess(response.access); @@ -2036,7 +2091,7 @@ branchMappings = [], annotations = [], layoutActivityDefs = [], - // trim the + systemGate = null, title = title.trim(), description = CKEDITOR.instances['ldDescriptionFieldDescription'].getData(), // final success/failure of the save @@ -2220,10 +2275,11 @@ } else if (activity instanceof ActivityDefs.GateActivity){ switch(activity.gateType) { - case 'sync' : activityTypeID = 3; break; - case 'schedule' : activityTypeID = 4; break; + case 'sync' : activityTypeID = 3; break; + case 'schedule' : activityTypeID = 4; break; case 'permission' : activityTypeID = 5; break; - case 'condition' : + case 'system' : activityTypeID = 9; systemGate = activity; break; + case 'condition' : activityTypeID = 14; if (activity.input) { @@ -2544,6 +2600,57 @@ }); }); + if (layout.liveEdit) { + // let backend know that system gate needs to be removed + $.ajax({ + type : 'POST', + async : false, + cache : false, + url : LAMS_URL + 'authoring/author.do', + data : { + 'method' : 'finishLearningDesignEdit', + 'learningDesignID' : layout.ld.learningDesignID, + 'cancelled' : 'false' + }, + success : function() { + // prepare for LD image generate + // remove system gate from the SVG + var fromActivity = null, + toActivity = null, + transitionUIID = null; + if (systemGate.transitions.from.length > 0 && systemGate.transitions.to.length > 0){ + var toTransition = systemGate.transitions.to[0]; + transitionUIID = toTransition.uiid; + toActivity = systemGate.transitions.from[0].toActivity; + fromActivity = toTransition.fromActivity; + } + + ActivityLib.removeActivity(systemGate, true); + if (fromActivity && toActivity) { + ActivityLib.addTransition(fromActivity, toActivity, null, transitionUIID); + } + + // draw all activities as writable + $.each(layout.activities, function(){ + this.readOnly = false; + this.draw(); + }); + + // set as not modified so dialog will not prompt user on close + GeneralLib.setModified(false); + // create the updated LD image + GeneralLib.saveLearningDesignImage(); + + // close the Live Edit dialog + alert('Changes were successfully applied.'); + window.parent.closeDialog('dialogFlashlessAuthoring'); + } + }); + + // if it is Live Edit, exit + return; + } + GeneralLib.saveLearningDesignImage(); if (response.validation.length == 0) { @@ -2627,8 +2734,8 @@ .css('opacity', 0.2); } }, - + /** * Displays sequence image in Open/Save dialog. */ Index: lams_central/web/includes/javascript/authoring/authoringHandler.js =================================================================== diff -u -r2f6c67e31d0c35ddcfb8b4ae9f53d162c6472f4c -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringHandler.js (.../authoringHandler.js) (revision 2f6c67e31d0c35ddcfb8b4ae9f53d162c6472f4c) +++ lams_central/web/includes/javascript/authoring/authoringHandler.js (.../authoringHandler.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -141,26 +141,33 @@ /** * Rewrites a shape's coordinates, so it is where the user dropped it. */ - dropObject : function(object) { + dropObject : function(object, cancel) { // finally transform the dragged elements var transformation = Snap.parseTransformString(object.items.transform().string); object.items.transform(''); - var box = object.items.getBBox(), - originalCoordinates = { - x : box.x, - // adjust this coordinate for annotation labels - y : box.y + (object instanceof DecorationDefs.Label ? 6 : 0) - }; - - if (transformation && transformation.length > 0) { - object.draw(originalCoordinates.x + transformation[0][1], - originalCoordinates.y + transformation[0][2]); + // cancel means that the object will be redrawn in its original place + if (cancel) { + object.draw(); + } else { + // finialise the drop + var box = object.items.shape.getBBox(), + originalCoordinates = { + x : box.x, + // adjust this coordinate for annotation labels + y : box.y + (object instanceof DecorationDefs.Label ? 6 : 0) + }; + + if (transformation && transformation.length > 0) { + object.draw(originalCoordinates.x + transformation[0][1], + originalCoordinates.y + transformation[0][2]); + } + + // add space if dropped object is next to border + GeneralLib.resizePaper(); + + return originalCoordinates; } - - // add space if dropped object is next to border - GeneralLib.resizePaper(); - return originalCoordinates; }, @@ -236,7 +243,11 @@ */ activityDblclickHandler : function(event) { var activity = ActivityLib.getParentObject(this); - ActivityLib.openActivityAuthoring(activity); + if (activity.readOnly) { + alert(LABELS.LIVEEDIT_READONLY_ACTIVITY_ERROR); + } else { + ActivityLib.openActivityAuthoring(activity); + } }, @@ -258,7 +269,28 @@ var mouseupHandler = function(event){ if (HandlerLib.isElemenentBinned(event)) { // if the activity was over rubbish bin, remove it - ActivityLib.removeActivity(activity); + var canRemove = true; + // check if the activity or its parent are read-only + if (activity.readOnly) { + canRemove = false; + alert(LABELS.LIVEEDIT_REMOVE_ACTIVITY_ERROR); + } else if (activity.branchingActivity){ + if (activity.branchingActivity.readOnly) { + canRemove = false; + alert(LABELS.LIVEEDIT_REMOVE_ACTIVITY_ERROR); + } + } + else if (activity.parentActivity && activity.parentActivity.readOnly){ + canRemove = false; + alert(LABELS.LIVEEDIT_REMOVE_PARENT_ERROR); + } + + if (canRemove) { + ActivityLib.removeActivity(activity); + } else { + //revert to the original position + HandlerLib.dropObject(activity, true); + } } else { // finalise movement - rewrite coordinates, see if the activity was not added to a container var originalCoordinates = HandlerLib.dropObject(activity), @@ -332,7 +364,27 @@ if (container instanceof DecorationDefs.Region) { DecorationLib.removeRegion(container); } else { - ActivityLib.removeActivity(container); + var canRemove = true; + if (container.readOnly) { + canRemove = false; + alert(LABELS.LIVEEDIT_REMOVE_ACTIVITY_ERROR); + } else if (container.childActivities){ + // if any of the child activities is read-only, the parent activity can not be removed + $.each(container.childActivities, function(){ + if (this.readOnly) { + canRemove = false; + alert(LABELS.LIVEEDIT_REMOVE_CHILD_ERROR); + return false; + } + }); + } + + if (canRemove) { + ActivityLib.removeActivity(container); + } else { + // revert the activity back to its original place + HandlerLib.dropObject(container, true); + } } } else { HandlerLib.dropObject(container); @@ -626,8 +678,14 @@ // allow transition dragging var mouseupHandler = function(event){ if (HandlerLib.isElemenentBinned(event)) { - // if the transition was over rubbish bin, remove it - ActivityLib.removeTransition(transition); + if (transition.toActivity.readOnly || transition.fromActivity.readOnly) { + alert(LABELS.LIVEEDIT_REMOVE_TRANSITION_ERROR); + // just draw it again in the original place + transition.draw(); + } else { + // if the transition was over rubbish bin, remove it + ActivityLib.removeTransition(transition); + } } else { transition.draw(); } Index: lams_central/web/includes/javascript/authoring/authoringMenu.js =================================================================== diff -u -r527f6618e7e2e01a4fbe155f19bda630be1afda2 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision 527f6618e7e2e01a4fbe155f19bda630be1afda2) +++ lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -166,7 +166,7 @@ y = translatedEvent[1] - 8; // if it is start point, branchingActivity is null and constructor acts accordingly - var branchingEdge = new ActivityDefs.BranchingEdgeActivity(null, null, x, y, null, null, branchingActivity); + var branchingEdge = new ActivityDefs.BranchingEdgeActivity(null, null, x, y, null, false, null, branchingActivity); layout.activities.push(branchingEdge); if (branchingActivity) { Index: lams_central/web/includes/javascript/authoring/authoringProperty.js =================================================================== diff -u -r6f765690f68ed125b45563796ce4501e2e002417 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision 6f765690f68ed125b45563796ce4501e2e002417) +++ lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -170,6 +170,12 @@ content = activity.propertiesContent = $('#propertiesContentGate').clone().attr('id', null) .show().data('parentObject', activity); $('.propertiesContentFieldTitle', content).val(activity.title); + if (activity.gateType == 'system') { + // remove everything except for the title + $('.propertiesContentFieldTitle', content).closest('tr').siblings().remove(); + return; + } + $('.propertiesContentFieldDescription', content).val(activity.description ? activity.description : ''); $('.propertiesContentFieldGateType', content).val(activity.gateType); @@ -1757,6 +1763,11 @@ var dialog = layout.propertiesDialog; dialog.children().detach(); dialog.append(object.propertiesContent); + if (object.readOnly) { + // make all widgets read-only + dialog.find('input, select, textarea').attr('disabled', 'disabled'); + dialog.find('.spinner').spinner('option', 'disabled', true); + } dialog.dialog('open'); dialog.find('input').blur(); var box = object.items.getBBox(), Index: lams_central/web/includes/javascript/groupDisplay.js =================================================================== diff -u -r48ff10930144a6b8fb7a6f43130d961aa904d4f0 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/groupDisplay.js (.../groupDisplay.js) (revision 48ff10930144a6b8fb7a6f43130d961aa904d4f0) +++ lams_central/web/includes/javascript/groupDisplay.js (.../groupDisplay.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -377,7 +377,7 @@ } -function showFlashlessAuthoringDialog(){ +function showFlashlessAuthoringDialog(learningDesignID){ showDialog('dialogFlashlessAuthoring', { 'height' : 865, 'width' : 1280, @@ -392,9 +392,15 @@ } }, 'open' : function() { - var orgID = $(this).dialog('option', 'orgID'); + var orgID = $(this).dialog('option', 'orgID'), + url = LAMS_URL + 'authoring/author.do?method=openAuthoring'; + + if (learningDesignID) { + url += '&learningDesignID=' + learningDesignID; + } + // load contents after opening the dialog - $('iframe', this).attr('src', LAMS_URL + 'authoring/author.do?method=openAuthoring'); + $('iframe', this).attr('src', url); } }, true); } Index: lams_central/web/includes/javascript/pedagogicalPlanner.js =================================================================== diff -u -rac7bf84996976633e737878c62b1d9b818a990d5 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_central/web/includes/javascript/pedagogicalPlanner.js (.../pedagogicalPlanner.js) (revision ac7bf84996976633e737878c62b1d9b818a990d5) +++ lams_central/web/includes/javascript/pedagogicalPlanner.js (.../pedagogicalPlanner.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -181,7 +181,7 @@ startPreview(startPreviewUrl); } else if (actionAfterCompleted==ACTION_OPEN_AUTHOR){ - var openAuthorURL = "home.do?method=authorFlash&learningDesignID=" + learningDesignId; + var openAuthorURL = "home.do?method=author&learningDesignID=" + learningDesignId; if (requestSrc != "") { openAuthorURL += "&requestSrc=" + requestSrc; } Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== diff -u -rac7bf84996976633e737878c62b1d9b818a990d5 -r07865c855b32c77613ed72dd81cd499033dca4dd --- lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision ac7bf84996976633e737878c62b1d9b818a990d5) +++ lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 07865c855b32c77613ed72dd81cd499033dca4dd) @@ -1452,8 +1452,7 @@ if (response) { alert(response); } else { - openPopUp(LAMS_URL + 'home.do?method=authorFlash&layout=editonfly&learningDesignID=' + ldId, - 'LiveEdit', 600, 800, false); + window.parent.showFlashlessAuthoringDialog(ldId, 'editonfly'); closeMonitorLessonDialog(); } }