diff --git a/src/main/java/org/olat/course/nodes/video/VideoEditController.java b/src/main/java/org/olat/course/nodes/video/VideoEditController.java index c6a1358fb68567c7872119eb886c8c306eda37fd..cd70378815359a40b0d6de3826416324733a8105 100644 --- a/src/main/java/org/olat/course/nodes/video/VideoEditController.java +++ b/src/main/java/org/olat/course/nodes/video/VideoEditController.java @@ -27,6 +27,7 @@ import org.olat.core.gui.components.form.flexible.FormUIFactory; import org.olat.core.gui.components.form.flexible.elements.RichTextElement; import org.olat.core.gui.components.form.flexible.elements.SelectionElement; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; +import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.link.Link; @@ -41,7 +42,11 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.tabbable.ActivateableTabbableDefaultController; import org.olat.core.logging.AssertException; +import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; +import org.olat.core.util.filter.FilterFactory; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSContainerMapper; import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentHelper; import org.olat.course.condition.Condition; @@ -56,6 +61,8 @@ import org.olat.modules.video.ui.VideoDisplayController; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.controllers.ReferencableEntriesSearchController; +import org.olat.repository.handlers.RepositoryHandler; +import org.olat.repository.handlers.RepositoryHandlerFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -95,6 +102,7 @@ public class VideoEditController extends ActivateableTabbableDefaultController private final VideoCourseNode videoNode; private RepositoryEntry repositoryEntry; + private VideoOptionsForm videoOptionsCtrl; private ReferencableEntriesSearchController searchController; private Link previewLink; @@ -234,9 +242,11 @@ public class VideoEditController extends ActivateableTabbableDefaultController fireEvent(urequest, NodeEditController.NODECONFIG_CHANGED_EVENT); videoConfigurationVc.contextPut("showOptions", Boolean.TRUE); - VideoOptionsForm videoOptions = new VideoOptionsForm(urequest, getWindowControl(), repositoryEntry, config); - videoConfigurationVc.put("videoOptions", videoOptions.getInitialComponent()); - listenTo(videoOptions); + + removeAsListenerAndDispose(videoOptionsCtrl); + videoOptionsCtrl = new VideoOptionsForm(urequest, getWindowControl(), repositoryEntry, config); + videoConfigurationVc.put("videoOptions", videoOptionsCtrl.getInitialComponent()); + listenTo(videoOptionsCtrl); } } } else if (source == accessibilityCondContr) { @@ -318,26 +328,35 @@ class VideoOptionsForm extends FormBasicController{ @Autowired protected VideoManager videoManager; - private RepositoryEntry repoEntry; private SelectionElement videoComments; private SelectionElement videoRating; private SelectionElement videoAutoplay; private SingleSelection description; private RichTextElement descriptionField; + private StaticTextElement descriptionRepoField; private boolean commentsEnabled; private boolean ratingEnabled; private boolean autoplay; - private ModuleConfiguration config; - - + + private String mediaRepoBaseUrl; + private final RepositoryEntry repoEntry; + private final ModuleConfiguration config; VideoOptionsForm(UserRequest ureq, WindowControl wControl, RepositoryEntry repoEntry, ModuleConfiguration moduleConfiguration) { super(ureq, wControl); this.config = moduleConfiguration; this.repoEntry = repoEntry; - this.commentsEnabled = config.getBooleanSafe(VideoEditController.CONFIG_KEY_COMMENTS); - this.ratingEnabled = config.getBooleanSafe(VideoEditController.CONFIG_KEY_RATING); - this.autoplay = config.getBooleanSafe(VideoEditController.CONFIG_KEY_AUTOPLAY); + + commentsEnabled = config.getBooleanSafe(VideoEditController.CONFIG_KEY_COMMENTS); + ratingEnabled = config.getBooleanSafe(VideoEditController.CONFIG_KEY_RATING); + autoplay = config.getBooleanSafe(VideoEditController.CONFIG_KEY_AUTOPLAY); + + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repoEntry); + VFSContainer mediaContainer = handler.getMediaContainer(repoEntry); + if(mediaContainer != null) { + mediaRepoBaseUrl = registerMapper(ureq, new VFSContainerMapper(mediaContainer.getParentContainer())); + } + initForm(ureq); } @@ -376,6 +395,8 @@ class VideoOptionsForm extends FormBasicController{ description.select(config.getStringValue(VideoEditController.CONFIG_KEY_DESCRIPTION_SELECT,"none"), true); String desc = repoEntry.getDescription(); descriptionField = uifactory.addRichTextElementForStringDataMinimalistic("description", "", desc, -1, -1, formLayout, getWindowControl()); + descriptionRepoField = uifactory.addStaticTextElement("description.repo", "", "", formLayout); + updateDescriptionField(); uifactory.addFormSubmitButton("submit", formLayout); //init options-config @@ -395,14 +416,26 @@ class VideoOptionsForm extends FormBasicController{ String selectDescOption = description.getSelectedKey(); if("none".equals(selectDescOption)) { descriptionField.setVisible(false); + descriptionRepoField.setVisible(false); } else if("resourceDescription".equals(selectDescOption)) { - descriptionField.setVisible(true); - descriptionField.setValue(repoEntry.getDescription()); + descriptionField.setVisible(false); descriptionField.setEnabled(false); + + String text = repoEntry.getDescription(); + if(StringHelper.containsNonWhitespace(text)) { + text = StringHelper.xssScan(text); + if(mediaRepoBaseUrl != null) { + text = FilterFactory.getBaseURLToMediaRelativeURLFilter(mediaRepoBaseUrl).filter(text); + } + text = Formatter.formatLatexFormulas(text); + } + descriptionRepoField.setValue(text); + descriptionRepoField.setVisible(true); } else if("customDescription".equals(selectDescOption)) { descriptionField.setVisible(true); - descriptionField.setValue(config.getStringValue(VideoEditController.CONFIG_KEY_DESCRIPTION_CUSTOMTEXT, "")); descriptionField.setEnabled(true); + descriptionField.setValue(config.getStringValue(VideoEditController.CONFIG_KEY_DESCRIPTION_CUSTOMTEXT, "")); + descriptionRepoField.setVisible(false); } } @@ -412,6 +445,7 @@ class VideoOptionsForm extends FormBasicController{ updateDescriptionField(); } } + @Override protected void doDispose() { // diff --git a/src/main/java/org/olat/modules/video/ui/VideoDisplayController.java b/src/main/java/org/olat/modules/video/ui/VideoDisplayController.java index d0db7cdd6ab5c958c32e69d86b4cb199bd777695..a7d7bb0f35416805e8b35765cd944430c8668887 100644 --- a/src/main/java/org/olat/modules/video/ui/VideoDisplayController.java +++ b/src/main/java/org/olat/modules/video/ui/VideoDisplayController.java @@ -35,9 +35,12 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; +import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; +import org.olat.core.util.filter.FilterFactory; import org.olat.core.util.prefs.Preferences; import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSContainerMapper; import org.olat.core.util.vfs.VFSLeaf; import org.olat.modules.video.VideoManager; import org.olat.modules.video.VideoMetadata; @@ -45,6 +48,8 @@ import org.olat.modules.video.VideoModule; import org.olat.modules.video.VideoTranscoding; import org.olat.modules.video.manager.VideoMediaMapper; import org.olat.repository.RepositoryEntry; +import org.olat.repository.handlers.RepositoryHandler; +import org.olat.repository.handlers.RepositoryHandlerFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -69,6 +74,7 @@ public class VideoDisplayController extends BasicController { private RepositoryEntry entry; private String descriptionText; + private String mediaRepoBaseUrl; public VideoDisplayController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, boolean autoWidth) { @@ -86,6 +92,12 @@ public class VideoDisplayController extends BasicController { mainVC = createVelocityContainer("video_run"); putInitialPanel(mainVC); + + RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(entry); + VFSContainer mediaContainer = handler.getMediaContainer(entry); + if(mediaContainer != null) { + mediaRepoBaseUrl = registerMapper(ureq, new VFSContainerMapper(mediaContainer.getParentContainer())); + } // load mediaelementjs player and sourcechooser plugin StringOutput sb = new StringOutput(50); @@ -153,6 +165,22 @@ public class VideoDisplayController extends BasicController { VFSLeaf video = videoManager.getMasterVideoFile(entry.getOlatResource()); loadVideo(video); } + + /** + * Set the text with url rewrite for embedded images, latex... + * @param text + * @param key + */ + private void setText(String text, String key) { + if(StringHelper.containsNonWhitespace(text)) { + text = StringHelper.xssScan(text); + if(mediaRepoBaseUrl != null) { + text = FilterFactory.getBaseURLToMediaRelativeURLFilter(mediaRepoBaseUrl).filter(text); + } + text = Formatter.formatLatexFormulas(text); + } + mainVC.contextPut(key, text); + } /** * Internal helper to do the actual video loading, checking for transcoded versions and captions @@ -161,8 +189,8 @@ public class VideoDisplayController extends BasicController { */ private void loadVideo(VFSLeaf video) { mainVC.contextPut("title", entry.getDisplayname()); - String desc = (descriptionText != null ? descriptionText : entry.getDescription()); - mainVC.contextPut("description", (StringHelper.containsNonWhitespace(desc) ? desc : null)); + String desc = (descriptionText != null ? descriptionText : entry.getDescription()); + setText(desc, "description"); String authors = entry.getAuthors(); mainVC.contextPut("authors", (StringHelper.containsNonWhitespace(authors) ? authors : null));