diff --git a/src/main/java/org/olat/core/gui/components/dropdown/Dropdown.java b/src/main/java/org/olat/core/gui/components/dropdown/Dropdown.java index 6bf2493d3cbde6ac978efe311dd80fff1e97bf5a..157851cc6044ac8bc5adc8a66a6c0d149fbecd05 100644 --- a/src/main/java/org/olat/core/gui/components/dropdown/Dropdown.java +++ b/src/main/java/org/olat/core/gui/components/dropdown/Dropdown.java @@ -183,6 +183,18 @@ public class Dropdown extends AbstractComponent implements ComponentCollection { } return null; } + + public Integer getComponentIndex(Component component) { + if (component == null) return null; + + for (int i = 0; i < components.size(); i++) { + Component componentInList = components.get(i); + if (component.getComponentName().equals(componentInList.getComponentName())) { + return Integer.valueOf(i); + } + } + return null; + } @Override public Iterable<Component> getComponents() { diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java index 74b8cbc3affbc51540291e0b541ba6ccf39e2755..edea663b2ee0e14fe507a98d30c543274dc37e61 100644 --- a/src/main/java/org/olat/course/run/CourseRuntimeController.java +++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java @@ -100,10 +100,12 @@ import org.olat.course.db.CustomDBMainController; import org.olat.course.editor.EditorMainController; import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.groupsandrights.CourseRights; +import org.olat.course.learningpath.LearningPathService; import org.olat.course.learningpath.manager.LearningPathNodeAccessProvider; import org.olat.course.learningpath.ui.LearningPathIdentityListController; import org.olat.course.learningpath.ui.MyLearningPathController; import org.olat.course.member.MembersManagementMainController; +import org.olat.course.nodeaccess.ui.UnsupportedCourseNodesController; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.ENCourseNode; import org.olat.course.nodes.bc.CourseDocumentsController; @@ -177,7 +179,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private Link folderLink, assessmentLink, archiverLink, courseStatisticLink, surveyStatisticLink, testStatisticLink, - areaLink, dbLink, + areaLink, dbLink, convertLearningPathLink, //settings lecturesAdminLink, reminderLink, assessmentModeLink, lifeCycleChangeLink, @@ -213,6 +215,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private StatisticCourseNodesController statsToolCtr; private AssessmentModeListController assessmentModeCtrl; private LectureRepositoryAdminController lecturesAdminCtrl; + private UnsupportedCourseNodesController unsupportedCourseNodesCtrl; private CloseableCalloutWindowController courseSearchCalloutCtr; protected RepositoryEntryLifeCycleChangeController lifeCycleChangeCtr; @@ -240,6 +243,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private CourseDBManager courseDBManager; @Autowired private SearchModule searchModule; + @Autowired + private LearningPathService learningPathService; public CourseRuntimeController(UserRequest ureq, WindowControl wControl, RepositoryEntry re, RepositoryEntrySecurity reSecurity, RuntimeControllerCreator runtimeControllerCreator, @@ -644,6 +649,22 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im tools.addComponent(ordersLink); } } + + @Override + protected void initToolsMenuEdition(Dropdown toolsDropdown) { + super.initToolsMenuEdition(toolsDropdown); + if (copyLink != null) { + ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); + if (course != null) { + if (!LearningPathNodeAccessProvider.TYPE.equals(course.getCourseConfig().getNodeAccessType().getType())) { + Integer index = toolsDropdown.getComponentIndex(copyLink); + convertLearningPathLink = LinkFactory.createToolLink("convert.course.learning.path", + translate("tools.convert.course.learning.path"), this, "o_icon o_icon-fw o_icon_learning_path"); + toolsDropdown.addComponent(index + 1, convertLearningPathLink); + } + } + } + } @Override protected void initToolsMenuDelete(Dropdown settingsDropdown) { @@ -992,6 +1013,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im doAssessmentSurveyStatistics(ureq); } else if(assessmentLink == source) { doAssessmentTool(ureq); + } else if (convertLearningPathLink == source) { + doConvertToLearningPath(ureq); } else if(participantListLink == source) { doParticipantList(ureq); } else if(participantInfoLink == source) { @@ -1086,6 +1109,9 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im if (QuickSearchEvent.QUICKSEARCH.equals(event.getCommand())) { doDeactivateQuickSearch(); } + } else if (source == unsupportedCourseNodesCtrl) { + cmc.deactivate(); + cleanUp(); } if(editorCtrl == source && source instanceof VetoableCloseController) { @@ -1133,6 +1159,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im @Override protected void cleanUp() { + removeAsListenerAndDispose(unsupportedCourseNodesCtrl); removeAsListenerAndDispose(lifeCycleChangeCtr); removeAsListenerAndDispose(assessmentToolCtr); removeAsListenerAndDispose(courseFolderCtrl); @@ -1143,6 +1170,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im removeAsListenerAndDispose(membersCtrl); removeAsListenerAndDispose(areasCtrl); removeAsListenerAndDispose(leaveDialogBox); + unsupportedCourseNodesCtrl = null; lifeCycleChangeCtr = null; assessmentToolCtr = null; courseFolderCtrl = null; @@ -1741,6 +1769,29 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } } + private void doConvertToLearningPath(UserRequest ureq) { + ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); + List<CourseNode> unsupportedCourseNodes = learningPathService.getUnsupportedCourseNodes(course); + if (!unsupportedCourseNodes.isEmpty()) { + showUnsupportedMessage(ureq, unsupportedCourseNodes); + return; + } + + RepositoryEntry lpEntry = learningPathService.migrate(getRepositoryEntry(), getIdentity()); + String bPath = "[RepositoryEntry:" + lpEntry.getKey() + "]"; + NewControllerFactory.getInstance().launch(bPath, ureq, getWindowControl()); + } + + private void showUnsupportedMessage(UserRequest ureq, List<CourseNode> unsupportedCourseNodes) { + unsupportedCourseNodesCtrl = new UnsupportedCourseNodesController(ureq, getWindowControl(), unsupportedCourseNodes); + listenTo(unsupportedCourseNodesCtrl); + + cmc = new CloseableModalController(getWindowControl(), translate("close"), + unsupportedCourseNodesCtrl.getInitialComponent(), true, translate("unsupported.course.nodes.title")); + cmc.activate(); + listenTo(cmc); + } + @Override protected void launchContent(UserRequest ureq) { super.launchContent(ureq); diff --git a/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties index 8cd191878d71f840c835633e3e089163608f1cba..87b908b2daab58f68fc07e142c6551325e8bbb8d 100644 --- a/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/run/_i18n/LocalStrings_de.properties @@ -75,6 +75,8 @@ msg.nodenotavailableanymore=Es haben sich Berechtigungen ver\u00E4ndert, so dass participants.in.course={0} Kursteilnehmer anwesend participants.in.course.desc=Anzahl Personen, die momentan diesen Kurs besuchen. warn.cannotactivatesinceintool=Es ist bereits ein anderes Kurswerkzeug desselben Kurses gestartet. Bitte schliessen Sie das aktivierte Kurswerkzeug, bevor Sie ein neues starten. +tools.convert.course.learning.path=In Lernpfadkurs konvertieren +unsupported.course.nodes.title=$org.olat.course.nodeaccess.ui\:unsupported.course.nodes.title course.leave.confirm.hint=Wollen Sie wirklich aus diesem Kurs austreten? Sie verlieren damit die entsprechende Kurs- oder Gruppenmitgliedschaft und werden diesen Kurs in Zukunft nicht mehr betreten k\u00F6nnen. course.leave.entry=Kurs course.leave.acknowledge.msg=Mitgliedschaft beenden diff --git a/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties index 0f5a0fe4626bfd0bcbcff33916cc850590816629..0c3785d2dd24ca2c956383306ca31f4105e67a6a 100644 --- a/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/run/_i18n/LocalStrings_en.properties @@ -75,6 +75,8 @@ msg.nodenotavailableanymore=Your access rights have been altered in the meantime participants.in.course={0} course participants present participants.in.course.desc=Number of course participants in this course warn.cannotactivatesinceintool=Another course tool of the same course is already active. Please deactivate this tool before starting a new one. +tools.convert.course.learning.path=Convert to learning path course +unsupported.course.nodes.title=$org.olat.course.nodeaccess.ui\:unsupported.course.nodes.title course.leave.confirm.hint=Do you really want to leave this course? This deletes your respective course or group membership, and you will not be able to access this course in the future. course.leave.entry=Course course.leave.acknowledge.msg=Delete membership