diff --git a/src/main/java/org/olat/core/logging/activity/ActionObject.java b/src/main/java/org/olat/core/logging/activity/ActionObject.java index 7ea26cecba6ca55950b951516db3f5dcd8c7e3f7..9cd993132a5ab83de66e8530f6525c6bf1dc78c7 100644 --- a/src/main/java/org/olat/core/logging/activity/ActionObject.java +++ b/src/main/java/org/olat/core/logging/activity/ActionObject.java @@ -99,6 +99,7 @@ public enum ActionObject { tools, toolsempty, waitingperson, + wiki, bulkassessment, lectures, lecturesRollcall, diff --git a/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java b/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java index 2fc0190b3b88470f924b2c72fd5d4c7a1486dcc3..b12f1b6682ee89bf387e3750ca067ba74108dd16 100644 --- a/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java +++ b/src/main/java/org/olat/core/logging/activity/LearningResourceLoggingAction.java @@ -111,6 +111,10 @@ public class LearningResourceLoggingAction extends BaseLoggingAction { new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.blog).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_BLOG_DISABLED = new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.remove, ActionObject.blog).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); + public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_WIKI_ENABLED = + new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.wiki).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); + public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_WIKI_DISABLED = + new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.remove, ActionObject.wiki).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_FORUM_ENABLED = new LearningResourceLoggingAction(ActionType.admin, CrudAction.update, ActionVerb.add, ActionObject.forum).setTypeList(LEARNING_RESOURCE_OPEN_CLOSE_LIST); public static final ILoggingAction REPOSITORY_ENTRY_PROPERTIES_FORUM_DISABLED = diff --git a/src/main/java/org/olat/course/config/CourseConfigEvent.java b/src/main/java/org/olat/course/config/CourseConfigEvent.java index e3e15a89412b5afdce55aa248baca8f4765e656e..48367986c6643f336be0ed0ec1c449f843e4235e 100644 --- a/src/main/java/org/olat/course/config/CourseConfigEvent.java +++ b/src/main/java/org/olat/course/config/CourseConfigEvent.java @@ -64,6 +64,7 @@ public class CourseConfigEvent extends MultiUserEvent { participantInfo, email, blog, + wiki, forum, documents, chat, diff --git a/src/main/java/org/olat/course/config/ui/CourseToolbarController.java b/src/main/java/org/olat/course/config/ui/CourseToolbarController.java index 53fb5afe658cfa436d36491c74dd01d7f9e16e6e..eb4ff7b0ea13c9619994f8e19c840051533ed801 100644 --- a/src/main/java/org/olat/course/config/ui/CourseToolbarController.java +++ b/src/main/java/org/olat/course/config/ui/CourseToolbarController.java @@ -54,6 +54,7 @@ import org.olat.course.config.CourseConfig; import org.olat.course.config.CourseConfigEvent; import org.olat.course.config.CourseConfigEvent.CourseConfigType; import org.olat.fileresource.types.BlogFileResource; +import org.olat.fileresource.types.WikiResource; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.RepositoryManager; @@ -87,6 +88,10 @@ public class CourseToolbarController extends FormBasicController { private FormLayoutContainer blogCont; private FormLink blogOpenLink; private FormLink blogSelectLink; + private SelectionElement wikiEl; + private FormLayoutContainer wikiCont; + private FormLink wikiOpenLink; + private FormLink wikiSelectLink; private SelectionElement forumEl; private SelectionElement documentsEl; private SelectionElement chatEl; @@ -94,12 +99,14 @@ public class CourseToolbarController extends FormBasicController { private CloseableModalController cmc; private ReferencableEntriesSearchController blogSearchCtrl; + private ReferencableEntriesSearchController wikiSearchCtrl; private LockResult lockEntry; private final boolean editable; private RepositoryEntry entry; private CourseConfig courseConfig; private RepositoryEntry blogEntry; + private RepositoryEntry wikiEntry; @Autowired private UserManager userManager; @@ -119,6 +126,9 @@ public class CourseToolbarController extends FormBasicController { if (StringHelper.containsNonWhitespace(courseConfig.getBlogSoftKey())) { blogEntry = repositoryManager.lookupRepositoryEntryBySoftkey(courseConfig.getBlogSoftKey(), false); } + if (StringHelper.containsNonWhitespace(courseConfig.getWikiSoftKey())) { + wikiEntry = repositoryManager.lookupRepositoryEntryBySoftkey(courseConfig.getWikiSoftKey(), false); + } lockEntry = CoordinatorManager.getInstance().getCoordinator().getLocker() .acquireLock(entry.getOlatResource(), getIdentity(), CourseFactory.COURSE_EDITOR_LOCK); @@ -206,7 +216,6 @@ public class CourseToolbarController extends FormBasicController { if(managedEmail && emailEnabled) { canHideToolbar &= false; } - boolean blogEnabled = courseConfig.isBlogEnabled(); boolean managedBlog = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.blog); blogEl = uifactory.addCheckboxesHorizontal("blogIsOn", "chkbx.blog.onoff", formLayout, onKeys, onValues); @@ -223,6 +232,22 @@ public class CourseToolbarController extends FormBasicController { blogOpenLink = uifactory.addFormLink("blog.not.selected", blogCont, Link.LINK); blogSelectLink = uifactory.addFormLink("blog.select", blogCont, Link.BUTTON_XSMALL); + boolean wikiEnabled = courseConfig.isWikiEnabled(); + boolean managedwWiki = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.wiki); + wikiEl = uifactory.addCheckboxesHorizontal("wikiIsOn", "chkbx.wiki.onoff", formLayout, onKeys, onValues); + wikiEl.addActionListener(FormEvent.ONCHANGE); + wikiEl.select(onKeys[0], wikiEnabled); + wikiEl.setEnabled(editable && !managedwWiki); + if(managedwWiki && wikiEnabled) { + canHideToolbar &= false; + } + + wikiCont = FormLayoutContainer.createButtonLayout("wikiButtons", getTranslator()); + wikiCont.setRootForm(mainForm); + formLayout.add(wikiCont); + wikiOpenLink = uifactory.addFormLink("wiki.not.selected", wikiCont, Link.LINK); + wikiSelectLink = uifactory.addFormLink("wiki.select", wikiCont, Link.BUTTON_XSMALL); + boolean forumEnabled = courseConfig.isForumEnabled(); boolean managedForum = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.forum); forumEl = uifactory.addCheckboxesHorizontal("forumIsOn", "chkbx.forum.onoff", formLayout, onKeys, onValues); @@ -291,6 +316,24 @@ public class CourseToolbarController extends FormBasicController { blogSelectLink.setVisible(blogEntryEditable); blogSelectLink.setI18nKey("blog.select.button", new String[] { translate(blogSelected? "blog.replace": "blog.select")}); } + + boolean wikiEnabled = wikiEl.isSelected(0); + wikiOpenLink.setVisible(wikiEnabled); + wikiCont.setVisible(wikiEnabled); + wikiSelectLink.setVisible(wikiEnabled); + if (wikiEnabled) { + boolean wikiSelected = wikiEntry != null; + wikiOpenLink.setEnabled(wikiSelected); + String wikiTitle = wikiSelected + ? StringHelper.escapeHtml(wikiEntry.getDisplayname()) + : translate("wiki.not.selected"); + wikiOpenLink.setI18nKey("wiki.open", new String[] { wikiTitle }); + wikiOpenLink.setIconLeftCSS(wikiSelected? "o_icon o_icon-fw o_icon_preview": null); + + boolean wikiEntryEditable = wikiEl.isEnabled() && wikiEnabled; + wikiSelectLink.setVisible(wikiEntryEditable); + wikiSelectLink.setI18nKey("wiki.select.button", new String[] { translate(wikiSelected? "wiki.replace": "wiki.select")}); + } } @Override @@ -299,6 +342,10 @@ public class CourseToolbarController extends FormBasicController { updateUI(); } else if (source == blogSelectLink) { doSelectBlog(ureq); + } else if (source == wikiEl) { + updateUI(); + } else if (source == wikiSelectLink) { + doSelectWiki(ureq); } else if(toolbarEl == source) { if(!toolbarEl.isSelected(0) && isAnyToolSelected()) { showWarning("chkbx.toolbar.off.warning"); @@ -315,6 +362,7 @@ public class CourseToolbarController extends FormBasicController { || participantInfoEl.isSelected(0) || emailEl.isSelected(0) || blogEl.isSelected(0) + || wikiEl.isSelected(0) || forumEl.isSelected(0) || documentsEl.isSelected(0) || chatEl.isSelected(0) @@ -332,6 +380,7 @@ public class CourseToolbarController extends FormBasicController { participantInfoEl.setVisible(enabled); emailEl.setVisible(enabled); blogEl.setVisible(enabled); + wikiEl.setVisible(enabled); forumEl.setVisible(enabled); documentsEl.setVisible(enabled); chatEl.setVisible(enabled); @@ -350,14 +399,26 @@ public class CourseToolbarController extends FormBasicController { } cmc.deactivate(); cleanUp(); + } else if (source == wikiSearchCtrl) { + if (event == ReferencableEntriesSearchController.EVENT_REPOSITORY_ENTRY_SELECTED) { + RepositoryEntry wikiEntry = wikiSearchCtrl.getSelectedEntry(); + if (wikiEntry != null) { + this.wikiEntry = wikiEntry; + updateUI(); + } + } + cmc.deactivate(); + cleanUp(); } super.event(ureq, source, event); } private void cleanUp() { removeAsListenerAndDispose(blogSearchCtrl); + removeAsListenerAndDispose(wikiSearchCtrl); removeAsListenerAndDispose(cmc); blogSearchCtrl = null; + wikiSearchCtrl = null; cmc = null; } @@ -373,6 +434,15 @@ public class CourseToolbarController extends FormBasicController { allOk = false; } } + + wikiCont.clearError(); + boolean wikiEnabled = wikiEl.isSelected(0); + if (wikiEnabled) { + if (wikiEntry == null) { + wikiCont.setErrorKey("error.no.wiki.selected", null); + allOk = false; + } + } return allOk & super.validateFormLogic(ureq); } @@ -414,6 +484,14 @@ public class CourseToolbarController extends FormBasicController { courseConfig.setBlogSoftKey(blogSoftKey); doUpdateBlogReference(course, blogSelected); + boolean enableWiki = wikiEl.isSelected(0); + boolean updateWiki = courseConfig.isWikiEnabled() != enableWiki; + courseConfig.setWikiEnabled(enableWiki && toolbarEnabled); + boolean wikiSelected = enableWiki && wikiEntry != null; + String wikiSoftKey = wikiSelected? wikiEntry.getSoftkey(): null; + courseConfig.setWikiSoftKey(wikiSoftKey); + doUpdateWikiReference(course, wikiSelected); + boolean enableForum = forumEl.isSelected(0); boolean updateForum = courseConfig.isForumEnabled() != enableForum; courseConfig.setForumEnabled(enableForum && toolbarEnabled); @@ -495,6 +573,16 @@ public class CourseToolbarController extends FormBasicController { .fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.blog, course.getResourceableId()), course); } + if(updateWiki) { + ILoggingAction loggingAction = enableWiki ? + LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_WIKI_ENABLED: + LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_WIKI_DISABLED; + ThreadLocalUserActivityLogger.log(loggingAction, getClass()); + + CoordinatorManager.getInstance().getCoordinator().getEventBus() + .fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.wiki, course.getResourceableId()), course); + } + if(updateForum) { ILoggingAction loggingAction = enableForum ? LearningResourceLoggingAction.REPOSITORY_ENTRY_PROPERTIES_FORUM_ENABLED: @@ -571,4 +659,32 @@ public class CourseToolbarController extends FormBasicController { } } + private void doSelectWiki(UserRequest ureq) { + wikiSearchCtrl = new ReferencableEntriesSearchController(getWindowControl(), ureq, WikiResource.TYPE_NAME, + translate("wiki.select.titile")); + listenTo(wikiSearchCtrl); + cmc = new CloseableModalController(getWindowControl(), translate("close"), + wikiSearchCtrl.getInitialComponent(), true, translate("wiki.select.title")); + cmc.activate(); + } + + private void doUpdateWikiReference(ICourse course, boolean wikiSelected) { + Optional<Reference> reference = referenceManager.getReferences(course).stream() + .filter(ref -> ref.getUserdata().equals("wiki")) + .findAny(); + if (wikiSelected) { + if (reference.isPresent()) { + if (!reference.get().getTarget().equals(wikiEntry.getOlatResource())) { + // User selected other wiki (replaced) + referenceManager.delete(reference.get()); + referenceManager.addReference(course, wikiEntry.getOlatResource(), "wiki"); + } + } else { + referenceManager.addReference(course, wikiEntry.getOlatResource(), "wiki"); + } + } else if(!wikiSelected && reference.isPresent()) { + referenceManager.delete(reference.get()); + } + } + } diff --git a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties index 3b8f47c812242fe64d4bab13404bd3d6cdffc2ba..64489cec714f80864c1c98c3b2e125f2bc747f6a 100644 --- a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_de.properties @@ -22,6 +22,7 @@ chkbx.participantlist.onoff=Teilnehmerliste chkbx.toolbar.explain=Werkzeuge in Toolbar aktivieren: chkbx.toolbar.onoff=Toolbar sichtbar f\u00FCr Teilnehmer chkbx.toolbar.off.warning=Wenn sie die Toolbar abschalten, stehen die einzelnen Werkzeuge ebenfalls nicht mehr zur Verf\u00FCgung. +chkbx.wiki.onoff=Wiki chkbx.breadcrumb.onoff=Kr\u00FCmelnavigation command.choose=W\u00E4hlen command.glossary.add=Glossar w\u00E4hlen @@ -30,6 +31,7 @@ course.log.changed.message=<br>Detaillierte Kurs-Log-Dateien k\u00F6nnen im Arch coursefolder=Ablageordner details.options.title=Glossar und Ressourcenordner error.no.blog.selected=Es ist kein Blog ausgew\u00E4hlt. +error.no.wiki.selected=Es ist kein Wiki ausgew\u00E4hlt. form.layout.changecustomcss=CSS auswechseln form.layout.choosecustomcss=Eigenes CSS w\u00E4hlen form.layout.choosesystemcss=Standard CSS w\u00E4hlen @@ -59,3 +61,9 @@ warning.change.toenable=Mit dieser Auswahl werden die Leistungsnachweise f\u00FC warning.folderRef.title=Achtung! warning.folderRef=Es gibt einen Ordner Kursbaustein der auf diesen Ressourcenordner referenziert. Soll die Auswahl trotzdem gel\u00F6scht werden? warning.folderRefAdd=Der aktuelle Ressourcenordner ist durch einen Ordner Kursbaustein referenziert. Soll die Auswahl trotzdem ge\u00E4ndert werden? +wiki.not.selected=Kein Wiki ausgew\u00E4hlt +wiki.open={0} +wiki.replace=Ersetzen +wiki.select=Ausw\u00E4hlen +wiki.select.button={0} +wiki.select.title=Wiki ausw\u00E4hlen diff --git a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties index 4930a2b5ed57688d22f81f6f0653063a9abee37f..1e0c691db08c20b4de1921f3c0abfdacfa37049a 100644 --- a/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/config/ui/_i18n/LocalStrings_en.properties @@ -22,6 +22,7 @@ chkbx.participantlist.onoff=Participant list chkbx.toolbar.explain=Activate tools in toolbar: chkbx.toolbar.onoff=Toolbar visible for participants chkbx.toolbar.off.warning=If you disable the toolbar, the individual tools are also no longer available. +chkbx.wiki.onoff=Wiki chkbx.breadcrumb.onoff=Bread-crumb navigation command.choose=Choose command.glossary.add=Select glossary @@ -30,6 +31,7 @@ course.log.changed.message=<br>Detailed course log files can be downloaded with coursefolder=Storage folder details.options.title=Glossary and resource folder error.no.blog.selected=No blog selected. +error.no.wiki.selected=No wiki selected. form.layout.changecustomcss=Change CSS form.layout.choosecustomcss=Choose your own CSS form.layout.choosesystemcss=Select default CSS @@ -58,4 +60,10 @@ warning.change.todisabled=All evidences of achievement already existing will no warning.change.toenable=By selecting this option evidences of achievement will be created for the entire course. This will take a while. Do you want to proceed? warning.folderRef.title=Attention! warning.folderRef=This resource folder is referenced by at least one folder course node. Removing this resource folder will lead to an inconsistent folder configuration. Do you wish to proceed nevertheless? -warning.folderRefAdd=This resource folder is referenced by at least one folder course node. Changing this resource folder will lead to an inconsistent folder configuration. Do you wish to proceed nevertheless? \ No newline at end of file +warning.folderRefAdd=This resource folder is referenced by at least one folder course node. Changing this resource folder will lead to an inconsistent folder configuration. Do you wish to proceed nevertheless? +wiki.not.selected=No wiki selected +wiki.open={0} +wiki.replace=Replace +wiki.select=Select +wiki.select.button={0} +wiki.select.wiki=Select wiki \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/wiki/_content/WikiToolController.java b/src/main/java/org/olat/course/nodes/wiki/_content/WikiToolController.java new file mode 100644 index 0000000000000000000000000000000000000000..11e4b6e923146515a98fa12ccdd423aeafdfdacc --- /dev/null +++ b/src/main/java/org/olat/course/nodes/wiki/_content/WikiToolController.java @@ -0,0 +1,146 @@ +/** + * <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.nodes.wiki._content; + +import java.util.List; + +import org.olat.basesecurity.GroupRoles; +import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.gui.control.generic.messages.MessageController; +import org.olat.core.gui.control.generic.messages.MessageUIFactory; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; +import org.olat.core.util.UserSession; +import org.olat.core.util.resource.OresHelper; +import org.olat.course.CourseModule; +import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.wiki.DryRunAssessmentProvider; +import org.olat.modules.wiki.PersistingAssessmentProvider; +import org.olat.modules.wiki.WikiAssessmentProvider; +import org.olat.modules.wiki.WikiMainController; +import org.olat.modules.wiki.WikiManager; +import org.olat.modules.wiki.WikiReadOnlySecurityCallback; +import org.olat.modules.wiki.WikiSecurityCallback; +import org.olat.modules.wiki.WikiSecurityCallbackImpl; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryManager; +import org.olat.repository.RepositoryService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 4 Mar 2020<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class WikiToolController extends BasicController implements Activateable2 { + + public static final String SUBSCRIPTION_SUBIDENTIFIER = "wiki"; + + private WikiMainController wikiCtrl; + private MessageController noWikiCtrl; + + @Autowired + private RepositoryManager repositoryManager; + @Autowired + private RepositoryService repositoryService; + + public WikiToolController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv) { + super(ureq, wControl); + + String wikiSoftKey = userCourseEnv.getCourseEnvironment().getCourseConfig().getWikiSoftKey(); + RepositoryEntry wikiEntry = repositoryManager.lookupRepositoryEntryBySoftkey(wikiSoftKey, false); + if (wikiEntry != null) { + //check role + UserSession usess = ureq.getUserSession(); + boolean isAdmininstrator = userCourseEnv.isAdmin(); + boolean isGuestOnly = usess.getRoles().isGuestOnly(); + boolean isResourceOwner = isAdmininstrator || repositoryService.hasRole(getIdentity(), wikiEntry, GroupRoles.owner.name()); + + // Check for jumping to certain wiki page + BusinessControl bc = wControl.getBusinessControl(); + ContextEntry ce = bc.popLauncherContextEntry(); + + String resName = CourseModule.getCourseTypeName(); + Long resId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); + OLATResourceable courseOres = OresHelper.createOLATResourceableInstance(resName, resId); + SubscriptionContext subsContext = new SubscriptionContext(courseOres, SUBSCRIPTION_SUBIDENTIFIER); + WikiSecurityCallback callback; + WikiAssessmentProvider assessmentProvider; + if(userCourseEnv.isCourseReadOnly()) { + callback = new WikiReadOnlySecurityCallback(isGuestOnly, (isAdmininstrator || isResourceOwner)); + assessmentProvider = DryRunAssessmentProvider.create(); + } else { + callback = new WikiSecurityCallbackImpl(Boolean.TRUE, isAdmininstrator, isGuestOnly, false, + isResourceOwner, subsContext); + assessmentProvider = userCourseEnv.isParticipant() + ? PersistingAssessmentProvider.create(wikiEntry, getIdentity()) + : DryRunAssessmentProvider.create(); + } + + + if ( ce != null ) { //jump to a certain context + OLATResourceable ores = ce.getOLATResourceable(); + String typeName = ores.getResourceableTypeName(); + String page = typeName.substring("page=".length()); + if(page.endsWith(":0")) { + page = page.substring(0, page.length() - 2); + } + wikiCtrl = WikiManager.getInstance().createWikiMainController(ureq, wControl, wikiEntry.getOlatResource(), callback, assessmentProvider, page); + } else { + wikiCtrl = WikiManager.getInstance().createWikiMainController(ureq, wControl, wikiEntry.getOlatResource(), callback, assessmentProvider, null); + } + listenTo(wikiCtrl); + putInitialPanel(wikiCtrl.getInitialComponent()); + } else { + String title = translate("tool.no.wiki.title"); + String text = translate("tool.no.wiki.text"); + noWikiCtrl = MessageUIFactory.createInfoMessage(ureq, wControl, title, text); + listenTo(noWikiCtrl); + putInitialPanel(noWikiCtrl.getInitialComponent()); + } + } + + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if (wikiCtrl != null) { + wikiCtrl.activate(ureq, entries, state); + } + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // + } + + @Override + protected void doDispose() { + // + } + +} diff --git a/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_de.properties index fe4ba6f3d2f3e68f82349552199932114f0f9099..063eccc447a809c1e5739ee7bea87ee330316384 100644 --- a/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_de.properties @@ -82,3 +82,5 @@ no.entry.chosen=<i>Kein Wiki ausgew\u00E4hlt</i> pane.tab.accessibility=Zugang pane.tab.wikiconfig=Wiki-Lerninhalt preview=Vorschau +tool.no.wiki.text=F\u00FCr diesen Kurs ist kein Wiki vorhanden. +tool.no.wiki.title=Kein Wiki vorhanden. diff --git a/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_en.properties index 46efef79f42e60294d494193c3d9aa278c1a68f0..cce2ec4eace4536c775839849047d5cf7125cff7 100644 --- a/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/wiki/_i18n/LocalStrings_en.properties @@ -82,3 +82,5 @@ pane.tab.accessibility=Access pane.tab.wikiconfig=Wiki learning content preview=Preview title_wiki=Wiki +tool.no.wiki.text=There is no wiki available for this course. +tool.no.wiki.title=No wiki available diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java index 98ead8bb1d8e39b2e3716557a13b671615ca01d6..74b8cbc3affbc51540291e0b541ba6ccf39e2755 100644 --- a/src/main/java/org/olat/course/run/CourseRuntimeController.java +++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java @@ -113,6 +113,7 @@ import org.olat.course.nodes.fo.FOToolController; import org.olat.course.nodes.info.InfoCourseSecurityCallback; import org.olat.course.nodes.info.InfoRunController; import org.olat.course.nodes.members.MembersToolRunController; +import org.olat.course.nodes.wiki._content.WikiToolController; import org.olat.course.reminder.ui.CourseRemindersController; import org.olat.course.run.calendar.CourseCalendarController; import org.olat.course.run.glossary.CourseGlossaryFactory; @@ -184,7 +185,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im efficiencyStatementsLink, noteLink, leaveLink, // course tools learningPathLink, learningPathsLink, calendarLink, chatLink, participantListLink, participantInfoLink, - blogLink, forumLink, documentsLink, emailLink, searchLink, + blogLink, wikiLink, forumLink, documentsLink, emailLink, searchLink, //glossary openGlossaryLink, enableGlossaryLink, lecturesLink; private Link currentUserCountLink; @@ -193,6 +194,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private CloseableModalController cmc; private COToolController emailCtrl; private BlogToolController blogCtrl; + private WikiToolController wikiCtrl; private FOToolController forumCtrl; private CourseDocumentsController documentsCtrl; private CourseAreasController areasCtrl; @@ -856,6 +858,12 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im toolbarPanel.addTool(blogLink); } + if(!assessmentLock) { + wikiLink = LinkFactory.createToolLink("wiki", translate("command.wiki"), this, "o_wiki_icon"); + wikiLink.setVisible(cc.isWikiEnabled()); + toolbarPanel.addTool(wikiLink); + } + if(!assessmentLock) { forumLink = LinkFactory.createToolLink("forum", translate("command.forum"), this, "o_fo_icon"); forumLink.setVisible(cc.isForumEnabled()); @@ -992,6 +1000,8 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im doEmail(ureq); } else if(blogLink == source) { doBlog(ureq); + } else if(wikiLink == source) { + doWiki(ureq); } else if(forumLink == source) { doForum(ureq); } else if(documentsLink == source) { @@ -1107,6 +1117,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im case participantInfo: doParticipantInfo(ureq); break; case email: doEmail(ureq); break; case blog: doBlog(ureq); break; + case wiki: doWiki(ureq); break; case forum: doForum(ureq); break; case documents: doDocuments(ureq); break; } @@ -1207,6 +1218,14 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im blog.activate(ureq, subEntries, entries.get(0).getTransientState()); } } + } else if("Wiki".equalsIgnoreCase(type)) { + if (wikiLink != null && wikiLink.isVisible()) { + Activateable2 wiki = doWiki(ureq); + if (wiki != null) { + List<ContextEntry> subEntries = entries.subList(1, entries.size()); + wiki.activate(ureq, subEntries, entries.get(0).getTransientState()); + } + } } else if("Forum".equalsIgnoreCase(type)) { if (forumLink != null && forumLink.isVisible()) { doForum(ureq); @@ -1866,6 +1885,23 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im return null; } + private WikiToolController doWiki(UserRequest ureq) { + if(delayedClose == Delayed.wiki || requestForClose(ureq)) { + removeCustomCSS(); + + OLATResourceable ores = OresHelper.createOLATResourceableType("wiki"); + WindowControl swControl = addToHistory(ureq, ores, null); + wikiCtrl = new WikiToolController(ureq, swControl, getUserCourseEnvironment()); + + pushController(ureq, translate("command.wiki"), wikiCtrl); + setActiveTool(wikiLink); + currentToolCtr = wikiCtrl; + return wikiCtrl; + } + delayedClose = Delayed.wiki; + return null; + } + private void doForum(UserRequest ureq) { if(delayedClose == Delayed.forum || requestForClose(ureq)) { removeCustomCSS(); @@ -2060,6 +2096,15 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } break; } + case wiki: { + if(wikiLink != null) { + ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); + CourseConfig cc = course.getCourseEnvironment().getCourseConfig(); + wikiLink.setVisible(cc.isWikiEnabled()); + toolbarPanel.setDirty(true); + } + break; + } case forum: { if(forumLink != null) { ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); @@ -2218,6 +2263,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im participantInfo, email, blog, + wiki, forum, documents } 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 9575dd7198ef8e1638c490fd07087449483c57b4..8cd191878d71f840c835633e3e089163608f1cba 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 @@ -51,6 +51,7 @@ command.previous=Zur\u00FCck zur letzten Seite command.reminders=Erinnerung command.run=Kurs Laufzeitumgebung command.settings=Kursinfo \u00E4ndern +command.wiki=Wiki course.closed=Dieser Kurs wurde beendet und kann nicht mehr bearbeitet oder aktualisiert werden. course.disposed.command.restart=Den Kurs beenden und neu starten course.disposed.message=Bitte beenden Sie diesen Kurs und starten Sie ihn neu. 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 c81dbd89f868b50e226155fd01169c2ba61578a3..7b80373d63bbd5e8c188a75ad4ccadf2a8e9a606 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 @@ -51,6 +51,7 @@ command.previous=Go to previous page command.reminders=Reminders command.run=Course runtime command.settings=Change course info +command.wiki=wiki course.closed=This course is finished and can therefore no longer be edited or updated. course.disposed.command.restart=Close course and restart course.disposed.message=Please close this course and restart. diff --git a/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java b/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java index 963191a90b44db1dcb7be88f14f168691998006e..f58198ff2508f076ba4e08c9b600fe0a957cb1dd 100644 --- a/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java +++ b/src/main/java/org/olat/repository/RepositoryEntryManagedFlag.java @@ -51,6 +51,7 @@ public enum RepositoryEntryManagedFlag { participantInfo(settings, all), email(settings, all), blog(settings, all), + wiki(settings, all), forum(settings, all), documents(settings, all), chat(settings,all),