Skip to content
Snippets Groups Projects
Commit da22337a authored by srosse's avatar srosse
Browse files

OO-413: propose an alternative course node implementation, process the...

OO-413: propose an alternative course node implementation, process the alternative node, mark the other as deleted...
parent ef227e8a
No related branches found
No related tags found
No related merge requests found
Showing
with 330 additions and 68 deletions
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
<bean id="vc" class="de.bps.course.nodes.vc.VCCourseNodeConfiguration" scope="prototype"> <bean id="vc" class="de.bps.course.nodes.vc.VCCourseNodeConfiguration" scope="prototype">
<property name="enabled" value="${course.node.vc.enabled}" /> <property name="enabled" value="${course.node.vc.enabled}" />
<property name="order" value="300" /> <property name="order" value="300" />
<property name="alternativeCourseNodes">
<list>
<value>openmeetings</value>
</list>
</property>
</bean> </bean>
</beans> </beans>
\ No newline at end of file
...@@ -650,12 +650,14 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider { ...@@ -650,12 +650,14 @@ public class WimbaClassroomProvider extends LogDelegator implements VCProvider {
*/ */
private int getStatusCode(String line) { private int getStatusCode(String line) {
int code = StatusCode.UNDEFINED.getCode(); int code = StatusCode.UNDEFINED.getCode();
String extracted = line.split(" ", 2)[0]; if(line != null) {
if(extracted != null && !extracted.isEmpty()) { String extracted = line.split(" ", 2)[0];
try { if(extracted != null && !extracted.isEmpty()) {
code = Integer.parseInt(extracted); try {
} catch(NumberFormatException e) { code = Integer.parseInt(extracted);
// nothing to do since code is pre-set } catch(NumberFormatException e) {
// nothing to do since code is pre-set
}
} }
} }
return code; return code;
......
...@@ -113,6 +113,14 @@ public abstract class DefaultController implements Controller, ControllerEventLi ...@@ -113,6 +113,14 @@ public abstract class DefaultController implements Controller, ControllerEventLi
} }
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
/** /**
* do NOT use normally. use the constructor super(wControl). only used for classes which are loaded by Class.forName and need an empty contstructor * do NOT use normally. use the constructor super(wControl). only used for classes which are loaded by Class.forName and need an empty contstructor
* @param wControl not null * @param wControl not null
......
...@@ -64,7 +64,6 @@ import org.olat.core.util.Util; ...@@ -64,7 +64,6 @@ import org.olat.core.util.Util;
public abstract class BasicController extends DefaultController { public abstract class BasicController extends DefaultController {
protected String velocity_root; protected String velocity_root;
private Locale locale;
private final Identity identity; private final Identity identity;
private Translator translator; private Translator translator;
private Translator fallbackTranslator; private Translator fallbackTranslator;
...@@ -83,9 +82,9 @@ public abstract class BasicController extends DefaultController { ...@@ -83,9 +82,9 @@ public abstract class BasicController extends DefaultController {
*/ */
protected BasicController(UserRequest ureq, WindowControl wControl) { protected BasicController(UserRequest ureq, WindowControl wControl) {
super(wControl); super(wControl);
this.locale = ureq.getLocale(); setLocale(ureq.getLocale());
this.identity = ureq.getIdentity(); this.identity = ureq.getIdentity();
this.translator = Util.createPackageTranslator(this.getClass(), locale); this.translator = Util.createPackageTranslator(this.getClass(), getLocale());
this.fallbackTranslator = null; this.fallbackTranslator = null;
this.velocity_root = Util.getPackageVelocityRoot(this.getClass()); this.velocity_root = Util.getPackageVelocityRoot(this.getClass());
this.logger = Tracing.createLoggerFor(this.getClass()); this.logger = Tracing.createLoggerFor(this.getClass());
...@@ -106,14 +105,14 @@ public abstract class BasicController extends DefaultController { ...@@ -106,14 +105,14 @@ public abstract class BasicController extends DefaultController {
protected BasicController(UserRequest ureq, WindowControl wControl, protected BasicController(UserRequest ureq, WindowControl wControl,
Translator fallBackTranslator) { Translator fallBackTranslator) {
super(wControl); super(wControl);
this.locale = ureq.getLocale(); setLocale(ureq.getLocale());
this.identity = ureq.getIdentity(); this.identity = ureq.getIdentity();
if (fallBackTranslator == null) { if (fallBackTranslator == null) {
throw new AssertException( throw new AssertException(
"please provide a fall translator if using this constructor!!"); "please provide a fall translator if using this constructor!!");
} }
this.fallbackTranslator = fallBackTranslator; this.fallbackTranslator = fallBackTranslator;
this.translator = Util.createPackageTranslator(this.getClass(), locale, this.translator = Util.createPackageTranslator(this.getClass(), getLocale(),
fallBackTranslator); fallBackTranslator);
this.velocity_root = Util.getPackageVelocityRoot(this.getClass()); this.velocity_root = Util.getPackageVelocityRoot(this.getClass());
this.logger = Tracing.createLoggerFor(this.getClass()); this.logger = Tracing.createLoggerFor(this.getClass());
...@@ -392,13 +391,6 @@ public abstract class BasicController extends DefaultController { ...@@ -392,13 +391,6 @@ public abstract class BasicController extends DefaultController {
return identity; return identity;
} }
/**
* @return Returns the locale.
*/
protected Locale getLocale() {
return locale;
}
/** /**
* @return Returns the translator. * @return Returns the translator.
*/ */
...@@ -592,7 +584,7 @@ public abstract class BasicController extends DefaultController { ...@@ -592,7 +584,7 @@ public abstract class BasicController extends DefaultController {
* translator; false: the new locale is not applied to the translator * translator; false: the new locale is not applied to the translator
*/ */
protected void setLocale(Locale locale, boolean setLocaleOnTranslator) { protected void setLocale(Locale locale, boolean setLocaleOnTranslator) {
this.locale = locale; setLocale(locale);
if (setLocaleOnTranslator) { if (setLocaleOnTranslator) {
getTranslator().setLocale(locale); getTranslator().setLocale(locale);
} }
......
/**
* <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.course.editor;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.course.nodes.CourseNode;
import org.olat.course.nodes.CourseNodeConfiguration;
import org.olat.course.nodes.CourseNodeFactory;
/**
*
* Initial date: 14.11.2012<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class AlternativeCourseNodeController extends FormBasicController {
private SingleSelection alternativesEl;
private final CourseNode courseNode;
public AlternativeCourseNodeController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
super(ureq, wControl);
this.courseNode = courseNode;
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormDescription("alternative.choose.description");
CourseNodeConfiguration config
= CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(courseNode.getType());
List<String> alternativeKeyList = new ArrayList<String>(4);
List<String> alternativeValueList = new ArrayList<String>(4);
for(String alt:config.getAlternativeCourseNodes()) {
CourseNodeConfiguration altConfig = CourseNodeFactory.getInstance().getCourseNodeConfigurationEvenForDisabledBB(alt);
if(altConfig.isEnabled()) {
alternativeKeyList.add(alt);
alternativeValueList.add(altConfig.getLinkText(getLocale()));
}
}
String[] alternativeKeys = alternativeKeyList.toArray(new String[alternativeKeyList.size()]);
String[] alternativeValues = alternativeValueList.toArray(new String[alternativeValueList.size()]);
alternativesEl = uifactory.addRadiosVertical("alternative.bbs", formLayout, alternativeKeys, alternativeValues);
if(alternativeKeys.length == 1) {
alternativesEl.select(alternativeKeys[0], true);
}
FormLayoutContainer buttonsLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
formLayout.add(buttonsLayout);
uifactory.addFormSubmitButton("ok", buttonsLayout);
uifactory.addFormCancelButton("cancel", buttonsLayout, ureq, getWindowControl());
}
@Override
protected void doDispose() {
//
}
public String getSelectedAlternative() {
return alternativesEl.isOneSelected() ? alternativesEl.getSelectedKey() : null;
}
public CourseNode getCourseNode() {
return courseNode;
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true;
alternativesEl.clearError();
if(!alternativesEl.isOneSelected()) {
alternativesEl.setErrorKey("form.legende.mandatory", null);
allOk = false;
}
return allOk && super.validateFormLogic(ureq);
}
@Override
protected void formOK(UserRequest ureq) {
fireEvent(ureq, Event.DONE_EVENT);
}
@Override
protected void formCancelled(UserRequest ureq) {
fireEvent(ureq, Event.CANCELLED_EVENT);
}
}
...@@ -78,6 +78,7 @@ import org.olat.core.logging.activity.ActionType; ...@@ -78,6 +78,7 @@ import org.olat.core.logging.activity.ActionType;
import org.olat.core.logging.activity.CourseLoggingAction; import org.olat.core.logging.activity.CourseLoggingAction;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.Formatter; import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util; import org.olat.core.util.Util;
import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.LockEntry; import org.olat.core.util.coordinate.LockEntry;
...@@ -188,6 +189,7 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -188,6 +189,7 @@ public class EditorMainController extends MainLayoutBasicController implements G
private Controller areasController; private Controller areasController;
private DialogBoxController deleteDialogController; private DialogBoxController deleteDialogController;
private LayoutMain3ColsController columnLayoutCtr; private LayoutMain3ColsController columnLayoutCtr;
private AlternativeCourseNodeController alternateCtr;
private LockResult lockEntry; private LockResult lockEntry;
...@@ -199,6 +201,7 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -199,6 +201,7 @@ public class EditorMainController extends MainLayoutBasicController implements G
private Link keepOpenErrorButton; private Link keepOpenErrorButton;
private Link keepClosedWarningButton; private Link keepClosedWarningButton;
private Link keepOpenWarningButton; private Link keepOpenWarningButton;
private Link alternativeLink;
private CloseableModalController cmc; private CloseableModalController cmc;
private MultiSPController multiSPChooserCtr; private MultiSPController multiSPChooserCtr;
...@@ -300,6 +303,9 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -300,6 +303,9 @@ public class EditorMainController extends MainLayoutBasicController implements G
tabbedNodeConfig = new TabbedPane("tabbedNodeConfig", ureq.getLocale()); tabbedNodeConfig = new TabbedPane("tabbedNodeConfig", ureq.getLocale());
main.put(tabbedNodeConfig.getComponentName(), tabbedNodeConfig); main.put(tabbedNodeConfig.getComponentName(), tabbedNodeConfig);
alternativeLink = LinkFactory.createButton("alternative", main, this);
main.put("alternative", alternativeLink);
toolC = ToolFactory.createToolController(getWindowControl()); toolC = ToolFactory.createToolController(getWindowControl());
listenTo(toolC); listenTo(toolC);
...@@ -431,6 +437,9 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -431,6 +437,9 @@ public class EditorMainController extends MainLayoutBasicController implements G
// do logging // do logging
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_RESTORED, getClass(), ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_RESTORED, getClass(),
LoggingResourceable.wrap(activeNode.getCourseNode())); LoggingResourceable.wrap(activeNode.getCourseNode()));
} else if(source == alternativeLink) {
CourseNode chosenNode = (CourseNode)alternativeLink.getUserObject();
askForAlternative(ureq, chosenNode);
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
log.warn(RELEASE_LOCK_AT_CATCH_EXCEPTION+" [in event(UserRequest,Component,Event)]", e); log.warn(RELEASE_LOCK_AT_CATCH_EXCEPTION+" [in event(UserRequest,Component,Event)]", e);
...@@ -438,6 +447,74 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -438,6 +447,74 @@ public class EditorMainController extends MainLayoutBasicController implements G
throw e; throw e;
} }
} }
private void askForAlternative(UserRequest ureq, CourseNode chosenNode) {
removeAsListenerAndDispose(alternateCtr);
removeAsListenerAndDispose(cmc);
alternateCtr = new AlternativeCourseNodeController(ureq, getWindowControl(), chosenNode);
listenTo(alternateCtr);
cmc = new CloseableModalController(getWindowControl(), translate("close"), alternateCtr.getInitialComponent(), true, translate("alternative.choose"));
listenTo(cmc);
cmc.activate();
}
/**
* The following operation are done:
* <ul>
* <li>create a new instance of the replacement type
* <li>add the new element below the original element
* <li>copy the element title, description and the generic configuration options
* <li>copy the access, visibility and scoring rules (easy and expert)
* <li>optionally copy some other configuration if this is possible at all
* <li>move all child elements from the original to the replacement element
* <li>mark the original element as deleted
* </ul>
*
* @param chosenNode
* @param selectAlternative
*/
private void doCreateAlternateBuildingBlock(UserRequest ureq, ICourse course, CourseNode chosenNode, String selectAlternative) {
if(!StringHelper.containsNonWhitespace(selectAlternative)) return;
//create the alternative node
CourseNodeConfiguration newConfig = CourseNodeFactory.getInstance().getCourseNodeConfiguration(selectAlternative);
CourseNode newNode = newConfig.getInstance();
//copy configurations
newNode.setDisplayOption(chosenNode.getDisplayOption());
newNode.setLearningObjectives(chosenNode.getLearningObjectives());
newNode.setLongTitle(chosenNode.getLongTitle());
newNode.setNoAccessExplanation(chosenNode.getNoAccessExplanation());
newNode.setShortTitle(chosenNode.getShortTitle());
//insert the node
CourseEditorTreeNode cetn = (CourseEditorTreeNode)cetm.getNodeById(chosenNode.getIdent());
CourseEditorTreeNode parentNode = (CourseEditorTreeNode)cetn.getParent();
int position = cetn.getPosition() + 1;
CourseEditorTreeNode newCetn =course.getEditorTreeModel().insertCourseNodeAt(newNode, parentNode.getCourseNode(), position);
doInsert(ureq, newNode);
//copy the children
while(cetn.getChildCount() > 0) {
CourseEditorTreeNode childNode = (CourseEditorTreeNode)cetn.getChildAt(0);
newCetn.addChild(childNode);
}
//set all dirty
TreeVisitor tv = new TreeVisitor( new Visitor() {
public void visit(INode node) {
CourseEditorTreeNode cetn = (CourseEditorTreeNode)node;
cetn.setDirty(true);
}
}, newCetn, true);
tv.visitAll();
//mark as deleted
doDelete(course, chosenNode.getIdent());
//save
CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
}
/** /**
* helper to update menu tree, content area, tools to a selected tree node * helper to update menu tree, content area, tools to a selected tree node
...@@ -487,8 +564,11 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -487,8 +564,11 @@ public class EditorMainController extends MainLayoutBasicController implements G
nodeEditCntrllr = chosenNode.createEditController(ureq, getWindowControl(), stackPanel, course, euce); nodeEditCntrllr = chosenNode.createEditController(ureq, getWindowControl(), stackPanel, course, euce);
listenTo(nodeEditCntrllr); listenTo(nodeEditCntrllr);
nodeEditCntrllr.addTabs(tabbedNodeConfig); nodeEditCntrllr.addTabs(tabbedNodeConfig);
} }
main.contextPut("courseNodeDisabled", !cnConfig.isEnabled()); boolean disabled = !cnConfig.isEnabled();
main.contextPut("courseNodeDisabled", disabled);
alternativeLink.setVisible(disabled && !cnConfig.getAlternativeCourseNodes().isEmpty());
alternativeLink.setUserObject(chosenNode);
main.contextPut("courseNodeCss", cnConfig.getIconCSSClass()); main.contextPut("courseNodeCss", cnConfig.getIconCSSClass());
main.contextPut("courseNode", chosenNode); main.contextPut("courseNode", chosenNode);
} }
...@@ -721,11 +801,13 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -721,11 +801,13 @@ public class EditorMainController extends MainLayoutBasicController implements G
removeAsListenerAndDispose(moveCopyController); removeAsListenerAndDispose(moveCopyController);
removeAsListenerAndDispose(insertNodeController); removeAsListenerAndDispose(insertNodeController);
removeAsListenerAndDispose(folderController); removeAsListenerAndDispose(folderController);
removeAsListenerAndDispose(alternateCtr);
removeAsListenerAndDispose(cmc); removeAsListenerAndDispose(cmc);
moveCopyController = null; moveCopyController = null;
insertNodeController = null; insertNodeController = null;
multiSPChooserCtr = null; multiSPChooserCtr = null;
folderController = null; folderController = null;
alternateCtr = null;
cmc = null; cmc = null;
} else if (source == moveCopyController) { } else if (source == moveCopyController) {
cmc.deactivate(); cmc.deactivate();
...@@ -761,20 +843,8 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -761,20 +843,8 @@ public class EditorMainController extends MainLayoutBasicController implements G
// necessary if previous action was a delete node action // necessary if previous action was a delete node action
tabbedNodeConfig.setVisible(true); tabbedNodeConfig.setVisible(true);
main.setPage(VELOCITY_ROOT + "/index.html"); main.setPage(VELOCITY_ROOT + "/index.html");
CourseNode newNode = insertNodeController.getInsertedNode(); CourseNode newNode = insertNodeController.getInsertedNode();
menuTree.setSelectedNodeId(newNode.getIdent()); doInsert(ureq, newNode);
// update the current node in the editor course environment
euce.getCourseEditorEnv().setCurrentCourseNodeId(newNode.getIdent());
euce.getCourseEditorEnv().validateCourse();
StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus();
updateCourseStatusMessages(ureq.getLocale(), courseStatus);
initNodeEditor(ureq, newNode);
// do logging
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_CREATED, getClass(),
LoggingResourceable.wrap(newNode));
// Resize layout columns to make all nodes viewable in the menu column
JSCommand resizeCommand = new JSCommand("b_AddOnDomReplacementFinishedCallback( B_ResizableColumns.adjustHeight.bind(B_ResizableColumns));");
getWindowControl().getWindowBackOffice().sendCommandTo(resizeCommand);
} }
// in all cases: // in all cases:
removeAsListenerAndDispose(insertNodeController); removeAsListenerAndDispose(insertNodeController);
...@@ -788,30 +858,7 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -788,30 +858,7 @@ public class EditorMainController extends MainLayoutBasicController implements G
// delete confirmed // delete confirmed
String ident = menuTree.getSelectedNode().getIdent(); String ident = menuTree.getSelectedNode().getIdent();
// udpate the current node in the course editor environment // udpate the current node in the course editor environment
euce.getCourseEditorEnv().setCurrentCourseNodeId(ident); doDelete(course, ident);
CourseNode activeNode = cetm.getCourseNode(ident);
cetm.markDeleted(activeNode);
menuTree.setDirty(true);
CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
tabbedNodeConfig.removeAll();
tabbedNodeConfig.setVisible(false);
toolC.setEnabled(CMD_DELNODE, false);
toolC.setEnabled(CMD_MOVENODE, false);
toolC.setEnabled(CMD_COPYNODE, false);
main.setPage(VELOCITY_ROOT + "/undeletenode.html"); // offer undelete
showInfo(NLS_DELETENODE_SUCCESS);
/*
* validate course and update course status
*/
euce.getCourseEditorEnv().validateCourse();
StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus();
updateCourseStatusMessages(ureq.getLocale(), courseStatus);
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_DELETED, getClass(),
LoggingResourceable.wrap(activeNode));
} else { } else {
tabbedNodeConfig.setVisible(true); tabbedNodeConfig.setVisible(true);
} }
...@@ -827,6 +874,17 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -827,6 +874,17 @@ public class EditorMainController extends MainLayoutBasicController implements G
StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus(); StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus();
updateCourseStatusMessages(ureq.getLocale(), courseStatus); updateCourseStatusMessages(ureq.getLocale(), courseStatus);
} }
} else if (source == alternateCtr) {
cmc.deactivate();
if(event == Event.DONE_EVENT) {
CourseNode chosenNode = alternateCtr.getCourseNode();
String selectAlternative = alternateCtr.getSelectedAlternative();
doCreateAlternateBuildingBlock(ureq, course, chosenNode, selectAlternative);
}
removeAsListenerAndDispose(cmc);
removeAsListenerAndDispose(alternateCtr);
cmc = null;
alternateCtr = null;
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
log.warn(RELEASE_LOCK_AT_CATCH_EXCEPTION+" [in event(UserRequest,Controller,Event)]", e); log.warn(RELEASE_LOCK_AT_CATCH_EXCEPTION+" [in event(UserRequest,Controller,Event)]", e);
...@@ -835,6 +893,47 @@ public class EditorMainController extends MainLayoutBasicController implements G ...@@ -835,6 +893,47 @@ public class EditorMainController extends MainLayoutBasicController implements G
} }
} }
private void doDelete(ICourse course, String ident) {
CourseNode activeNode = cetm.getCourseNode(ident);
cetm.markDeleted(activeNode);
menuTree.setDirty(true);
CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
tabbedNodeConfig.removeAll();
tabbedNodeConfig.setVisible(false);
toolC.setEnabled(CMD_DELNODE, false);
toolC.setEnabled(CMD_MOVENODE, false);
toolC.setEnabled(CMD_COPYNODE, false);
main.setPage(VELOCITY_ROOT + "/undeletenode.html"); // offer undelete
showInfo(NLS_DELETENODE_SUCCESS);
/*
* validate course and update course status
*/
euce.getCourseEditorEnv().validateCourse();
StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus();
updateCourseStatusMessages(getLocale(), courseStatus);
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_DELETED, getClass(),
LoggingResourceable.wrap(activeNode));
}
private void doInsert(UserRequest ureq, CourseNode newNode) {
menuTree.setSelectedNodeId(newNode.getIdent());
// update the current node in the editor course environment
euce.getCourseEditorEnv().setCurrentCourseNodeId(newNode.getIdent());
euce.getCourseEditorEnv().validateCourse();
StatusDescription[] courseStatus = euce.getCourseEditorEnv().getCourseStatus();
updateCourseStatusMessages(getLocale(), courseStatus);
initNodeEditor(ureq, newNode);
// do logging
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_CREATED, getClass(),
LoggingResourceable.wrap(newNode));
// Resize layout columns to make all nodes viewable in the menu column
JSCommand resizeCommand = new JSCommand("b_AddOnDomReplacementFinishedCallback( B_ResizableColumns.adjustHeight.bind(B_ResizableColumns));");
getWindowControl().getWindowBackOffice().sendCommandTo(resizeCommand);
}
//fxdiff VCRP-9: drag and drop in menu tree //fxdiff VCRP-9: drag and drop in menu tree
private void dropNodeAsChild(UserRequest ureq, ICourse course, String droppedNodeId, String targetNodeId, boolean asChild, boolean atTheEnd) { private void dropNodeAsChild(UserRequest ureq, ICourse course, String droppedNodeId, String targetNodeId, boolean asChild, boolean atTheEnd) {
menuTree.setDirty(true); // setDirty when moving menuTree.setDirty(true); // setDirty when moving
......
...@@ -91,7 +91,8 @@ ...@@ -91,7 +91,8 @@
$r.render("tabbedNodeConfig") $r.render("tabbedNodeConfig")
#end #end
#if($courseNodeDisabled) #if($courseNodeDisabled)
$r.translate("course.building.block.disabled") $r.translate("course.building.block.disabled")<br/><br/>
$r.render("alternative")
#end #end
<div class="o_courseeditor_legend b_small"> <div class="o_courseeditor_legend b_small">
<strong>$r.translate("legend.title")</strong> <strong>$r.translate("legend.title")</strong>
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
access.form.label=Zugriff auf den gesamten Kurs haben access.form.label=Zugriff auf den gesamten Kurs haben
access.legend=Zugriff auf den gesamten Kurs \u00E4ndern access.legend=Zugriff auf den gesamten Kurs \u00E4ndern
apply=OK apply=OK
alternative=Alternative Kursbaustein erstellen
alternative.bbs=Kursbaustein
alternative.choose=Alternative Kursaustein wählen und bestätigen
alternative.choose.description=Sie können die Kursbausstein wählen.
checkall=Alle ausw\u00E4hlen checkall=Alle ausw\u00E4hlen
chelp.attributeEasy=<b>$org.olat.course.condition\:form.easy.attributeSwitch\: </b> chelp.attributeEasy=<b>$org.olat.course.condition\:form.easy.attributeSwitch\: </b>
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package org.olat.course.nodes; package org.olat.course.nodes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.olat.core.configuration.AbstractConfigOnOff; import org.olat.core.configuration.AbstractConfigOnOff;
...@@ -34,11 +36,11 @@ import org.olat.core.configuration.AbstractConfigOnOff; ...@@ -34,11 +36,11 @@ import org.olat.core.configuration.AbstractConfigOnOff;
* Common class for all CourseNodeConfigratiuon classes. * Common class for all CourseNodeConfigratiuon classes.
* @author guretzki * @author guretzki
*/ */
public abstract class AbstractCourseNodeConfiguration extends AbstractConfigOnOff { public abstract class AbstractCourseNodeConfiguration extends AbstractConfigOnOff implements CourseNodeConfiguration {
private int order = 0; private int order = 0;
private String name;
private List<String> alias; private List<String> alternatives;
public AbstractCourseNodeConfiguration() { public AbstractCourseNodeConfiguration() {
super(); super();
...@@ -47,8 +49,25 @@ public abstract class AbstractCourseNodeConfiguration extends AbstractConfigOnOf ...@@ -47,8 +49,25 @@ public abstract class AbstractCourseNodeConfiguration extends AbstractConfigOnOf
public void setOrder(int order) { public void setOrder(int order) {
this.order = order; this.order = order;
} }
@Override
public int getOrder() { public int getOrder() {
return order; return order;
} }
@Override
public List<String> getAlternativeCourseNodes() {
if(alternatives == null) {
return Collections.emptyList();
}
return alternatives;
}
public void setAlternativeCourseNodes(List<String> alternatives) {
if(alternatives == null || alternatives.isEmpty()) {
this.alternatives = null;
} else {
this.alternatives = new ArrayList<String>(alternatives);
}
}
} }
\ No newline at end of file
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package org.olat.course.nodes; package org.olat.course.nodes;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import org.olat.core.configuration.ConfigOnOff; import org.olat.core.configuration.ConfigOnOff;
...@@ -47,5 +48,7 @@ public interface CourseNodeConfiguration extends ConfigOnOff{ ...@@ -47,5 +48,7 @@ public interface CourseNodeConfiguration extends ConfigOnOff{
public String getLinkCSSClass(); public String getLinkCSSClass();
public int getOrder(); public int getOrder();
public List<String> getAlternativeCourseNodes();
} }
...@@ -58,12 +58,12 @@ import org.olat.repository.handlers.RepositoryHandlerFactory; ...@@ -58,12 +58,12 @@ import org.olat.repository.handlers.RepositoryHandlerFactory;
*/ */
public class CourseNodeFactory { public class CourseNodeFactory {
private static OLog log = Tracing.createLoggerFor(CourseNodeFactory.class); private static final OLog log = Tracing.createLoggerFor(CourseNodeFactory.class);
private static CourseNodeFactory INSTANCE; private static CourseNodeFactory INSTANCE;
private static List<String> courseNodeConfigurationsAliases; private static List<String> courseNodeConfigurationsAliases;
private static Map<String, CourseNodeConfiguration> courseNodeConfigurations; private static Map<String, CourseNodeConfiguration> courseNodeConfigurations;
private Object lockObject = new Object(); private Object lockObject = new Object();
private HashMap<String, CourseNodeConfiguration> allCourseNodeConfigurations; private Map<String, CourseNodeConfiguration> allCourseNodeConfigurations;
/** /**
* [used by spring] * [used by spring]
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
<bean id="vitero" class="org.olat.course.nodes.vitero.ViteroCourseNodeConfiguration" scope="prototype"> <bean id="vitero" class="org.olat.course.nodes.vitero.ViteroCourseNodeConfiguration" scope="prototype">
<property name="enabled" value="${course.node.vitero.enabled}" /> <property name="enabled" value="${course.node.vitero.enabled}" />
<property name="order" value="301" /> <property name="order" value="301" />
<property name="alternativeCourseNodes">
<list>
<value>openmeetings</value>
</list>
</property>
</bean> </bean>
</beans> </beans>
\ No newline at end of file
...@@ -75,7 +75,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo ...@@ -75,7 +75,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo
* @param parentNode * @param parentNode
* @param pos * @param pos
*/ */
public void insertCourseNodeAt(CourseNode newNode, CourseNode parentNode, int pos) { public CourseEditorTreeNode insertCourseNodeAt(CourseNode newNode, CourseNode parentNode, int pos) {
// update editor tree model // update editor tree model
CourseEditorTreeNode ctnParent = (CourseEditorTreeNode) getNodeById(parentNode.getIdent()); CourseEditorTreeNode ctnParent = (CourseEditorTreeNode) getNodeById(parentNode.getIdent());
if (ctnParent == null) throw new AssertException("Corrupt CourseEditorTreeModel."); if (ctnParent == null) throw new AssertException("Corrupt CourseEditorTreeModel.");
...@@ -84,6 +84,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo ...@@ -84,6 +84,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo
newCetn.setDirty(true); newCetn.setDirty(true);
ctnParent.insert(newCetn, pos); ctnParent.insert(newCetn, pos);
log.debug("insertCourseNodeAt - nodeId: " + newNode.getIdent()); log.debug("insertCourseNodeAt - nodeId: " + newNode.getIdent());
return newCetn;
} }
/** /**
...@@ -91,7 +92,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo ...@@ -91,7 +92,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo
* @param newNode * @param newNode
* @param parentNode * @param parentNode
*/ */
public void addCourseNode(CourseNode newNode, CourseNode parentNode){ public CourseEditorTreeNode addCourseNode(CourseNode newNode, CourseNode parentNode){
//update editor tree model //update editor tree model
CourseEditorTreeNode ctnParent = (CourseEditorTreeNode) getNodeById(parentNode.getIdent()); CourseEditorTreeNode ctnParent = (CourseEditorTreeNode) getNodeById(parentNode.getIdent());
if (ctnParent == null) throw new AssertException("Corrupt CourseEditorTreeModel."); if (ctnParent == null) throw new AssertException("Corrupt CourseEditorTreeModel.");
...@@ -100,6 +101,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo ...@@ -100,6 +101,7 @@ public class CourseEditorTreeModel extends GenericTreeModel implements DnDTreeMo
newCetn.setDirty(true); newCetn.setDirty(true);
ctnParent.addChild(newCetn); ctnParent.addChild(newCetn);
log.debug("addCourseNode - nodeId: " + newNode.getIdent()); log.debug("addCourseNode - nodeId: " + newNode.getIdent());
return newCetn;
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment