From 8c3792280ee6f7bf3ef198447ab7b7c1d4663754 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Wed, 7 Dec 2011 16:30:18 +0100 Subject: [PATCH] FXOLAT-391: backport back/resume function (and configurable home, system admin tab...) --- .../olat/vitero/_spring/viteroContext.xml | 2 + .../java/org/olat/NewControllerFactory.java | 41 +- .../olat/admin/SystemAdminMainController.java | 366 +--------- .../olat/admin/UserAdminMainController.java | 215 ++++-- .../admin/_i18n/LocalStrings_de.properties | 8 +- .../admin/_i18n/LocalStrings_en.properties | 6 + .../java/org/olat/admin/site/AdminSite.java | 7 +- .../org/olat/admin/site/UserAdminSite.java | 7 +- .../olat/admin/sysinfo/SysinfoController.java | 14 +- .../olat/admin/user/UserAdminController.java | 22 +- .../olat/admin/user/UserSearchController.java | 16 +- .../user/UsermanagerUserSearchController.java | 114 +++- .../user/delete/TabbedPaneController.java | 16 +- .../BookmarksPortletRunController.java | 13 +- .../olat/catalog/ui/CatalogController.java | 96 ++- .../ui/KalendarEntryDetailsController.java | 1 + .../calendar/ui/WeeklyCalendarController.java | 8 +- .../FileChooseCreateEditController.java | 1 - .../InfoMessagePortletRunController.java | 17 +- .../chiefcontrollers/BaseChiefController.java | 21 +- .../fullWebApp/BaseFullWebappController.java | 156 ++++- .../fullWebApp/LayoutMain3ColsController.java | 32 +- .../modules/bc/FolderRunController.java | 43 +- .../core/extensions/AbstractExtension.java | 40 +- .../org/olat/core/extensions/ExtManager.java | 108 ++- .../org/olat/core/extensions/Extension.java | 25 +- .../extensions/action/ActionExtension.java | 14 + .../action/GenericActionExtension.java | 110 ++- .../GuestOnlyExtensionSecurityCallback.java | 45 ++ .../UserOnlyExtensionSecurityCallback.java | 48 ++ .../java/org/olat/core/gui/UserRequest.java | 12 + .../org/olat/core/gui/components/Window.java | 12 +- .../gui/components/tabbedpane/TabbedPane.java | 29 +- .../core/gui/control/DefaultController.java | 32 + .../generic/docking/DockController.java | 4 + .../control/generic/dtabs/Activateable2.java | 44 ++ .../core/gui/control/generic/dtabs/DTab.java | 6 + .../gui/control/generic/dtabs/DTabImpl.java | 11 +- .../core/gui/control/generic/dtabs/DTabs.java | 27 + .../generic/layout/GenericMainController.java | 285 ++++++-- .../control/navigation/BornSiteInstance.java | 3 +- .../olat/core/id/context/BusinessControl.java | 6 + .../id/context/BusinessControlFactory.java | 212 ++++-- .../olat/core/id/context/ContextEntry.java | 11 +- .../ContextEntryControllerCreator2.java | 30 + .../olat/core/id/context/HistoryManager.java | 106 +++ .../olat/core/id/context/HistoryModule.java | 137 ++++ .../olat/core/id/context/HistoryPoint.java | 39 ++ .../core/id/context/HistoryPointImpl.java | 68 ++ .../id/context/StackedBusinessControl.java | 13 + .../org/olat/core/id/context/StateEntry.java | 34 + .../org/olat/core/id/context/StateMapped.java | 79 +++ .../org/olat/core/id/context/StateSite.java | 62 ++ .../id/context/_spring/historyCorecontext.xml | 43 ++ .../java/org/olat/core/util/CodeHelper.java | 6 + .../java/org/olat/core/util/UserSession.java | 74 +- ...esourceableListeningWrapperController.java | 20 +- .../org/olat/core/util/event/EventAgency.java | 21 +- .../org/olat/core/util/tree/TreeHelper.java | 12 + .../DisposedCourseRestartController.java | 5 +- .../archiver/ArchiverMainController.java | 6 +- .../EfficiencyStatementsListController.java | 5 +- ...iciencyStatementsPortletRunController.java | 15 +- .../olat/course/nodes/CourseNodeFactory.java | 3 +- .../org/olat/course/nodes/STCourseNode.java | 4 +- .../nodes/bc/BCCourseNodeRunController.java | 16 +- .../olat/course/nodes/cp/CPRunController.java | 14 +- .../nodes/fo/FOCourseNodeRunController.java | 19 +- .../olat/course/nodes/iq/IQRunController.java | 22 +- .../PortfolioCourseNodeRunController.java | 2 +- .../course/nodes/wiki/WikiEditController.java | 3 +- .../course/nodes/wiki/WikiRunController.java | 13 +- .../olat/course/run/RunMainController.java | 71 +- .../olat/group/site/GroupsManagementSite.java | 7 +- .../java/org/olat/group/site/GroupsSite.java | 7 +- .../olat/group/ui/BGControllerFactory.java | 2 +- .../BGContextManagementController.java | 76 ++- .../ui/edit/BusinessGroupEditController.java | 25 +- .../olat/group/ui/main/BGMainController.java | 68 +- .../run/BusinessGroupMainRunController.java | 167 ++++- .../olat/home/GuestHomeInfoController.java | 63 ++ .../org/olat/home/HomeMainController.java | 634 ++---------------- src/main/java/org/olat/home/HomeSite.java | 95 +++ src/main/java/org/olat/home/HomeSiteDef.java | 52 ++ .../home/UserSearchAndInfoController.java | 107 +++ .../home/_i18n/LocalStrings_de.properties | 4 +- .../home/_i18n/LocalStrings_en.properties | 6 +- .../org/olat/home/_spring/homeContext.xml | 209 ++++++ .../GuestHomeCEControllerCreator.java | 61 ++ .../HomePortalControllerCreator.java | 137 ++++ .../ManageBookmarkControllerCreator.java | 60 ++ .../NotificationsControllerCreator.java | 60 ++ .../PersonalFolderControllerCreator.java | 60 ++ .../controllerCreators/_content/welcome.html | 96 +++ .../java/org/olat/home/site/HomeSite.java | 90 --- .../java/org/olat/home/site/HomeSiteDef.java | 95 --- .../org/olat/ldap/ui/LDAPAdminExtension.java | 4 +- .../login/OLATAuthenticationController.java | 12 +- .../olat/modules/cp/CPDisplayController.java | 53 +- .../java/org/olat/modules/cp/CPUIFactory.java | 7 +- .../org/olat/modules/fo/ForumController.java | 23 +- .../org/olat/modules/fo/ForumManager.java | 5 +- .../olat/modules/iq/IQDisplayController.java | 48 +- .../java/org/olat/modules/iq/IQManager.java | 3 +- .../scorm/ScormAPIandDisplayController.java | 2 +- .../olat/modules/wiki/WikiMainController.java | 24 +- .../org/olat/modules/wiki/WikiManager.java | 3 +- .../olat/note/NotesPortletRunController.java | 19 +- .../NotificationNewsController.java | 41 +- ...ficationSubscriptionAndNewsController.java | 24 +- .../NotificationsPortletRunController.java | 8 +- .../CalendarPortletRunController.java | 14 +- .../QuickstartPortletRunController.java | 2 +- .../portfolio/EPArtefactPoolExtension.java | 2 +- .../portfolio/EPMapOnInvitationExtension.java | 1 + .../org/olat/portfolio/EPMyMapsExtension.java | 10 +- .../EPMyStructuredMapsExtension.java | 2 +- .../olat/portfolio/EPOtherMapsExtension.java | 2 +- .../java/org/olat/portfolio/EPUIFactory.java | 3 +- .../portfolio/_spring/portfolioContext.xml | 104 ++- .../ui/structel/EPMultipleMapController.java | 2 +- .../RepositoryDetailsController.java | 11 +- .../controllers/RepositoryMainController.java | 69 +- .../RepositorySearchController.java | 19 +- .../RepositoryPortletRunController.java | 3 +- .../olat/repository/site/RepositorySite.java | 7 +- .../org/olat/user/ChangePrefsController.java | 71 +- .../olat/user/PersonalSettingsController.java | 21 +- .../ProfileAndHomePageEditController.java | 3 - .../user/_i18n/LocalStrings_de.properties | 7 + .../user/_i18n/LocalStrings_en.properties | 7 + .../resources/serviceconfig/olat.properties | 29 +- .../org/olat/_spring/extensionContext.xml | 362 +++++++++- .../org/olat/_spring/sitedefContext.xml | 3 +- src/main/webapp/WEB-INF/web.xml | 7 +- 135 files changed, 4882 insertions(+), 1584 deletions(-) create mode 100644 src/main/java/org/olat/core/extensions/security/GuestOnlyExtensionSecurityCallback.java create mode 100644 src/main/java/org/olat/core/extensions/security/UserOnlyExtensionSecurityCallback.java create mode 100644 src/main/java/org/olat/core/gui/control/generic/dtabs/Activateable2.java create mode 100644 src/main/java/org/olat/core/id/context/ContextEntryControllerCreator2.java create mode 100644 src/main/java/org/olat/core/id/context/HistoryManager.java create mode 100644 src/main/java/org/olat/core/id/context/HistoryModule.java create mode 100644 src/main/java/org/olat/core/id/context/HistoryPoint.java create mode 100644 src/main/java/org/olat/core/id/context/HistoryPointImpl.java create mode 100644 src/main/java/org/olat/core/id/context/StateEntry.java create mode 100644 src/main/java/org/olat/core/id/context/StateMapped.java create mode 100644 src/main/java/org/olat/core/id/context/StateSite.java create mode 100644 src/main/java/org/olat/core/id/context/_spring/historyCorecontext.xml create mode 100644 src/main/java/org/olat/home/GuestHomeInfoController.java create mode 100644 src/main/java/org/olat/home/HomeSite.java create mode 100644 src/main/java/org/olat/home/HomeSiteDef.java create mode 100644 src/main/java/org/olat/home/UserSearchAndInfoController.java create mode 100644 src/main/java/org/olat/home/_spring/homeContext.xml create mode 100644 src/main/java/org/olat/home/controllerCreators/GuestHomeCEControllerCreator.java create mode 100644 src/main/java/org/olat/home/controllerCreators/HomePortalControllerCreator.java create mode 100644 src/main/java/org/olat/home/controllerCreators/ManageBookmarkControllerCreator.java create mode 100644 src/main/java/org/olat/home/controllerCreators/NotificationsControllerCreator.java create mode 100644 src/main/java/org/olat/home/controllerCreators/PersonalFolderControllerCreator.java create mode 100644 src/main/java/org/olat/home/controllerCreators/_content/welcome.html delete mode 100644 src/main/java/org/olat/home/site/HomeSite.java delete mode 100644 src/main/java/org/olat/home/site/HomeSiteDef.java diff --git a/src/main/java/com/frentix/olat/vitero/_spring/viteroContext.xml b/src/main/java/com/frentix/olat/vitero/_spring/viteroContext.xml index fda0fb3d3d5..ac511df7eaf 100644 --- a/src/main/java/com/frentix/olat/vitero/_spring/viteroContext.xml +++ b/src/main/java/com/frentix/olat/vitero/_spring/viteroContext.xml @@ -54,6 +54,8 @@ <property name="factoryMethod" value="createViteroAdminController"/> </bean> </property> + <property name="navigationKey" value="vitero" /> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> <property name="i18nActionKey" value="admin.menu.title"/> <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> <property name="translationPackage" value="com.frentix.olat.vitero.ui"/> diff --git a/src/main/java/org/olat/NewControllerFactory.java b/src/main/java/org/olat/NewControllerFactory.java index 0118cd780f9..baaf0629c64 100644 --- a/src/main/java/org/olat/NewControllerFactory.java +++ b/src/main/java/org/olat/NewControllerFactory.java @@ -21,7 +21,9 @@ */ package org.olat; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.olat.core.gui.UserRequest; @@ -36,6 +38,8 @@ import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.ContextEntryControllerCreator; +import org.olat.core.id.context.ContextEntryControllerCreator2; +import org.olat.core.logging.AssertException; import org.olat.core.logging.LogDelegator; import org.olat.core.util.resource.OresHelper; import org.olat.repository.RepositoryEntry; @@ -128,10 +132,11 @@ public class NewControllerFactory extends LogDelegator { // Check for RepositoryEntry resource boolean ceConsumed = false; + RepositoryEntry re = null; if (ores.getResourceableTypeName().equals(OresHelper.calculateTypeName(RepositoryEntry.class))) { // It is a repository-entry => get OLATResourceable from RepositoryEntry RepositoryManager repom = RepositoryManager.getInstance(); - RepositoryEntry re = repom.lookupRepositoryEntry(ores.getResourceableId()); + re = repom.lookupRepositoryEntry(ores.getResourceableId()); if (re != null){ ores = re.getOlatResource(); ceConsumed = true; @@ -162,12 +167,21 @@ public class NewControllerFactory extends LogDelegator { if (!typeHandler.validateContextEntryAndShowError(mainCe, ureq, wControl)){ //simply return and don't throw a red screen return; - } - - String siteClassName = typeHandler.getSiteClassName(mainCe); + } + + //fxdiff BAKS-7 Resume function + String siteClassName; + if(typeHandler instanceof ContextEntryControllerCreator2) { + siteClassName = ((ContextEntryControllerCreator2)typeHandler).getSiteClassName(ureq, mainCe); + } else { + siteClassName = typeHandler.getSiteClassName(mainCe); + } + // open in existing site if (siteClassName != null) { // use special activation key to trigger the activate method + //fxdiff BAKS-7 Resume function + List<ContextEntry> entries = new ArrayList<ContextEntry>(); String viewIdentifyer = null; if (bc.hasContextEntry()) { ContextEntry subContext = bc.popLauncherContextEntry(); @@ -181,6 +195,10 @@ public class NewControllerFactory extends LogDelegator { viewIdentifyer = viewIdentifyer + ":" + subResource.getResourceableId(); } } + entries.add(subContext); + while(bc.hasContextEntry()) { + entries.add(bc.popLauncherContextEntry()); + } } } else if (!ceConsumed) { //the olatresourceable is not in a dynamic tab but in a fix one @@ -193,26 +211,35 @@ public class NewControllerFactory extends LogDelegator { } } } - dts.activateStatic(ureq, siteClassName, viewIdentifyer); + dts.activateStatic(ureq, siteClassName, viewIdentifyer, entries); } else { + List<ContextEntry> entries = new ArrayList<ContextEntry>(); + // or create new tab String tabName = typeHandler.getTabName(mainCe); // create and add Tab - dt = dts.createDTab(ores, tabName); + dt = dts.createDTab(ores, re, tabName); if (dt == null) { // tabs are full: TODO // user error message is generated in BaseFullWebappController, nothing // to do here } else { + while(bc.hasContextEntry()) { + entries.add(bc.popLauncherContextEntry()); + } WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, dt.getWindowControl()); Controller launchC = typeHandler.createController(mainCe, ureq, bwControl); + if (launchC == null) { + throw new AssertException("ControllerFactory could not create a controller to be launched. Please validate businesspath " + + bc.getAsString() + " for type " + typeHandler.getClass().getName() + " in advance with validateContextEntryAndShowError()."); + } dt.setController(launchC); dts.addDTab(dt); } - dts.activate(ureq, dt, null); // null: do not activate to a certain view + dts.activate(ureq, dt, null, entries); // null: do not activate to a certain view } } diff --git a/src/main/java/org/olat/admin/SystemAdminMainController.java b/src/main/java/org/olat/admin/SystemAdminMainController.java index c10620c8539..c40cc964890 100644 --- a/src/main/java/org/olat/admin/SystemAdminMainController.java +++ b/src/main/java/org/olat/admin/SystemAdminMainController.java @@ -21,360 +21,52 @@ package org.olat.admin; -import org.olat.admin.extensions.ExtensionsAdminController; -import org.olat.admin.instantMessaging.InstantMessagingAdminController; -import org.olat.admin.jmx.JMXInfoController; -import org.olat.admin.layout.LayoutAdminController; -import org.olat.admin.notifications.NotificationsEmailAdminController; -import org.olat.admin.properties.AdvancedPropertiesController; -import org.olat.admin.quota.QuotaController; -import org.olat.admin.registration.SystemRegistrationAdminController; -import org.olat.admin.restapi.RestapiAdminController; -import org.olat.admin.search.SearchAdminController; -import org.olat.admin.statistics.StatisticsAdminController; -import org.olat.admin.sysinfo.SysinfoController; -import org.olat.admin.version.VersionAdminController; -import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; -import org.olat.core.extensions.ExtManager; -import org.olat.core.extensions.Extension; -import org.olat.core.extensions.action.ActionExtension; -import org.olat.core.extensions.action.GenericActionExtension; +import java.util.List; + import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.panel.Panel; -import org.olat.core.gui.components.tree.GenericTreeModel; -import org.olat.core.gui.components.tree.GenericTreeNode; -import org.olat.core.gui.components.tree.MenuTree; -import org.olat.core.gui.components.tree.TreeModel; -import org.olat.core.gui.components.tree.TreeNode; import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.MainLayoutBasicController; -import org.olat.core.gui.translator.Translator; -import org.olat.core.util.i18n.I18nModule; -import org.olat.core.util.i18n.ui.I18nUIFactory; -import org.olat.core.util.nodes.INode; -import org.olat.instantMessaging.InstantMessagingModule; -import org.olat.search.service.SearchServiceFactory; +import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.gui.control.generic.layout.GenericMainController; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; /** - * Description: - * <p> - * The System admin main controller offers various administrative tools for - * users with administative rights. The controller menu can be extended using - * the ActionExtension interface - * <p> + * <h3>Description:</h3> Creates a MainController, which is configurable by + * olat_extensions + * * Initial Date: Apr 27, 2004 * * @author Felix Jost + * @author strentini, sergio.trentini@frentix.com, www.frentix.com + * */ -public class SystemAdminMainController extends MainLayoutBasicController { - private static boolean extensionLogged = false; - private static boolean configExtensionLogged = false; +public class SystemAdminMainController extends GenericMainController implements Activateable, Activateable2 { - private MenuTree olatMenuTree; - private Panel content; - - private LayoutMain3ColsController columnsLayoutCtr; - private Controller contentCtr; - - /** - * Constructor of the home main controller - * @param ureq The user request - * @param wControl The current window controller - */ public SystemAdminMainController(UserRequest ureq, WindowControl wControl) { - super(ureq, wControl); - - olatMenuTree = new MenuTree("olatMenuTree"); - TreeModel tm = buildTreeModel(); - olatMenuTree.setTreeModel(tm); - INode firstNode = tm.getRootNode().getChildAt(0); - olatMenuTree.setSelectedNodeId(firstNode.getIdent()); - olatMenuTree.addListener(this); - - String cmd = (String) tm.getRootNode().getUserObject(); - contentCtr = createController(cmd, ureq); - listenTo(contentCtr); // auto dispose later - Component resComp = contentCtr.getInitialComponent(); - - content = new Panel("content"); - content.setContent(resComp); - - columnsLayoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), olatMenuTree,null, content, "sysadminmain"); - columnsLayoutCtr.addCssClassToMain("o_admin"); - - listenTo(columnsLayoutCtr); // auto dispose later - putInitialPanel(columnsLayoutCtr.getInitialComponent()); + super(ureq, wControl); + init(ureq); } - + /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) + * @see org.olat.core.gui.control.generic.layout.GenericMainController#handleOwnMenuTreeEvent(java.lang.Object, + * org.olat.core.gui.UserRequest) */ - public void event(UserRequest ureq, Component source, Event event) { - if (source == olatMenuTree) { - if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_CLICKED)) { // process menu commands - TreeNode selTreeNode = olatMenuTree.getSelectedNode(); - if (selTreeNode.getDelegate() != null) { - selTreeNode= selTreeNode.getDelegate(); - olatMenuTree.setSelectedNode(selTreeNode); // enable right element - } - // cleanup old content controller (never null) - removeAsListenerAndDispose(contentCtr); - // create new content controller - contentCtr = createController(selTreeNode.getUserObject(), ureq); - listenTo(contentCtr); - Component resComp = contentCtr.getInitialComponent(); - content.setContent(resComp); - } else { // the action was not allowed anymore - content.setContent(null); // display an empty field (empty panel) - } - } else { - logWarn("Unhandled olatMenuTree event: " + event.getCommand(), null); - } - } - - private Controller createController(Object uobject, UserRequest ureq) { - if (uobject.equals("jmx")) { - return new JMXInfoController(ureq, getWindowControl()); - } else if (uobject.equals("sysinfo") || uobject.equals("admin")) { - return new SysinfoController(ureq, getWindowControl()); - } else if (uobject.equals("imadmin")) { - return new InstantMessagingAdminController(ureq, getWindowControl()); - } else if (uobject.equals("registration")) { - return new SystemRegistrationAdminController(ureq, getWindowControl()); - } else if (uobject.equals("quota")) { - return new QuotaController(ureq, getWindowControl()); - } else if (uobject.equals("advancedproperties")) { - return new AdvancedPropertiesController(ureq, getWindowControl()); - } else if (uobject.equals("onlinetranslation")) { - return I18nUIFactory.createTranslationToolLauncherController(ureq, getWindowControl()); - } else if (uobject.equals("search")) { - return new SearchAdminController(ureq, getWindowControl()); - } else if (uobject.equals("notifications")) { - return new NotificationsEmailAdminController(ureq, getWindowControl()); - } else if (uobject.equals("statistics")) { - return new StatisticsAdminController(ureq, getWindowControl()); - } else if(uobject.equals("layout")){ - return new LayoutAdminController(ureq, getWindowControl()); - } else if(uobject.equals("i18n")){ - return I18nUIFactory.createI18nConfigurationController(ureq, getWindowControl()); - } else if(uobject.equals("versions")){ - return new VersionAdminController(ureq, getWindowControl()); - } else if(uobject.equals("restapi")){ - return new RestapiAdminController(ureq, getWindowControl()); - } else if(uobject.equals("extensions")){ - return new ExtensionsAdminController(ureq, getWindowControl()); - } else if (uobject instanceof ActionExtension) { - ActionExtension ae = (ActionExtension) uobject; - return ae.createController(ureq, getWindowControl(), null); - } + @Override + protected Controller handleOwnMenuTreeEvent(Object uobject, UserRequest ureq) { return null; } - private TreeModel buildTreeModel() { - GenericTreeNode gtnChild, admin, confSub; - Translator translator = getTranslator(); - - GenericTreeModel gtm = new GenericTreeModel(); - admin = new GenericTreeNode(); - admin.setTitle(translator.translate("menu.admin")); - admin.setUserObject("admin"); - admin.setAltText(translator.translate("menu.admin.alt")); - gtm.setRootNode(admin); - - // - // The sysinfo stuff - // - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.sysinfo")); - gtnChild.setUserObject("sysinfo"); - gtnChild.setAltText(translator.translate("menu.sysinfo.alt")); - admin.addChild(gtnChild); - admin.setDelegate(gtnChild); - - // - // The system config submenu - // - - confSub = new GenericTreeNode(); - confSub.setTitle(translator.translate("menu.config")); - confSub.setUserObject("config"); - confSub.setAltText(translator.translate("menu.config.alt")); - admin.addChild(confSub); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.layout")); - gtnChild.setUserObject("layout"); - gtnChild.setAltText(translator.translate("menu.layout.alt")); - confSub.addChild(gtnChild); - confSub.setDelegate(gtnChild); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.i18n")); - gtnChild.setUserObject("i18n"); - gtnChild.setAltText(translator.translate("menu.i18n.alt")); - confSub.addChild(gtnChild); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.quota")); - gtnChild.setUserObject("quota"); - gtnChild.setAltText(translator.translate("menu.quota.alt")); - confSub.addChild(gtnChild); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.versions")); - gtnChild.setUserObject("versions"); - gtnChild.setAltText(translator.translate("menu.versions.alt")); - confSub.addChild(gtnChild); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.restapi")); - gtnChild.setUserObject("restapi"); - gtnChild.setAltText(translator.translate("menu.restapi.alt")); - confSub.addChild(gtnChild); - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.extensions")); - gtnChild.setUserObject("extensions"); - gtnChild.setAltText(translator.translate("menu.extensions.alt")); - confSub.addChild(gtnChild); - - // - // other tools and stuff - // - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.registration")); - gtnChild.setUserObject("registration"); - gtnChild.setAltText(translator.translate("menu.registration.alt")); - admin.addChild(gtnChild); - - - if (InstantMessagingModule.isEnabled()) { - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.imadmin")); - gtnChild.setUserObject("imadmin"); - gtnChild.setAltText(translator.translate("menu.imadmin.alt")); - admin.addChild(gtnChild); - } - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.advancedproperties")); - gtnChild.setUserObject("advancedproperties"); - gtnChild.setAltText(translator.translate("menu.advancedproperties.alt")); - admin.addChild(gtnChild); - - // show translation tool or cusomize link, not both - if (I18nModule.isTransToolEnabled()) { - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.onlinetranslation")); - gtnChild.setUserObject("onlinetranslation"); - gtnChild.setAltText(translator.translate("menu.onlinetranslation.alt")); - admin.addChild(gtnChild); - } else if (I18nModule.isOverlayEnabled()) { - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.onlinetranslation.customize")); - gtnChild.setUserObject("onlinetranslation"); - gtnChild.setAltText(translator.translate("menu.onlinetranslation.customize.alt")); - admin.addChild(gtnChild); - } - - - if (SearchServiceFactory.getService().isEnabled()) { - //since 6.0.3 the search service is distributed - //we have to check if we are the instance having - //the local search service, e.g. the one for creating the index - //and deliver results for queries. - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.search")); - gtnChild.setUserObject("search"); - gtnChild.setAltText(translator.translate("menu.search.alt")); - admin.addChild(gtnChild); - } - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.notifications")); - gtnChild.setUserObject("notifications"); - gtnChild.setAltText(translator.translate("menu.notifications.alt")); - admin.addChild(gtnChild); - - - gtnChild = new GenericTreeNode(); - gtnChild.setTitle(translator.translate("menu.statistics")); - gtnChild.setUserObject("statistics"); - gtnChild.setAltText(translator.translate("menu.statistics.alt")); - admin.addChild(gtnChild); - -// todo: 2009-09.22/cg move JMX menu-item to testing tab, because it is a beta-version -// gtnChild = new GenericTreeNode(); -// gtnChild.setTitle(translator.translate("menu.jmx")); -// gtnChild.setUserObject("jmx"); -// gtnChild.setAltText(translator.translate("menu.jmx.alt")); -// admin.addChild(gtnChild); - - //add extension menues - ExtManager extm = ExtManager.getInstance(); - int cnt = extm.getExtensionCnt(); - for (int i = 0; i < cnt; i++) { - Extension anExt = extm.getExtension(i); - // 1) general menu extensions - ActionExtension ae = (ActionExtension) anExt.getExtensionFor(SystemAdminMainController.class.getName()); - if (ae != null && anExt.isEnabled()) { - gtnChild = new GenericTreeNode(); - String menuText = ae.getActionText(getLocale()); - gtnChild.setTitle(menuText); - gtnChild.setUserObject(ae); - gtnChild.setAltText(ae.getDescription(getLocale())); - if (ae instanceof GenericActionExtension && ((GenericActionExtension) ae).getNodeIdentifierIfParent() != null) { - gtnChild.setIdent(((GenericActionExtension) ae).getNodeIdentifierIfParent()); - } - if (ae instanceof GenericActionExtension && ((GenericActionExtension) ae).getParentTreeNodeIdentifier() != null){ - GenericTreeNode parentNode = (GenericTreeNode) gtm.getNodeById(((GenericActionExtension) ae).getParentTreeNodeIdentifier()); - parentNode.addChild(gtnChild); - if (parentNode.getDelegate() == null) parentNode.setDelegate(gtnChild); - } else { - admin.addChild(gtnChild); - } - // inform only once - if (!extensionLogged) { - extensionLogged = true; - extm.inform(SystemAdminMainController.class, anExt, "added menu entry (for locale " + getLocale().toString() + " '" + menuText + "'"); - } - } - // 2) check for system configuration submenu / dynamic action submenue extensions - ae = (ActionExtension) anExt.getExtensionFor(SystemAdminMainController.class.getName() + "_configuration"); - if (ae != null) { - gtnChild = new GenericTreeNode(); - String menuText = ae.getActionText(getLocale()); - gtnChild.setTitle(menuText); - gtnChild.setUserObject(ae); - gtnChild.setAltText(ae.getDescription(getLocale())); - if (ae instanceof GenericActionExtension && ((GenericActionExtension) ae).getParentTreeNodeIdentifier() != null){ - GenericTreeNode parentNode = (GenericTreeNode) gtm.getNodeById(((GenericActionExtension) ae).getParentTreeNodeIdentifier()); - parentNode.addChild(gtnChild); - if (parentNode.getDelegate() == null) parentNode.setDelegate(gtnChild); - } else { - confSub.addChild(gtnChild); - } - // inform only once - if (!configExtensionLogged) { - configExtensionLogged = true; - extm.inform(SystemAdminMainController.class, anExt, "added configuration submenu entry (for locale " + getLocale().toString() + " '" + menuText + "'"); - } - } - } - - return gtm; + @Override + public void activate(UserRequest ureq, String viewIdentifier) { + super.activate(ureq, viewIdentifier); } - - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ - protected void doDispose() { - // controller disposed by BasicController + + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + super.activate(ureq, entries, state); } -} + +} \ No newline at end of file diff --git a/src/main/java/org/olat/admin/UserAdminMainController.java b/src/main/java/org/olat/admin/UserAdminMainController.java index aaf2512c6c1..3501e101e1c 100644 --- a/src/main/java/org/olat/admin/UserAdminMainController.java +++ b/src/main/java/org/olat/admin/UserAdminMainController.java @@ -56,12 +56,14 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.messages.MessageUIFactory; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -83,7 +85,7 @@ import org.olat.core.util.resource.OresHelper; * To append predefined searches use ActionExtensions and register them for UserAdminMainController.EXTENSIONPOINT_MENU_MENUQUERIES. * </pre> */ -public class UserAdminMainController extends MainLayoutBasicController implements Activateable { +public class UserAdminMainController extends MainLayoutBasicController implements Activateable, Activateable2 { public static final String EXTENSIONPOINT_MENU_MENUQUERIES = ".menu.menuqueries"; private static boolean extensionLogged = false; OLog log = Tracing.createLoggerFor(this.getClass()); @@ -107,14 +109,17 @@ public class UserAdminMainController extends MainLayoutBasicController implement public UserAdminMainController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); olatMenuTree = new MenuTree("olatMenuTree"); - TreeModel tm = buildTreeModel(ureq.getUserSession().getRoles().isOLATAdmin()); + TreeModel tm = buildTreeModel(ureq); olatMenuTree.setTreeModel(tm); - INode firstNode = tm.getRootNode().getChildAt(0); + TreeNode firstNode = (TreeNode)tm.getRootNode().getChildAt(0); olatMenuTree.setSelectedNodeId(firstNode.getIdent()); olatMenuTree.addListener(this); // we always start with a search controller - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl()); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(firstNode.getUserObject().toString(), 0l); + WindowControl bwControl = addToHistory(ureq, ores, null); + contentCtr = new UsermanagerUserSearchController(ureq, bwControl); listenTo(contentCtr); // auto dispose later content = new Panel("content"); @@ -155,7 +160,21 @@ public class UserAdminMainController extends MainLayoutBasicController implement Identity identity = userChoosenEvent.getChosenIdentity(); // cleanup old userAdminCtr controller removeAsListenerAndDispose(userAdminCtr); - userAdminCtr = new UserAdminController(ureq, getWindowControl(), identity); + + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, identity.getKey()); + WindowControl bwControl; + if(contentCtr instanceof UsermanagerUserSearchController) { + UsermanagerUserSearchController ctrl = (UsermanagerUserSearchController)contentCtr; + WindowControl tableControl = ctrl.getTableControl(); + if(tableControl == null) { + tableControl = ctrl.getWindowControlForDebug(); + } + bwControl = addToHistory(ureq, ores, null, tableControl, true); + } else { + bwControl = addToHistory(ureq, ores, null, contentCtr.getWindowControlForDebug(), true); + } + userAdminCtr = new UserAdminController(ureq, bwControl, identity); listenTo(userAdminCtr); // activate a special pane in the tabbed pane when set if ( activatePaneInDetailView != null) @@ -178,6 +197,8 @@ public class UserAdminMainController extends MainLayoutBasicController implement if (contentCtr instanceof UsermanagerUserSearchController) { UsermanagerUserSearchController userSearchCtr = (UsermanagerUserSearchController) contentCtr; userSearchCtr.reloadFoundIdentity(); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, userSearchCtr); } content.setContent(contentCtr.getInitialComponent()); } @@ -190,36 +211,53 @@ public class UserAdminMainController extends MainLayoutBasicController implement if (uobject instanceof ActionExtension) { ActionExtension ae = (ActionExtension) uobject; - contentCtr = ae.createController(ureq, getWindowControl(), null); + //fxdiff BAKS-7 Resume function + TreeNode node = ((GenericTreeModel)olatMenuTree.getTreeModel()).findNodeByUserObject(uobject); + OLATResourceable ores = OresHelper.createOLATResourceableInstance("AE", new Long(node.getPosition())); + WindowControl bwControl = addToHistory(ureq, ores, null); + contentCtr = ae.createController(ureq, bwControl, null); listenTo(contentCtr); return contentCtr.getInitialComponent(); } - + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(uobject.toString(), 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); + //first check if it is node which opens a subtree with further uobject.tree.commands if (uobject.equals("menuroles")) { if (rolesVC == null) rolesVC = createVelocityContainer("systemroles"); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, bwControl); return rolesVC; } else if (uobject.equals("menuqueries")) { if (queriesVC == null) queriesVC = createVelocityContainer("predefinedqueries"); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, bwControl); return queriesVC; } else if (uobject.equals("menuaccess")) { if (queriesVC == null) queriesVC = createVelocityContainer("systemroles"); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, bwControl); return queriesVC; } else if (uobject.equals("userdelete")) { //creates the user deletin controller //if locking fails -> a contentCtrl is created //-> hence removeAsListenerAndDispose(contentCtr) is delegated to the method called! - return createAndLockUserDeleteController(ureq); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, bwControl); + return createAndLockUserDeleteController(ureq, bwControl); } else if (uobject.equals("userdelete_direct")) { //creates the user deletin controller //if locking fails -> a contentCtrl is created //-> hence removeAsListenerAndDispose(contentCtr) is delegated to the method called! - return createAndLockDirectUserDeleteController(ureq); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, bwControl); + return createAndLockDirectUserDeleteController(ureq, bwControl); } //these nodes re-create (not stateful) content Controller (contentCtrl) @@ -227,7 +265,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement removeAsListenerAndDispose(contentCtr); if (uobject.equals("usearch") || uobject.equals("useradmin")) { activatePaneInDetailView = null; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl()); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -241,7 +281,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement Boolean canCreatePwdByConfig = BaseSecurityModule.USERMANAGER_CAN_CREATE_PWD; canCreateOLATPassword = canCreatePwdByConfig.booleanValue(); } - contentCtr = new UserCreateController(ureq, getWindowControl(), canCreateOLATPassword); + //fxdiff BAKS-7 Resume function + contentCtr = new UserCreateController(ureq, bwControl, canCreateOLATPassword); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -255,21 +297,27 @@ public class UserAdminMainController extends MainLayoutBasicController implement Boolean canCreatePwdByConfig = BaseSecurityModule.USERMANAGER_CAN_CREATE_PWD; canCreateOLATPassword = canCreatePwdByConfig.booleanValue(); } - contentCtr = new UserImportController(ureq, getWindowControl(), canCreateOLATPassword); + //fxdiff BAKS-7 Resume function + contentCtr = new UserImportController(ureq, bwControl, canCreateOLATPassword); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("admingroup")) { activatePaneInDetailView = ""; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_ADMIN)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("authorgroup")) { activatePaneInDetailView = "edit.uroles"; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_AUTHORS)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -277,7 +325,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement activatePaneInDetailView = "edit.uroles"; // special case: use user search controller and search for all users that have author rights PermissionOnResourceable[] permissions = {new PermissionOnResourceable(Constants.PERMISSION_HASROLE, Constants.ORESOURCE_AUTHOR)}; - UsermanagerUserSearchController myCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),null, permissions, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + UsermanagerUserSearchController myCtr = new UsermanagerUserSearchController(ureq, bwControl,null, permissions, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); // now subtract users that are in the author group to get the co-authors SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_AUTHORS)}; List identitiesFromAuthorGroup = BaseSecurityManager.getInstance().getVisibleIdentitiesByPowerSearch(null, null, true, secGroup , null, null, null, null); @@ -289,47 +339,61 @@ public class UserAdminMainController extends MainLayoutBasicController implement else if (uobject.equals("resourceowners")) { activatePaneInDetailView = "edit.uroles"; PermissionOnResourceable[] permissions = {new PermissionOnResourceable(Constants.PERMISSION_HASROLE, Constants.ORESOURCE_AUTHOR)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),null, permissions, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,null, permissions, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("groupmanagergroup")) { activatePaneInDetailView = "edit.uroles"; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_GROUPMANAGERS)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("usermanagergroup")) { activatePaneInDetailView = "edit.uroles"; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_USERMANAGERS)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("usergroup")) { activatePaneInDetailView = "edit.uroles"; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_OLATUSERS)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("anonymousgroup")) { activatePaneInDetailView = "edit.uroles"; SecurityGroup[] secGroup = {BaseSecurityManager.getInstance().findSecurityGroupByName(Constants.GROUP_ANONYMOUS)}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,secGroup, null, null, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("logondeniedgroup")) { activatePaneInDetailView = "edit.uroles"; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),null, null, null, null, null, Identity.STATUS_LOGIN_DENIED, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,null, null, null, null, null, Identity.STATUS_LOGIN_DENIED, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("deletedusers")) { activatePaneInDetailView = "list.deletedusers"; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(),null, null, null, null, null, Identity.STATUS_DELETED, false); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl,null, null, null, null, null, Identity.STATUS_DELETED, false); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -338,7 +402,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -7); Date time = cal.getTime(); - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(), null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl, null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -347,7 +413,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, -1); Date time = cal.getTime(); - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(), null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl, null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } @@ -356,19 +424,16 @@ public class UserAdminMainController extends MainLayoutBasicController implement Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, -6); Date time = cal.getTime(); - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(), null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl, null, null, null, time, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else if (uobject.equals("created.newUsersNotification")) { activatePaneInDetailView = null; - ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(new OLATResourceable() { - @Override - public Long getResourceableId() { return 0l; } - @Override - public String getResourceableTypeName() { return "NewIdentityCreated"; } - }); - WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, getWindowControl()); + //fxdiff BAKS-7 Resume function + bwControl = addToHistory(ureq, ores, null); contentCtr = new NewUsersNotificationsController(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); @@ -376,7 +441,9 @@ public class UserAdminMainController extends MainLayoutBasicController implement else if (uobject.equals("noauthentication")) { activatePaneInDetailView = null; String[] auth = {null}; - contentCtr = new UsermanagerUserSearchController(ureq, getWindowControl(), null, null, auth, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + //fxdiff BAKS-7 Resume function + contentCtr = new UsermanagerUserSearchController(ureq, bwControl, null, null, auth, null, null, Identity.STATUS_VISIBLE_LIMIT, true); + addToHistory(ureq, bwControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else{ @@ -391,12 +458,13 @@ public class UserAdminMainController extends MainLayoutBasicController implement * @param ureq * @return */ - private Component createAndLockDirectUserDeleteController(UserRequest ureq) { + //fxdiff BAKS-7 Resume function + private Component createAndLockDirectUserDeleteController(UserRequest ureq, WindowControl wControl) { Controller lockCtrl = acquireDeleteUserLock(ureq); if (lockCtrl == null) { //success -> create new User deletion workflow removeAsListenerAndDispose(contentCtr); - contentCtr = new DirectDeleteController(ureq, getWindowControl()); + contentCtr = new DirectDeleteController(ureq, wControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else { @@ -411,14 +479,15 @@ public class UserAdminMainController extends MainLayoutBasicController implement * @param ureq * @return */ - private Component createAndLockUserDeleteController(UserRequest ureq) { + //fxdiff BAKS-7 Resume function + private Component createAndLockUserDeleteController(UserRequest ureq, WindowControl wControl) { Controller lockCtrl = acquireDeleteUserLock(ureq); if (lockCtrl == null) { //success -> create new User deletion workflow activatePaneInDetailView = null; removeAsListenerAndDispose(contentCtr); - contentCtr = new TabbedPaneController(ureq, getWindowControl()); + contentCtr = new TabbedPaneController(ureq, wControl); listenTo(contentCtr); return contentCtr.getInitialComponent(); } else { @@ -451,7 +520,8 @@ public class UserAdminMainController extends MainLayoutBasicController implement } } - private TreeModel buildTreeModel(boolean isOlatAdmin) { + private TreeModel buildTreeModel(UserRequest ureq) { + boolean isOlatAdmin = ureq.getUserSession().getRoles().isOLATAdmin(); GenericTreeNode gtnChild, admin; Translator translator = getTranslator(); @@ -643,13 +713,82 @@ public class UserAdminMainController extends MainLayoutBasicController implement return gtm; } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + GenericTreeModel tm = (GenericTreeModel)olatMenuTree.getTreeModel(); + ContextEntry entry = entries.get(0); + String entryPoint = entry.getOLATResourceable().getResourceableTypeName(); + if(entryPoint.startsWith("notifications") || entryPoint.startsWith("NewIdentityCreated")) { + TreeNode node = tm.findNodeByUserObject("created.newUsersNotification"); + selectNode(ureq, node); + } else if(entryPoint.startsWith("AE")) { + TreeNode node = tm.findNodeByUserObject("menuqueries"); + int pos = entries.get(0).getOLATResourceable().getResourceableId().intValue(); + if(pos >= 0 && pos < node.getChildCount()) { + TreeNode childNode = (TreeNode)node.getChildAt(pos); + selectNode(ureq, childNode); + } + } else { + TreeNode node = tm.findNodeByUserObject(entryPoint); + if(node != null) { + selectNode(ureq, node); + entries = entries.subList(1, entries.size()); + if(contentCtr instanceof Activateable2) { + ((Activateable2)contentCtr).activate(ureq, entries, entry.getTransientState()); + } + if(!entries.isEmpty() && userAdminCtr != null) { + userAdminCtr.activate(ureq, entries, null); + } + } + } + } + + private void selectNode(UserRequest ureq, TreeNode childNode) { + olatMenuTree.setSelectedNode(childNode); + Component resComp = initComponentFromMenuCommand(childNode.getUserObject(), ureq); + content.setContent(resComp); + } + public void activate(UserRequest ureq, String viewIdentifier) { + if(viewIdentifier == null) return; + if(viewIdentifier.startsWith("notifications") || viewIdentifier.startsWith("NewIdentityCreated")) { GenericTreeModel tm = (GenericTreeModel)olatMenuTree.getTreeModel(); TreeNode node = tm.findNodeByUserObject("created.newUsersNotification"); olatMenuTree.setSelectedNode(node); Component resComp = initComponentFromMenuCommand("created.newUsersNotification", ureq); content.setContent(resComp); + } else if(viewIdentifier.startsWith("AE")) { + String posStr = viewIdentifier.substring(3); + try { + GenericTreeModel treeModel = (GenericTreeModel)olatMenuTree.getTreeModel(); + TreeNode node = treeModel.findNodeByUserObject("menuqueries"); + int pos = Integer.parseInt(posStr); + if(pos >= 0 && pos < node.getChildCount()) { + TreeNode childNode = (TreeNode)node.getChildAt(pos); + olatMenuTree.setSelectedNode(childNode); + Component resComp = initComponentFromMenuCommand(childNode.getUserObject(), ureq); + content.setContent(resComp); + } + } catch (Exception e) { + logWarn("", e); + } + } else { + int first = viewIdentifier.indexOf(":"); + String uobject = viewIdentifier.substring(0, first); + GenericTreeModel treeModel = (GenericTreeModel)olatMenuTree.getTreeModel(); + TreeNode node = treeModel.findNodeByUserObject(uobject); + if(node == null) { + node = treeModel.getRootNode(); + uobject = (String)node.getUserObject(); + } + olatMenuTree.setSelectedNode(node); + Component resComp = initComponentFromMenuCommand(uobject, ureq); + content.setContent(resComp); } } diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties index 10d1097987c..4aafc2c925d 100644 --- a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties @@ -1,4 +1,6 @@ #Mon Mar 02 09:54:03 CET 2009 +main.menu.title=Administration +main.menu.title.alt=Administration bulkuserreplay.chkbx.onoff=Checkbox an heisst Replay ON und AJAX OFF bulkuserreplay.tt=Benutzername Linie f\u00FCr Linie (ohne Komma, oder dergleichen) data.no.save=Achtung\: die \u00C4nderungen gehen nach einem Neustart von OLAT verloren\! Um die Einstellung permanent zu speichern m\u00FCssen Sie die Anpassungen in der <code>olat.properties</code> Datei \u00E4ndern. In zuk\u00FCnftigen Releases wird ein automatisches Speichern m\u00F6glich sein. @@ -95,4 +97,8 @@ menu.versions.alt=Versionierung Einstellungen queries.intro=Unter dem Men\u00FC <i>Vordefinierte Suchabfragen</i> finden Sie oft benutzte Suchabfragen. Spezifischere Suchabfragen k\u00F6nnen mit der Benutzersuche definiert werden. sysroles.intro=Unter dem Men\u00FC <i>Zugang und Rechte</i> finden Sie einen \u00DCberblick der Rechte in und Zug\u00E4nge zu OLAT, die Sie verwalten k\u00F6nnen. menu.extensions=Software Module -menu.extensions.alt=Liste der geladenen Software Module \ No newline at end of file +menu.extensions.alt=Liste der geladenen Software Module +menu.parent.maintenance=Systemwartung +menu.parent.maintenance.alt=Systemwartung und erweiterte Einstellungen +menu.parent.customizing=Customizing +menu.parent.customizing.alt=Anpassungen an OLAT vornehmen \ No newline at end of file diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties index 98d3f0a0565..1797852421d 100644 --- a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties @@ -1,4 +1,6 @@ #Fri Aug 13 18:17:56 CEST 2010 +main.menu.title=Administration +main.menu.title.alt=Administration bulkuserreplay.chkbx.onoff='Check box on' means 'Replay ON' and 'AJAX OFF' bulkuserreplay.tt=User names in separate lines (no comma, etc.) data.no.save=Attention\: your modifications will be lost after an OLAT reboot\! To save your changes permanently you have to adapt the file <code>olat.properties</code>. Future releases will provide you with the possibility to save modifications automatically. @@ -94,3 +96,7 @@ menu.versions=Versioning menu.versions.alt=Versioning settings queries.intro=In the menu <i>Predefined searches</i> you will find often used search queries. You can specify your queries by means of the user search. sysroles.intro=In the menu <i>Access and rights</i> you get an overview of access and rights in OLAT you can administer. +menu.parent.maintenance=System maintenance +menu.parent.maintenance.alt=System maintenance and extended setup +menu.parent.customizing=Customizing +menu.parent.customizing.alt=Customize your OLAT deeply \ No newline at end of file diff --git a/src/main/java/org/olat/admin/site/AdminSite.java b/src/main/java/org/olat/admin/site/AdminSite.java index f112afabe14..143978f29e3 100644 --- a/src/main/java/org/olat/admin/site/AdminSite.java +++ b/src/main/java/org/olat/admin/site/AdminSite.java @@ -35,6 +35,8 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; /** @@ -76,7 +78,10 @@ public class AdminSite implements SiteInstance { * @see org.olat.navigation.SiteInstance#createController(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) */ public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { - MainLayoutController c = ControllerFactory.createLaunchController(ORES_OLATADMINS, null, ureq, wControl, true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(AdminSite.class, 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); + MainLayoutController c = ControllerFactory.createLaunchController(ORES_OLATADMINS, null, ureq, bwControl, true); return c; } diff --git a/src/main/java/org/olat/admin/site/UserAdminSite.java b/src/main/java/org/olat/admin/site/UserAdminSite.java index 4300d993b20..bf47c4c413d 100644 --- a/src/main/java/org/olat/admin/site/UserAdminSite.java +++ b/src/main/java/org/olat/admin/site/UserAdminSite.java @@ -35,6 +35,8 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; /** @@ -70,7 +72,10 @@ public class UserAdminSite implements SiteInstance { * @see org.olat.navigation.SiteInstance#createController(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) */ public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { - MainLayoutController c = ControllerFactory.createLaunchController(ORES_OLATUSERADMINS, null, ureq, wControl, true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(UserAdminSite.class, 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); + MainLayoutController c = ControllerFactory.createLaunchController(ORES_OLATUSERADMINS, null, ureq, bwControl, true); return c; } diff --git a/src/main/java/org/olat/admin/sysinfo/SysinfoController.java b/src/main/java/org/olat/admin/sysinfo/SysinfoController.java index 1ffaea7d0ba..03ebc2c7439 100644 --- a/src/main/java/org/olat/admin/sysinfo/SysinfoController.java +++ b/src/main/java/org/olat/admin/sysinfo/SysinfoController.java @@ -64,7 +64,10 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.creator.AutoCreator; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.helpers.Settings; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.LogFileParser; import org.olat.core.logging.LogRealTimeViewerController; import org.olat.core.logging.OLATSecurityException; @@ -83,7 +86,7 @@ import org.olat.core.util.resource.OresHelper; * * @author Felix Jost */ -public class SysinfoController extends BasicController { +public class SysinfoController extends BasicController implements Activateable2 { private static final String ACTION_SNOOP = "snoop"; private static final String ACTION_ERRORS = "errors"; @@ -269,6 +272,13 @@ public class SysinfoController extends BasicController { + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries != null && entries.isEmpty()) return; + tabbedPane.activate(ureq, entries, state); + } + /** * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) */ @@ -276,6 +286,8 @@ public class SysinfoController extends BasicController { if (source == tabbedPane) { // those must be links TabbedPaneChangedEvent tbcEvent = (TabbedPaneChangedEvent)event; Component newComponent = tbcEvent.getNewComponent(); + //fxdiff BAKS-7 Resume function + tabbedPane.addToHistory(ureq, getWindowControl()); if (newComponent == cachePanel) { if (cacheController != null) { cacheController.dispose(); diff --git a/src/main/java/org/olat/admin/user/UserAdminController.java b/src/main/java/org/olat/admin/user/UserAdminController.java index 753af309903..967d9d73ee1 100644 --- a/src/main/java/org/olat/admin/user/UserAdminController.java +++ b/src/main/java/org/olat/admin/user/UserAdminController.java @@ -21,6 +21,7 @@ package org.olat.admin.user; +import java.util.List; import java.util.Locale; import org.olat.admin.policy.PolicyController; @@ -44,8 +45,11 @@ 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.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATSecurityException; import org.olat.core.util.WebappHelper; import org.olat.core.util.resource.OresHelper; @@ -69,7 +73,7 @@ import org.olat.user.UserPropertiesController; * * </pre> */ -public class UserAdminController extends BasicController implements Activateable { +public class UserAdminController extends BasicController implements Activateable, Activateable2 { // NLS support @@ -151,6 +155,17 @@ public class UserAdminController extends BasicController implements Activateable if (userTabP != null) userTabP.setSelectedPane(translate(viewIdentifier)); // do nothing if not initialized } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + String entryPoint = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if("tab".equals(entryPoint)) { + userTabP.activate(ureq, entries, state); + } else { + activate(ureq, entryPoint); + } + } /** * @param backButtonEnabled @@ -167,6 +182,9 @@ public class UserAdminController extends BasicController implements Activateable public void event(UserRequest ureq, Component source, Event event) { if (source == backLink){ fireEvent(ureq, Event.BACK_EVENT); + //fxdiff BAKS-7 Resume function + } else if (source == userTabP) { + userTabP.addToHistory(ureq, getWindowControl()); } } @@ -239,6 +257,8 @@ public class UserAdminController extends BasicController implements Activateable // first Initialize the user details tabbed pane boolean isOlatAdmin = ureq.getUserSession().getRoles().isOLATAdmin(); userTabP = new TabbedPane("userTabP", ureq.getLocale()); + //fxdiff BAKS-7 Resume function + userTabP.addListener(this); /** * Determine, whether the user admin is or is not able to edit all fields in user diff --git a/src/main/java/org/olat/admin/user/UserSearchController.java b/src/main/java/org/olat/admin/user/UserSearchController.java index 7baa643ed3b..609a7082c39 100644 --- a/src/main/java/org/olat/admin/user/UserSearchController.java +++ b/src/main/java/org/olat/admin/user/UserSearchController.java @@ -122,16 +122,24 @@ public class UserSearchController extends BasicController { private AutoCompleterController autocompleterC; private String actionKeyChoose; - private Map<String, String> userPropertiesSearch; private boolean isAdministrativeUser; private Link backLink; - private static final String STATE_SEARCHFORM = "searchform"; - private static final String STATE_RESULTS = "results"; - public static final String ACTION_KEY_CHOOSE = "action.choose"; public static final String ACTION_KEY_CHOOSE_FINISH = "action.choose.finish"; + + /** + * fxdiff: FXOLAT-250 we need standard-constructor for use in genericMainController + * + * @param ureq + * @param wControl + */ + public UserSearchController(UserRequest ureq, WindowControl wControl) { + this(ureq, wControl, false, false, false); + } + + /** * @param ureq * @param wControl diff --git a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java index d5fd45f5c94..4621075a574 100644 --- a/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java +++ b/src/main/java/org/olat/admin/user/UsermanagerUserSearchController.java @@ -65,6 +65,7 @@ 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.creator.ControllerCreator; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; import org.olat.core.gui.control.generic.wizard.Step; import org.olat.core.gui.control.generic.wizard.StepRunnerCallback; @@ -72,13 +73,18 @@ import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; +import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; +import org.olat.core.id.context.StateMapped; import org.olat.core.logging.AssertException; import org.olat.core.servlets.WebDAVManager; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.mail.ContactList; import org.olat.core.util.mail.ContactMessage; +import org.olat.core.util.resource.OresHelper; import org.olat.login.LoginModule; import org.olat.login.auth.AuthenticationProvider; import org.olat.login.auth.WebDAVAuthManager; @@ -100,7 +106,7 @@ import org.olat.user.propertyhandlers.UserPropertyHandler; * SingleIdentityChosenEvent Alternatively a Canceled Event is fired. * */ -public class UsermanagerUserSearchController extends BasicController { +public class UsermanagerUserSearchController extends BasicController implements Activateable2 { private static final String CMD_MAIL = "exeMail"; private static final String CMD_BULKEDIT = "bulkEditUsers"; @@ -219,6 +225,42 @@ public class UsermanagerUserSearchController extends BasicController { panel = putInitialPanel(userListVC); } + + //fxdiff BAKS-7 Resume function + public WindowControl getTableControl() { + return tableCtr == null ? null : tableCtr.getWindowControlForDebug(); + } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(state instanceof StateMapped) { + StateMapped searchState = (StateMapped)state; + searchform.setStateEntry(searchState); + + if(entries != null && entries.size() > 0) { + String table = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if("table".equals(table)) { + entries.remove(0); + event(ureq, searchform, Event.DONE_EVENT); + } + } + } + + if(entries == null || entries.isEmpty()) return; + + Long identityKey = entries.get(0).getOLATResourceable().getResourceableId(); + if(identityKey != null && identitiesList != null) { + for(Identity identity:identitiesList) { + if(identityKey.equals(identity.getKey())) { + foundIdentity = identity; + fireEvent(ureq, new SingleIdentityChosenEvent(foundIdentity)); + entries.remove(0); + break; + } + } + } + } /** * Remove the given identites from the list of identites in the table model @@ -263,7 +305,10 @@ public class UsermanagerUserSearchController extends BasicController { tdm = ExtendedIdentitiesTableControllerFactory.createTableDataModel(ureq, myIdentities, actionEnabled); removeAsListenerAndDispose(tableCtr); - tableCtr = ExtendedIdentitiesTableControllerFactory.createController(tdm, ureq, getWindowControl(), actionEnabled); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance("table", 0l); + WindowControl bwControl = addToHistory(ureq, ores, null); + tableCtr = ExtendedIdentitiesTableControllerFactory.createController(tdm, ureq, bwControl, actionEnabled); listenTo(tableCtr); if (showEmailButton) { @@ -359,6 +404,13 @@ public class UsermanagerUserSearchController extends BasicController { userListVC.put("userlist", tableCtr.getInitialComponent()); userListVC.contextPut("emptyList", (identitiesList.size() == 0 ? Boolean.TRUE : Boolean.FALSE)); panel.setContent(userListVC); + + //fxdiff BAKS-7 Resume function + ContextEntry currentEntry = getWindowControl().getBusinessControl().getCurrentContextEntry(); + if(currentEntry != null) { + currentEntry.setTransientState(searchform.getStateEntry()); + } + addToHistory(ureq, tableCtr); } else if (event == Event.CANCELLED_EVENT) { fireEvent(ureq, Event.CANCELLED_EVENT); } @@ -655,6 +707,15 @@ class UsermanagerUserSearchForm extends FormBasicController { } return null; } + + //fxdiff BAKS-7 Resume function + protected void setStringValue(String key, String value) { + FormItem f = items.get(key); + if (f == null) return; + if (f instanceof TextElement) { + ((TextElement) f).setValue(value); + } + } protected boolean getRole (String key) { return roles.isSelected(Arrays.asList(roleKeys).indexOf(key)); @@ -677,6 +738,41 @@ class UsermanagerUserSearchForm extends FormBasicController { } return apl.toArray(new String[apl.size()]); } + + //fxdiff BAKS-7 Resume function + protected StateMapped getStateEntry() { + StateMapped state = new StateMapped(); + if(items != null) { + for(Map.Entry<String, FormItem> itemEntry : items.entrySet()) { + String key = itemEntry.getKey(); + FormItem f = itemEntry.getValue(); + if (f instanceof TextElement) { + state.getDelegate().put(key, ((TextElement) f).getValue()); + } + } + } + + if(auth.isMultiselect()) { + //auth. + } + if(roles.isMultiselect()) { + // + } + if(status.isOneSelected()) { + // + } + + return state; + } + + //fxdiff BAKS-7 Resume function + protected void setStateEntry(StateMapped state) { + for(Map.Entry<String, String> entry:state.getDelegate().entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + setStringValue(key, value); + } + } @Override protected void formOK(UserRequest ureq) { @@ -700,13 +796,6 @@ class UsermanagerUserSearchForm extends FormBasicController { for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { if (userPropertyHandler == null) continue; - FormItem fi = userPropertyHandler.addFormItem( - getLocale(), null, getClass().getCanonicalName(), false, formLayout - ); - - fi.setTranslator(tr); - items.put(fi.getName(), fi); - String group = userPropertyHandler.getGroup(); if (!group.equals(currentGroup)) { if (currentGroup != null) { @@ -714,6 +803,13 @@ class UsermanagerUserSearchForm extends FormBasicController { } currentGroup = group; } + + FormItem fi = userPropertyHandler.addFormItem( + getLocale(), null, getClass().getCanonicalName(), false, formLayout + ); + + fi.setTranslator(tr); + items.put(fi.getName(), fi); } uifactory.addSpacerElement("space1", formLayout, false); diff --git a/src/main/java/org/olat/admin/user/delete/TabbedPaneController.java b/src/main/java/org/olat/admin/user/delete/TabbedPaneController.java index e93d546a976..89eba525daa 100644 --- a/src/main/java/org/olat/admin/user/delete/TabbedPaneController.java +++ b/src/main/java/org/olat/admin/user/delete/TabbedPaneController.java @@ -21,6 +21,8 @@ package org.olat.admin.user.delete; +import java.util.List; + import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -33,7 +35,10 @@ import org.olat.core.gui.control.ControllerEventListener; import org.olat.core.gui.control.DefaultController; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.translator.PackageTranslator; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; @@ -42,7 +47,7 @@ import org.olat.core.util.WebappHelper; * * @author Christian Guretzki */ -public class TabbedPaneController extends DefaultController implements ControllerEventListener { +public class TabbedPaneController extends DefaultController implements ControllerEventListener, Activateable2 { private static final String PACKAGE = Util.getPackageName(TabbedPaneController.class); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(PACKAGE); @@ -91,6 +96,8 @@ public class TabbedPaneController extends DefaultController implements Controlle userSelectionCtr.updateUserList(); userDeleteStatusCtr.updateUserList(); readyToDeleteCtr.updateUserList(); + //fxdiff BAKS-7 Resume function + userDeleteTabP.addToHistory(ureq, getWindowControl()); } } @@ -101,6 +108,13 @@ public class TabbedPaneController extends DefaultController implements Controlle } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries != null && entries.isEmpty()) return; + userDeleteTabP.activate(ureq, entries, state); + } + /** * Initialize the tabbed pane according to the users rights and the system * configuration diff --git a/src/main/java/org/olat/bookmark/BookmarksPortletRunController.java b/src/main/java/org/olat/bookmark/BookmarksPortletRunController.java index a96c263496d..c9937ecff1e 100644 --- a/src/main/java/org/olat/bookmark/BookmarksPortletRunController.java +++ b/src/main/java/org/olat/bookmark/BookmarksPortletRunController.java @@ -30,8 +30,8 @@ import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; import org.olat.ControllerFactory; +import org.olat.NewControllerFactory; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; @@ -45,7 +45,6 @@ import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.portal.AbstractPortletRunController; import org.olat.core.gui.control.generic.portal.PortletDefaultTableDataModel; import org.olat.core.gui.control.generic.portal.PortletEntry; @@ -55,10 +54,11 @@ import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OresHelper; -import org.olat.home.site.HomeSite; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryStatus; import org.olat.repository.RepositoryManager; @@ -202,9 +202,10 @@ public class BookmarksPortletRunController extends AbstractPortletRunController public void event(UserRequest ureq, Component source, Event event) { if (source == showAllLink){ // activate homes tab in top navigation and active bookmarks menu item - //was brasato:: getWindowControl().getDTabs().activateStatic(ureq, HomeSite.class.getName(), "bookmarks"); - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - dts.activateStatic(ureq, HomeSite.class.getName(), "bookmarks"); + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][bookmarks:0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); } } diff --git a/src/main/java/org/olat/catalog/ui/CatalogController.java b/src/main/java/org/olat/catalog/ui/CatalogController.java index 6f981ea46f8..abe5f4b9d54 100644 --- a/src/main/java/org/olat/catalog/ui/CatalogController.java +++ b/src/main/java/org/olat/catalog/ui/CatalogController.java @@ -21,7 +21,11 @@ package org.olat.catalog.ui; +import java.text.Collator; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; import java.util.List; import java.util.Stack; @@ -36,6 +40,7 @@ import org.olat.bookmark.AddAndEditBookmarkController; import org.olat.bookmark.BookmarkManager; import org.olat.catalog.CatalogEntry; import org.olat.catalog.CatalogManager; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.dispatcher.DispatcherAction; import org.olat.core.gui.UserRequest; @@ -51,6 +56,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.dtabs.DTab; import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.modal.DialogBoxController; @@ -61,6 +67,8 @@ import org.olat.core.gui.media.MediaResource; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.util.Util; import org.olat.core.util.coordinate.CoordinatorManager; @@ -128,7 +136,7 @@ import org.olat.resource.OLATResource; * Date: 2005/10/14 12:35:40 <br> * @author Felix Jost */ -public class CatalogController extends BasicController implements Activateable { +public class CatalogController extends BasicController implements Activateable, Activateable2 { // velocity form flags @@ -193,7 +201,7 @@ public class CatalogController extends BasicController implements Activateable { private CatalogEntry newLinkNotPersistedYet; private int currentCatalogEntryLevel = -1; private List<CatalogEntry> historyStack = new ArrayList<CatalogEntry>(5); - private List childCe; + private List<CatalogEntry> childCe; private boolean isOLATAdmin; private boolean isAuthor; private boolean isLocalTreeAdmin = false; @@ -282,7 +290,7 @@ public class CatalogController extends BasicController implements Activateable { myContent.contextPut("iconRenderer", new RepositoryEntryIconRenderer(getLocale())); // add this root node as history start historyStack.add(rootce); - updateContent(ureq.getIdentity(), rootce, 0); + updateContent(ureq, rootce, 0); // jump to a specific node in the catalog structure, build corresponding // historystack and update tool access @@ -316,7 +324,7 @@ public class CatalogController extends BasicController implements Activateable { // put new as trail on stack historyStack.add(cur); updateToolAccessRights(ureq, cur, historyStack.indexOf(cur)); - updateContent(ureq.getIdentity(), cur, historyStack.indexOf(cur)); + updateContent(ureq, cur, historyStack.indexOf(cur)); fireEvent(ureq, Event.CHANGED_EVENT); } else if (command.startsWith(CATCMD_HISTORY)) { // history clicked @@ -324,7 +332,7 @@ public class CatalogController extends BasicController implements Activateable { CatalogEntry cur = historyStack.get(pos); historyStack = historyStack.subList(0, pos + 1); updateToolAccessRights(ureq, cur, historyStack.indexOf(cur)); - updateContent(ureq.getIdentity(), cur, historyStack.indexOf(cur)); + updateContent(ureq, cur, historyStack.indexOf(cur)); fireEvent(ureq, Event.CHANGED_EVENT); } else if (command.startsWith(CATENTRY_LEAF)) { // link clicked @@ -349,7 +357,7 @@ public class CatalogController extends BasicController implements Activateable { DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, displayName); + dt = dts.createDTab(ores, repoEntry, displayName); if (dt == null) return; Controller launchController = ControllerFactory.createLaunchController(ores, null, ureq, dt.getWindowControl(), true); dt.setController(launchController); @@ -420,8 +428,11 @@ public class CatalogController extends BasicController implements Activateable { CatalogEntry showDetailForLink = (CatalogEntry) childCe.get(pos); RepositoryEntry repoEnt = showDetailForLink.getRepositoryEntry(); fireEvent(ureq, new EntryChangedEvent(repoEnt, EntryChangedEvent.MODIFIED)); - //TODO [ingkr] - //getWindowControl().getDTabs().activateStatic(ureq, RepositorySite.class.getName(), RepositoryMainController.JUMPFROMEXTERN+RepositoryMainController.JUMPFROMCATALOG+repoEnt.getKey().toString()); + //fxdiff BAKS-7 Resume function + OLATResourceable ceRes = OresHelper.createOLATResourceableInstance(CatalogEntry.class.getSimpleName(), showDetailForLink.getKey()); + WindowControl bwControl = addToHistory(ureq, ceRes, null); + OLATResourceable ores = OresHelper.createOLATResourceableInstance("details", 0l); + addToHistory(ureq, ores, null, bwControl, true); return; } } @@ -658,7 +669,7 @@ public class CatalogController extends BasicController implements Activateable { CatalogEntry newRoot = (CatalogEntry) cm.getRootCatalogEntries().get(0); historyStack = new ArrayList<CatalogEntry>(); historyStack.add(newRoot); - updateContent(ureq.getIdentity(), newRoot, 0); + updateContent(ureq, newRoot, 0); updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel); fireEvent(ureq, Event.CHANGED_EVENT); } @@ -690,11 +701,11 @@ public class CatalogController extends BasicController implements Activateable { newLinkNotPersistedYet.setOwnerGroup(BaseSecurityManager.getInstance().createAndPersistSecurityGroup()); cm.addCatalogEntry(currentCatalogEntry, newLinkNotPersistedYet); newLinkNotPersistedYet = null; - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel); fireEvent(ureq, Event.CHANGED_EVENT); } else if (event == Event.CANCELLED_EVENT) { - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel); fireEvent(ureq, Event.CHANGED_EVENT); @@ -711,7 +722,7 @@ public class CatalogController extends BasicController implements Activateable { cm.deleteCatalogEntry(currentCatalogEntry); // display the parent historyStack.remove(historyStack.size() - 1); - updateContent(ureq.getIdentity(), parent, historyStack.indexOf(parent)); + updateContent(ureq, parent, historyStack.indexOf(parent)); updateToolAccessRights(ureq, parent, historyStack.indexOf(parent)); fireEvent(ureq, Event.CHANGED_EVENT); } @@ -728,7 +739,7 @@ public class CatalogController extends BasicController implements Activateable { else if (source == dialogDeleteLink) { if (DialogBoxUIFactory.isYesEvent(event)) { cm.deleteCatalogEntry(linkMarkedToBeDeleted); - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); } // in any case, remove the lock if (catModificationLock != null && catModificationLock.isSuccess()) { @@ -743,7 +754,7 @@ public class CatalogController extends BasicController implements Activateable { // remove modal dialog cmc.deactivate(); if (event.equals(Event.DONE_EVENT) || event.equals(Event.CANCELLED_EVENT)) { - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); } } else if (source == groupController) { // remove modal dialog @@ -789,7 +800,7 @@ public class CatalogController extends BasicController implements Activateable { reloadHistoryStack(ureq, currentCatalogEntry.getKey()); } else if(event.equals(Event.FAILED_EVENT)){ showError("tools.move.catalog.entry.failed"); - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); } // in any case, remove the lock if (catModificationLock != null && catModificationLock.isSuccess()) { @@ -808,7 +819,7 @@ public class CatalogController extends BasicController implements Activateable { else if (source == repositoryEditDescriptionController) { if (event == Event.CHANGED_EVENT) { linkMarkedToBeEdited.setRepositoryEntry(repositoryEditDescriptionController.getRepositoryEntry()); - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); cm.updateReferencedRepositoryEntry(repositoryEditDescriptionController.getRepositoryEntry()); } else if (event == Event.CANCELLED_EVENT) { cmc.deactivate(); @@ -830,7 +841,7 @@ public class CatalogController extends BasicController implements Activateable { } CatalogEntry reloaded = cm.loadCatalogEntry(currentCatalogEntry); currentCatalogEntry = reloaded;// FIXME:pb: - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel); // in any case, remove the lock if (catModificationLock != null && catModificationLock.isSuccess()) { @@ -860,7 +871,7 @@ public class CatalogController extends BasicController implements Activateable { CoordinatorManager.getInstance().getCoordinator().getLocker().releaseLock(catModificationLock); catModificationLock = null; } - updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel); + updateContent(ureq, currentCatalogEntry, currentCatalogEntryLevel); } } @@ -932,7 +943,9 @@ public class CatalogController extends BasicController implements Activateable { * @param ce * @param ceLevel */ - private void updateContent(Identity identity, CatalogEntry ce, int ceLevel) { + //fxdiff BAKS-7 Resume function + private void updateContent(UserRequest ureq, CatalogEntry ce, int ceLevel) { + Identity identity = ureq.getIdentity(); /* * FIXME:pb:c include lookahead feature, displaying the 1st 3 children if * any, to give a google directory feeling @@ -974,6 +987,18 @@ public class CatalogController extends BasicController implements Activateable { } else myContent.contextPut("hasOwnedLinks", Boolean.FALSE); } else myContent.contextPut("hasOwnedLinks", Boolean.FALSE); + //fxdiff BAKS-7 Resume function + updateHistory(ureq); + } + + //fxdiff BAKS-7 Resume function + public void updateHistory(UserRequest ureq) { + if(currentCatalogEntry != null) { + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CatalogEntry.class, currentCatalogEntry.getKey()); + addToHistory(ureq, ores, null); + } else { + addToHistory(ureq); + } } /** @@ -1083,7 +1108,35 @@ public class CatalogController extends BasicController implements Activateable { canAdministrateCategory = true; canAddSubCategories = true; canRemoveAllLinks = true; - fireEvent(ureq, Event.CHANGED_EVENT); + fireEvent(ureq, Event.CHANGED_EVENT); + } + } + } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry catCe = entries.remove(0); + Long catId = catCe.getOLATResourceable().getResourceableId(); + CatalogEntry ce = CatalogManager.getInstance().loadCatalogEntry(catId); + switch(ce.getType()) { + case CatalogEntry.TYPE_NODE: { + reloadHistoryStack(ureq, catId); + break; + } + case CatalogEntry.TYPE_LEAF: { + Long folderId = ce.getParent().getKey(); + reloadHistoryStack(ureq, folderId); + if(!entries.isEmpty()) { + ContextEntry subEntry = entries.remove(0); + String subType = subEntry.getOLATResourceable().getResourceableTypeName(); + if("details".equals(subType)) { + event(ureq, myContent, new Event(CATCMD_DETAIL + CATENTRY_LEAF + "0")); + } + } + break; } } } @@ -1122,7 +1175,8 @@ public class CatalogController extends BasicController implements Activateable { { cE = stack.pop(); historyStack.add(cE); - updateContent(ureq.getIdentity(), cE, historyStack.size()-1); + //fxdiff BAKS-7 Resume function + updateContent(ureq, cE, historyStack.size()-1); updateToolAccessRights(ureq, cE, historyStack.size()-1); } return true; diff --git a/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java b/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java index ead775e9871..5591ddaaa08 100644 --- a/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java +++ b/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java @@ -93,6 +93,7 @@ public class KalendarEntryDetailsController extends BasicController { linkVC = createVelocityContainer ("calEditLinks"); linkVC.contextPut("caller", caller); if (!isReadOnly) { + //course node links pane.addTab(translate("tab.links"), linkVC); } diff --git a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java index 41579632d0e..0db87f37fab 100644 --- a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java +++ b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java @@ -202,9 +202,9 @@ public class WeeklyCalendarController extends BasicController implements Calenda weeklyCalendar = new WeeklyCalendarComponent("weeklyCalendar", allCalendarWrappers, 7, getTranslator(), eventAlwaysVisible); weeklyCalendar.addListener(this); - /// subscription, see OLAT-3861 - if(!isGuest){ - final SubscriptionProvider provider = new SubscriptionProviderImpl(caller, calendarWrappers.get(0)); + // subscription, see OLAT-3861 + if (!isGuest) { + SubscriptionProvider provider = new SubscriptionProviderImpl(caller, calendarWrappers.get(0)); subsContext = provider.getSubscriptionContext(); // if sc is null, then no subscription is desired if (subsContext != null) { @@ -212,7 +212,7 @@ public class WeeklyCalendarController extends BasicController implements Calenda vcMain.put("calsubscription", csc.getInitialComponent()); } } - + ComponentUtil.registerForValidateEvents(vcMain, this); vcMain.put("calendar", weeklyCalendar); diff --git a/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java b/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java index c2567c02c1a..3e9d1b2e139 100644 --- a/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java +++ b/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java @@ -175,7 +175,6 @@ public class FileChooseCreateEditController extends BasicController{ init(chosenFile, allowRelativeLinks, rootContainer, VC_DEFAULT, fieldSetLegend, ureq, wControl); } - private void init(String file, Boolean allowRelLinks, VFSContainer rContainer, String target, String fieldSetLegend, UserRequest ureq, WindowControl wControl ) { if(log.isDebug()) { log.debug("Constructing FileChooseCreateEditController using the current velocity root"); diff --git a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java index 89c834a1909..6d22a2b1de0 100644 --- a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java +++ b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java @@ -11,10 +11,10 @@ import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; +import org.olat.NewControllerFactory; import org.olat.commons.info.manager.InfoMessageFrontendManager; import org.olat.commons.info.model.InfoMessage; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; @@ -28,7 +28,6 @@ import org.olat.core.gui.components.table.TableGuiConfiguration; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.portal.AbstractPortletRunController; import org.olat.core.gui.control.generic.portal.PortletDefaultTableDataModel; import org.olat.core.gui.control.generic.portal.PortletEntry; @@ -37,6 +36,8 @@ import org.olat.core.gui.control.generic.portal.SortingCriteria; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; @@ -44,7 +45,6 @@ import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.notifications.NotificationsManager; import org.olat.core.util.notifications.SubscriptionInfo; import org.olat.core.util.notifications.items.SubscriptionListItem; -import org.olat.home.site.HomeSite; /** * @@ -179,10 +179,13 @@ public class InfoMessagePortletRunController extends AbstractPortletRunControlle Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.add(Calendar.MONTH, -1); - //the end is businessPath compatible - String activationCmd = "adminnotifications.[news:0][type=" + InfoMessage.class.getSimpleName() + ":0][date=" + format.format(cal.getTime()) + ":0]"; - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - dts.activateStatic(ureq, HomeSite.class.getName(), activationCmd); + // fxdiff activate homes tab in top navigation and activate the correct + // menu item + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][notifications:0][type=" + InfoMessage.class.getSimpleName() + + ":0][date=" + format.format(cal.getTime()) + ":0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); } } diff --git a/src/main/java/org/olat/core/commons/chiefcontrollers/BaseChiefController.java b/src/main/java/org/olat/core/commons/chiefcontrollers/BaseChiefController.java index 62cf660e75f..d23daf41ee2 100644 --- a/src/main/java/org/olat/core/commons/chiefcontrollers/BaseChiefController.java +++ b/src/main/java/org/olat/core/commons/chiefcontrollers/BaseChiefController.java @@ -262,27 +262,28 @@ public class BaseChiefController extends DefaultChiefController implements Conte Boolean isInlineTranslationEnabled = (Boolean) guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_INLINE_TRANSLATION_ENABLED, Boolean.FALSE); I18nManager.getInstance().setMarkLocalizedStringsEnabled(ureq.getUserSession(), isInlineTranslationEnabled); mainvc.put("inlineTranslation", inlineTranslationC.getInitialComponent()); - } + } // debug info if debugging if (wbo.isDebuging()) { developmentC = wbo.createDevelopmentController(ureq, getWindowControl()); mainvc.put("development", developmentC.getInitialComponent()); } - + // attach AJAX javascript console jsLoggerC = new JavaScriptTracingController(ureq, getWindowControl()); // the js logger provides only a header element, nevertheless we need to - // put it into the main velocity container. + // put it into the main velocity container. mainvc.put("jsLoggerC", jsLoggerC.getInitialComponent()); - - //put the globals path like "/olat/classpath/61x/" into the main win, used for some dynamic injected js libs like jsMath + + // put the globals path like "/olat/classpath/61x/" into the main win, + // used for some dynamic injected js libs like jsMath String resourcePath = getWindowControl().getWindowBackOffice().getWindowManager().getMapPathFor(this.getClass()); mainvc.contextPut("classPathStaticBaseURI", resourcePath.substring(0, resourcePath.indexOf("org.olat"))); // put the global js translator mapper path into the main window mainvc.contextPut("jsTranslationMapperPath", jsTranslationMapperPath); - + // master window w.addListener(this); // to be able to report "browser reload" to the user w.setContentPane(mainPanel); @@ -344,8 +345,6 @@ public class BaseChiefController extends DefaultChiefController implements Conte } } - - /** * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) */ @@ -359,17 +358,17 @@ public class BaseChiefController extends DefaultChiefController implements Conte jsServerC.dispose(); jsServerC = null; } - + if (debugC != null) { debugC.dispose(); debugC = null; } - + if (inlineTranslationC != null) { inlineTranslationC.dispose(); inlineTranslationC = null; } - + if (developmentC != null) { developmentC.dispose(); developmentC = null; diff --git a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java index 1576f9ff095..eedc0b8b73f 100644 --- a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java +++ b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java @@ -35,6 +35,7 @@ import org.olat.core.commons.fullWebApp.util.GlobalStickyMessage; import org.olat.core.gui.GUIInterna; import org.olat.core.gui.GUIMessage; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.WindowManager; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.Window; import org.olat.core.gui.components.htmlheader.jscss.CustomCSS; @@ -52,6 +53,7 @@ import org.olat.core.gui.control.WindowControlInfoImpl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.dtabs.DTab; import org.olat.core.gui.control.generic.dtabs.DTabImpl; import org.olat.core.gui.control.generic.dtabs.DTabs; @@ -62,10 +64,17 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.control.util.ZIndexWrapper; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.HistoryModule; +import org.olat.core.id.context.HistoryPoint; +import org.olat.core.id.context.StateEntry; +import org.olat.core.id.context.StateSite; import org.olat.core.logging.AssertException; import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller; import org.olat.core.util.StringHelper; import org.olat.core.util.event.GenericEventListener; +import org.olat.core.util.prefs.Preferences; import org.olat.core.util.resource.OresHelper; /** @@ -109,6 +118,8 @@ public class BaseFullWebappController extends BasicController implements Generic private Map<SiteInstance, BornSiteInstance> siteToBornSite = new HashMap<SiteInstance, BornSiteInstance>(); private static final int MAX_TABS = 5; private int navLinkCounter = 1; + //fxdiff BAKS-7 Resume function + private Map<SiteInstance,HistoryPoint> siteToBusinessPath = new HashMap<SiteInstance,HistoryPoint>(); // private BaseFullWebappControllerParts baseFullWebappControllerParts; @@ -223,19 +234,34 @@ public class BaseFullWebappController extends BasicController implements Generic myDTabsImpl = new DTabs() { public void activate(UserRequest ureq, DTab dTab, String viewIdentifier) { - BaseFullWebappController.this.activate(ureq, dTab, viewIdentifier); + BaseFullWebappController.this.activate(ureq, dTab, viewIdentifier, null); + } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, DTab dTab, String viewIdentifier, List<ContextEntry> entries) { + BaseFullWebappController.this.activate(ureq, dTab, viewIdentifier, entries); } public void activateStatic(UserRequest ureq, String className, String viewIdentifier) { - BaseFullWebappController.this.activateStatic(ureq, className, viewIdentifier); + BaseFullWebappController.this.activateStatic(ureq, className, viewIdentifier, null); + } + @Override + //fxdiff BAKS-7 Resume function + public void activateStatic(UserRequest ureq, String className, String viewIdentifier, List<ContextEntry> entries) { + BaseFullWebappController.this.activateStatic(ureq, className, viewIdentifier, entries); } public void addDTab(DTab dt) { BaseFullWebappController.this.addDTab(dt); } - + //fxdiff BAKS-7 Resume function public DTab createDTab(OLATResourceable ores, String title) { - return BaseFullWebappController.this.createDTab(ores, title); + return BaseFullWebappController.this.createDTab(ores, null, title); + } + + public DTab createDTab(OLATResourceable ores, OLATResourceable initialOres, String title) { + return BaseFullWebappController.this.createDTab(ores, initialOres, title); } public DTab getDTab(OLATResourceable ores) { @@ -275,6 +301,7 @@ public class BaseFullWebappController extends BasicController implements Generic Boolean alreadySeen = ((Boolean)ureq.getUserSession().getEntry(PRESENTED_AFTER_LOGIN_WORKFLOW)); if (ureq.getUserSession().isAuthenticated() && alreadySeen == null) { Controller aftLHookCtr = ((ControllerCreator) CoreSpringFactory.getBean("fullWebApp.AfterLoginInterceptionControllerCreator")).createController(ureq, getWindowControl()); + listenTo(aftLHookCtr); aftLHookCtr.getInitialComponent(); ureq.getUserSession().putEntry(PRESENTED_AFTER_LOGIN_WORKFLOW, Boolean.TRUE); } @@ -395,7 +422,7 @@ public class BaseFullWebappController extends BasicController implements Generic prevSite = sites.get(0); if (contentCtrl == null) { //activate site only if no content was set -> allow content before activation of default site. - activateSite(sites.get(0), ureq, null); + activateSite(sites.get(0), ureq, null, null); } } if (sites == null && contentCtrl == null) { throw new AssertException("either one site has to be present or a content controller"); } @@ -413,7 +440,20 @@ public class BaseFullWebappController extends BasicController implements Generic String mC = link.getCommand().substring(0, 1); if (mC.equals("t")) { // activate normal tab SiteInstance s = (SiteInstance) link.getUserObject(); - activateSite(s, ureq, null); + //fxdiff BAKS-7 Resume function + if(prevSite != null) { + siteToBusinessPath.put(prevSite, ureq.getUserSession().getLastHistoryPoint()); + } + + HistoryPoint point = null; + if(siteToBusinessPath.containsKey(s)) { + point = siteToBusinessPath.get(s); + } + activateSite(s, ureq, null, null); + if(point != null) { + BusinessControlFactory.getInstance().addToHistory(ureq, point); + } + siteToBusinessPath.put(s, ureq.getUserSession().getLastHistoryPoint()); } else if (mC.equals("a")) { // activate dyntab DTab dt = (DTab) link.getUserObject(); doActivateDTab((DTabImpl) dt); @@ -435,6 +475,58 @@ public class BaseFullWebappController extends BasicController implements Generic } else { getLogger().info("RELOAD"); } + + if(isBackEnabled(ureq)) { + HistoryPoint point = ureq.getUserSession().popLastHistoryEntry(); + if(point != null) { + back(ureq, point); + } + } + } + } + } + + private boolean isBackEnabled(UserRequest ureq) { + HistoryModule historyModule = (HistoryModule)CoreSpringFactory.getBean("historyModule"); + if(historyModule.isBackEnabled()) { + Preferences prefs = ureq.getUserSession().getGuiPreferences(); + Boolean be = (Boolean)prefs.get(WindowManager.class, "back-enabled"); + if (be != null) { + return be.booleanValue(); + } + else { + return historyModule.isBackDefaultSetting(); + } + } + return false; + } + + protected void back(UserRequest ureq, HistoryPoint cstate) { + List<ContextEntry> entries = cstate.getEntries(); + if(entries.isEmpty()) return; + + entries = new ArrayList<ContextEntry>(entries); + + ContextEntry state = entries.remove(0); + if(state == null) return;//no red screen for this + + OLATResourceable ores = state.getOLATResourceable(); + DTab dt = getDTab(ores); + if(dt instanceof DTabImpl) { + DTabImpl dti = (DTabImpl)dt; + doActivateDTab(dti); + if(dti.getController() instanceof Activateable2) { + ((Activateable2)dti.getController()).activate(ureq, entries, null); + } + } else if (dt == null) { + StateEntry s = state.getTransientState(); + if(s instanceof StateSite && sites != null) { + SiteInstance site = ((StateSite)s).getSite(); + for(SiteInstance savedSite:sites) { + if(site.getClass().equals(savedSite.getClass())) { + activateSite(savedSite, ureq, null, entries); + } + } } } } @@ -493,8 +585,8 @@ public class BaseFullWebappController extends BasicController implements Generic } // FROM FULLCHIEFCONTROLLER - - private void activateSite(SiteInstance s, UserRequest ureq, String viewIdentifier) { + //fxdiff BAKS-7 Resume function + private void activateSite(SiteInstance s, UserRequest ureq, String viewIdentifier, List<ContextEntry> entries) { BornSiteInstance bs = siteToBornSite.get(s); GuiStack gs; Controller resC; @@ -528,16 +620,19 @@ public class BaseFullWebappController extends BasicController implements Generic siteToBornSite.put(s, new BornSiteInstance(gs, resC)); } doActivateSite(s, gs); + //fxdiff BAKS-7 Resume function + if(entries != null && !entries.isEmpty() && resC instanceof Activateable2) { + ((Activateable2)resC).activate(ureq, entries, null); + } else if(viewIdentifier != null && resC instanceof Activateable) { + ((Activateable)resC).activate(ureq, viewIdentifier); + } + //fxdiff perhaps has activation changed the gui stack and it need to be updated + setGuiStack(gs); //set current BusPath for extraction in the TopNav Controller //FIXME:pb:2009-06-21:move core //PB//getWindowControl().getWindowBackOffice().getWindow().setAttribute("BUSPATH", site_wControl); getWindowControl().getWindowBackOffice().getWindow().setAttribute("BUSPATH", getWindowControl()); - - if (viewIdentifier != null && (resC instanceof Activateable)) { - Activateable a = (Activateable) resC; - a.activate(ureq, viewIdentifier); - } } private void doActivateSite(SiteInstance s, GuiStack gs) { @@ -686,9 +781,11 @@ public class BaseFullWebappController extends BasicController implements Generic * @see org.olat.core.gui.control.generic.dtabs.DTabs#getDTab(org.olat.core.id.OLATResourceable */ public DTab getDTab(OLATResourceable ores) { - for (Iterator it_dts = dtabs.iterator(); it_dts.hasNext();) { - DTab dtab = (DTab) it_dts.next(); + for (Iterator<DTab> it_dts = dtabs.iterator(); it_dts.hasNext();) { + DTab dtab = it_dts.next(); if (OresHelper.equals(dtab.getOLATResourceable(), ores)) return dtab; + //fxdiff BAKS-7 Resume function + if (OresHelper.equals(dtab.getInitialOLATResourceable(), ores)) return dtab; } return null; } @@ -697,12 +794,14 @@ public class BaseFullWebappController extends BasicController implements Generic * @see org.olat.core.gui.control.generic.dtabs.DTabs#createDTab(org.olat.core.id.OLATResourceable * java.lang.String) */ - public DTab createDTab(OLATResourceable ores, String title) { + //fxdiff BAKS-7 Resume function + public DTab createDTab(OLATResourceable ores, OLATResourceable repoOres, String title) { + // fxdiff: read from props if (dtabs.size() >= MAX_TABS) { getWindowControl().setError(translate("warn.tabsfull")); return null; } - DTabImpl dt = new DTabImpl(ores, title, getWindowControl()); + DTabImpl dt = new DTabImpl(ores, repoOres, title, getWindowControl()); return dt; } @@ -755,15 +854,25 @@ public class BaseFullWebappController extends BasicController implements Generic * @see org.olat.core.gui.control.generic.dtabs.DTabs#activate(org.olat.core.gui.UserRequest, * org.olat.core.gui.control.generic.dtabs.DTab, java.lang.String) */ - public void activate(final UserRequest ureq, DTab dTab, final String viewIdentifier) { + public void activate(final UserRequest ureq, DTab dTab, final String viewIdentifier, final List<ContextEntry> entries) { // FIXME:fj:c if viewIdentifier is DTABS.initialView -> activate to this // init view (e.g. kurs in run mode, repo-detail-edit...) // jump here via external link or just open a new tab from e.g. repository + //fxdiff FXOLAT-113: business path in DMZ + if(dTab == null && contentCtrl instanceof Activateable2) { + ((Activateable2)contentCtrl).activate(ureq, entries, null); + return; + } + DTabImpl dtabi = (DTabImpl) dTab; Controller c = dtabi.getController(); if (c == null) throw new AssertException("no controller set yet! " + dTab + ", view: " + viewIdentifier); doActivateDTab(dtabi); - if (viewIdentifier != null && c instanceof Activateable) { + //fxdiff BAKS-7 Resume function + if(entries != null && !entries.isEmpty() && c instanceof Activateable2) { + final Activateable2 activateable = ((Activateable2) c); + activateable.activate(ureq, entries, null); + } else if (viewIdentifier != null && c instanceof Activateable) { final Activateable activateable = ((Activateable) c); ThreadLocalUserActivityLoggerInstaller.runWithUserActivityLogger(new Runnable() { @@ -773,6 +882,9 @@ public class BaseFullWebappController extends BasicController implements Generic }, activateable.getUserActivityLogger()); } + //fxdiff BAKS-7 Resume function + //update the panels after activation + setGuiStack(dtabi.getGuiStackHandle()); // activating a tab is like focusing a new window - we need to adjust the // guipath since e.g. the button triggering the activation is not @@ -792,12 +904,13 @@ public class BaseFullWebappController extends BasicController implements Generic * java.lang.String, java.lang.String) */ // brasato:: remove - public void activateStatic(UserRequest ureq, String className, String viewIdentifier) { + //fxdiff BAKS-7 Resume function + public void activateStatic(UserRequest ureq, String className, String viewIdentifier, List<ContextEntry> entries) { for (Iterator it_sites = sites.iterator(); it_sites.hasNext();) { SiteInstance site = (SiteInstance) it_sites.next(); String cName = site.getClass().getName(); if (cName.equals(className)) { - activateSite(site, ureq, viewIdentifier); + activateSite(site, ureq, viewIdentifier, entries); return; } } @@ -846,7 +959,6 @@ public class BaseFullWebappController extends BasicController implements Generic initialPanel.pushContent(mainVc); // } else if (event instanceof ChiefControllerMessageEvent) { - ChiefControllerMessageEvent messageEvent = (ChiefControllerMessageEvent) event; // msg can be set to show only on one node or on all nodes String msg = GlobalStickyMessage.getGlobalStickyMessage();//either null, or the global message or the per-node-message Boolean hasStickyMessage = Boolean.valueOf(msg != null); diff --git a/src/main/java/org/olat/core/commons/fullWebApp/LayoutMain3ColsController.java b/src/main/java/org/olat/core/commons/fullWebApp/LayoutMain3ColsController.java index da2e5ab979f..3ec86fc6afc 100644 --- a/src/main/java/org/olat/core/commons/fullWebApp/LayoutMain3ColsController.java +++ b/src/main/java/org/olat/core/commons/fullWebApp/LayoutMain3ColsController.java @@ -21,6 +21,7 @@ package org.olat.core.commons.fullWebApp; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; import org.olat.core.gui.UserRequest; @@ -31,7 +32,11 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.layout.MainLayout3ColumnsController; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; /** * <h3>Description:</h3> This main layout controller provides a three column @@ -61,7 +66,7 @@ import org.olat.core.gui.control.generic.layout.MainLayout3ColumnsController; * * @author Florian Gnaegi, frentix GmbH, http://www.frentix.com */ -public class LayoutMain3ColsController extends MainLayoutBasicController implements MainLayout3ColumnsController { +public class LayoutMain3ColsController extends MainLayoutBasicController implements MainLayout3ColumnsController, Activateable, Activateable2 { private VelocityContainer layoutMainVC; // current columns components private Component[] columns = new Component[3]; @@ -70,6 +75,8 @@ public class LayoutMain3ColsController extends MainLayoutBasicController impleme private LayoutMain3ColsConfig localLayoutConfig; private String layoutConfigKey = null; private Panel panel1, panel2, panel3; + private Activateable activateableDelegate; //fxdiff BAKS-7 Resume function + private Activateable2 activateableDelegate2; //fxdiff BAKS-7 Resume function /** * Constructor for creating a 3 col based menu on the main area. This @@ -138,6 +145,29 @@ public class LayoutMain3ColsController extends MainLayoutBasicController impleme public void addDisposableChildController(Controller toBedisposedControllerOnDispose) { listenTo(toBedisposedControllerOnDispose); } + + //fxdiff BAKS-7 Resume function + public void addActivateableDelegate(Activateable delegate) { + this.activateableDelegate = delegate; + } + //fxdiff BAKS-7 Resume function + public void addActivateableDelegate(Activateable2 delegate) { + this.activateableDelegate2 = delegate; + } + //fxdiff BAKS-7 Resume function + @Override + public void activate(UserRequest ureq, String viewIdentifier) { + if(activateableDelegate != null) { + activateableDelegate.activate(ureq, viewIdentifier); + } + } + //fxdiff BAKS-7 Resume function + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(activateableDelegate2 != null) { + activateableDelegate2.activate(ureq, entries, state); + } + } /** * The Controller to be set on the mainPanel in case of disposing this layout diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java index 1c746484fc8..2a2ce0905bc 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java @@ -24,6 +24,7 @@ package org.olat.core.commons.modules.bc; import java.io.File; import java.util.Enumeration; import java.util.Iterator; +import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -56,11 +57,14 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.NotFoundMediaResource; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.CoreLoggingResourceable; @@ -90,7 +94,7 @@ import org.olat.core.util.vfs.filters.VFSItemFilter; * * @author Felix Jost, Florian Gnägi */ -public class FolderRunController extends BasicController implements Activateable { +public class FolderRunController extends BasicController implements Activateable, Activateable2 { private OLog log = Tracing.createLoggerFor(this.getClass()); @@ -110,6 +114,16 @@ public class FolderRunController extends BasicController implements Activateable private CloseableModalController cmc; private Link editQuotaButton; + /** + * default Constructor, results in showing users personal folder + * + * @param ureq + * @param wControl + */ + public FolderRunController(UserRequest ureq, WindowControl wControl) { + this(new BriefcaseWebDAVProvider().getContainer(ureq.getIdentity()), true, true, ureq, wControl); + } + /** * Constructor for a folder controller without filter and custom link model for editor * @param rootContainer @@ -362,9 +376,19 @@ public class FolderRunController extends BasicController implements Activateable folderComponent.updateChildren(); } } + //fxdiff BAKS-7 Resume function + if(FolderCommandFactory.COMMAND_BROWSE.equals(cmd)) { + updatePathResource(ureq); + } enableDisableQuota(ureq); } } + //fxdiff BAKS-7 Resume function + private void updatePathResource(UserRequest ureq) { + final String path = "path=" + folderComponent.getCurrentContainerPath(); + OLATResourceable ores = OresHelper.createOLATResourceableTypeWithoutCheck(path); + addToHistory(ureq, ores, null); + } private void enableDisableQuota(UserRequest ureq) { if (!ureq.getUserSession().getRoles().isOLATAdmin()) { @@ -402,6 +426,21 @@ public class FolderRunController extends BasicController implements Activateable //folderCommandController is registerd with listenTo and gets disposed in BasicController } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + String path = BusinessControlFactory.getInstance().getPath(entries.get(0)); + VFSItem vfsItem = folderComponent.getRootContainer().resolve(path); + if (vfsItem instanceof VFSContainer) { + folderComponent.setCurrentContainerPath(path); + updatePathResource(ureq); + } else { + activate(ureq, path); + } + } + /** * @see org.olat.core.gui.control.generic.dtabs.Activateable#activate(org.olat.core.gui.UserRequest, * java.lang.String) @@ -441,6 +480,8 @@ public class FolderRunController extends BasicController implements Activateable DisplayOrDownloadComponent dordc = new DisplayOrDownloadComponent("downloadcomp",baseUrl + path); folderContainer.put("autoDownloadComp", dordc); } + //fxdiff BAKS-7 Resume function + updatePathResource(ureq); } } diff --git a/src/main/java/org/olat/core/extensions/AbstractExtension.java b/src/main/java/org/olat/core/extensions/AbstractExtension.java index 903933669fb..d8584b37e1f 100644 --- a/src/main/java/org/olat/core/extensions/AbstractExtension.java +++ b/src/main/java/org/olat/core/extensions/AbstractExtension.java @@ -22,7 +22,6 @@ package org.olat.core.extensions; import org.olat.core.configuration.AbstractConfigOnOff; -import org.olat.core.configuration.ConfigOnOff; import org.olat.core.extensions.action.ActionExtensionSecurityCallback; import org.olat.core.gui.UserRequest; import org.olat.core.logging.AssertException; @@ -30,7 +29,7 @@ import org.olat.core.logging.AssertException; /** * @author Christian Guretzki */ -abstract public class AbstractExtension extends AbstractConfigOnOff implements ConfigOnOff { +abstract public class AbstractExtension extends AbstractConfigOnOff implements Extension { private int order = 0; private String secCallbackName = null; @@ -46,6 +45,23 @@ abstract public class AbstractExtension extends AbstractConfigOnOff implements C this.order = order; } + @Override + public int compareTo(Extension o) { + if(getOrder() < o.getOrder()) return -1; + if(getOrder() > o.getOrder()) return 1; + return 0; + } + + /** + * @overrides + * @see org.olat.core.extensions.Extension#getUniqueExtensionID() + */ + public String getUniqueExtensionID(){ + StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getName()).append(":").append(order).append(":"); + return sb.toString(); + } + /** * [ Spring ] * define the name of a class implementing ActionExtensionSecurityCallback. @@ -129,7 +145,25 @@ abstract public class AbstractExtension extends AbstractConfigOnOff implements C public void setParentTreeNodeIdentifier(String parentTreeNodeIdentifier) { this.parentTreeNodeIdentifier = parentTreeNodeIdentifier; } + + /** + * if there is a security-callback provided, go and check access for user + * @see org.olat.core.extensions.Extension#getExtensionFor(java.lang.String, org.olat.core.gui.UserRequest) + */ + public ExtensionElement getExtensionFor(String extensionPoint, UserRequest ureq) { + if (isSecCallbackNameSet()){ + // no session on dmz! + boolean isDMZ = ureq.getUserSession() == null || ureq.getUserSession().getIdentityEnvironment().getRoles() == null; + boolean launchOK = isDMZ || getActionExtensionSecurityCallback().isAllowedToLaunchActionController(ureq); + if (isDMZ || !launchOK){ + return null; + } + } + return getExtensionFor(extensionPoint); + } - + public boolean isSecCallbackNameSet(){ + return secCallbackName != null; + } } diff --git a/src/main/java/org/olat/core/extensions/ExtManager.java b/src/main/java/org/olat/core/extensions/ExtManager.java index 1ac57a666c3..b3f489148a8 100644 --- a/src/main/java/org/olat/core/extensions/ExtManager.java +++ b/src/main/java/org/olat/core/extensions/ExtManager.java @@ -23,14 +23,18 @@ package org.olat.core.extensions; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TreeMap; import org.olat.core.CoreBeanTypes; import org.olat.core.CoreSpringFactory; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; +import org.olat.core.extensions.action.GenericActionExtension; +import org.olat.core.logging.LogDelegator; +import org.olat.core.util.CodeHelper; +import org.olat.core.util.StringHelper; + /** * Description:<br> @@ -38,14 +42,17 @@ import org.olat.core.logging.Tracing; * @author Felix * @author guido */ -public class ExtManager { - private static OLog log = Tracing.createLoggerFor(ExtManager.class); +public class ExtManager extends LogDelegator { private static ExtManager instance; private long timeOfExtensionStartup; private List<Extension> extensions; private Object lockObject = new Object(); - + + private Map<Long,Extension> idExtensionlookup; + + private Map<String,GenericActionExtension> navKeyGAExtensionlookup; + /** * @return the instance */ @@ -80,6 +87,30 @@ public class ExtManager { return getExtensions().get(i); } + /** + * returns the corresponding extension for a given unique extension id. + * if no Extension is found for the specified id, null is returned instead. + * + * @param id + * @return the corresponding extension or null, if no extension is found for given id + */ + public Extension getExtensionByID(long id){ + if(idExtensionlookup.containsKey(id)) + return idExtensionlookup.get(id); + else return null; + } + + /** + * returns the GenericActionExtension that corresponds to the given NavKey. if + * no suiting GAE is found, null is returned. + * + * @param navKey + * @return the GenericActionExtension or null + */ + public GenericActionExtension getActionExtensioByNavigationKey(String navKey) { + if (navKeyGAExtensionlookup.containsKey(navKey)) return navKeyGAExtensionlookup.get(navKey); + return null; + } /** * [used by spring] @@ -113,28 +144,67 @@ public class ExtManager { } private void initExtentions() { + logInfo("****** start loading extensions *********"); + Map<Integer, Extension> orderKeys = new HashMap<Integer, Extension>(); + idExtensionlookup = new HashMap<Long, Extension>(); + navKeyGAExtensionlookup = new HashMap<String, GenericActionExtension>(); + extensions = new ArrayList<Extension>(); - Map<Integer,Extension> sortedMap = new TreeMap<Integer,Extension>(); Map<String, Object> extensionMap = CoreSpringFactory.getBeansOfType(CoreBeanTypes.extension); Collection<Object> extensionValues = extensionMap.values(); + + int count_disabled = 0; + int count_duplid = 0; + int count_duplnavkey = 0; + // first build ordered list for (Object object : extensionValues) { Extension extension = (Extension) object; - log.debug("initExtentions extention=" + extension); - int key = extension.getOrder(); - while (sortedMap.containsKey(key) ) { - // a key with this value already exist => add 1000 because offset must be outside of other values. - key += 1000; + if (!extension.isEnabled()){ + count_disabled++; + logWarn("* Disabled Extension got loaded :: " + extension + ". Check yourself that you don't use it or that extension returns null for getExtensionFor() when disabled, resp. overwrite isEnabled().",null); + } + int orderKey = extension.getOrder(); + + if(orderKey == 0){ + //not configured via spring (order not set) + logDebug("Extension-Configuration Warning: Order-value was not set for extension=" + extension + ", set order-value to config positionioning of extension...",null); + if(extension instanceof AbstractExtension){ + ((AbstractExtension)extension).setOrder(1000); + } } - if ( key != extension.getOrder() ) { - log.warn("Extension-Configuration Problem: Dublicate order-value ("+extension.getOrder()+") for extension=" + extension.getClass() + ", append extension at the end"); + if (orderKeys.containsKey(orderKey)) { + Extension occupant = orderKeys.get(orderKey); + logDebug("Extension-Configuration Problem: Dublicate order-value ("+extension.getOrder()+") for extension=" + extension + ", orderKey already occupied by "+occupant,null); + } else { + orderKeys.put(orderKey, extension); } - sortedMap.put(key, extension); - log.debug("extension is enabled => add to list of extentions = " + extension); - } - for (Object key : sortedMap.keySet()) { - extensions.add(sortedMap.get(key)); + + Long uid = CodeHelper.getUniqueIDFromString(extension.getUniqueExtensionID()); + if(idExtensionlookup.containsKey(uid)){ + count_duplid++; + logWarn("Devel-Info :: duplicate unique id generated for extensions :: "+uid+" [ ["+idExtensionlookup.get(uid)+"] and ["+extension+"] ]",null); + }else{ + extensions.add(extension); + idExtensionlookup.put(uid, extension); + if (extension instanceof GenericActionExtension) { + GenericActionExtension gAE = (GenericActionExtension) extension; + if (StringHelper.containsNonWhitespace(gAE.getNavigationKey())) { + if (!navKeyGAExtensionlookup.containsKey(gAE.getNavigationKey())) { + navKeyGAExtensionlookup.put(gAE.getNavigationKey(), gAE); + } else { + count_duplnavkey++; + logInfo( + "Devel-Info :: duplicate navigation-key for extension :: " + gAE.getNavigationKey() + " [ [" + idExtensionlookup.get(uid) + + "] and [" + extension + "] ]", null); + } + } + } + } + logDebug("Created unique-id "+uid+" for extension:: "+extension); } + logInfo("Devel-Info :: initExtensions done. :: "+count_disabled+" disabled Extensions, "+count_duplid+" extensions with duplicate ids, "+count_duplnavkey+ " extensions with duplicate navigationKeys"); + Collections.sort(extensions); } } diff --git a/src/main/java/org/olat/core/extensions/Extension.java b/src/main/java/org/olat/core/extensions/Extension.java index 95caab14484..51ff2f57d49 100644 --- a/src/main/java/org/olat/core/extensions/Extension.java +++ b/src/main/java/org/olat/core/extensions/Extension.java @@ -22,6 +22,7 @@ package org.olat.core.extensions; import org.olat.core.configuration.ConfigOnOff; +import org.olat.core.gui.UserRequest; /** * Description:<br> @@ -31,15 +32,37 @@ import org.olat.core.configuration.ConfigOnOff; * Initial Date: 02.08.2005 <br> * @author Felix */ -public interface Extension extends ConfigOnOff { +public interface Extension extends ConfigOnOff, Comparable<Extension> { /** * @param extensionPoint * @return the handler for the extension (an ExtensionElement) * do a check here, if the extension is enabled and return null if not! + * @deprecated fxdiff: better use method getExtensionFor(String extensionPoint, UserRequest ureq) to check per user! */ public ExtensionElement getExtensionFor(String extensionPoint); + /** + * fxdiff: FXOLAT-79 + * check with userrequest if extension will be available to this user! + * also does isEnabled(). this is better than to loop over all extensions and do checks locally! + * returns null if not allowed to access or disabled + * @param extensionPoint + * @param ureq + * @return + */ + public ExtensionElement getExtensionFor(String extensionPoint, UserRequest ureq); + + /** + * returns the order-property of this extension + * @return + */ public int getOrder(); + /** + * returns a String that is unique for this extension + * @return + */ + public String getUniqueExtensionID(); + } diff --git a/src/main/java/org/olat/core/extensions/action/ActionExtension.java b/src/main/java/org/olat/core/extensions/action/ActionExtension.java index a1e383ae7e5..fd873dca921 100644 --- a/src/main/java/org/olat/core/extensions/action/ActionExtension.java +++ b/src/main/java/org/olat/core/extensions/action/ActionExtension.java @@ -25,16 +25,30 @@ import java.util.Locale; import org.olat.core.extensions.ExtensionElement; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.tree.GenericTreeNode; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; /** * Description:<br> * Initial Date: 02.08.2005 <br> + * + * @deprecated + * + * do not directly implement this interface. Subclass GenericActionExtension instead! + * * @author Felix */ public interface ActionExtension extends ExtensionElement { + /** + * creates a GenericTreeNode to be used in Menu/Navigation trees + * + * @param ureq + * @return + */ + public GenericTreeNode createMenuNode(UserRequest ureq); + /** * @param loc diff --git a/src/main/java/org/olat/core/extensions/action/GenericActionExtension.java b/src/main/java/org/olat/core/extensions/action/GenericActionExtension.java index 90fff9c58f2..462476cffb5 100644 --- a/src/main/java/org/olat/core/extensions/action/GenericActionExtension.java +++ b/src/main/java/org/olat/core/extensions/action/GenericActionExtension.java @@ -24,16 +24,19 @@ import java.util.List; import java.util.Locale; import org.olat.core.extensions.AbstractExtension; -import org.olat.core.extensions.Extension; import org.olat.core.extensions.ExtensionElement; import org.olat.core.extensions.helpers.ExtensionElements; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.tree.GenericTreeNode; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.creator.AutoCreator; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.i18n.I18nManager; /** * Description:<br> @@ -45,28 +48,66 @@ import org.olat.core.gui.translator.Translator; * * @author Roman Haag, frentix GmbH, roman.haag@frentix.com */ -public class GenericActionExtension extends AbstractExtension implements ActionExtension, Extension { +public class GenericActionExtension extends AbstractExtension implements ActionExtension { private ExtensionElements elements = new ExtensionElements(); private ControllerCreator actionControllerCreator; private String i18nActionKey; private String i18nDescriptionKey; + /* + * fxdiff : we use this navigationKey to find the correct actionExtension in a + * genericMainController. (to select the correct tree-entry...) + */ + private String navigationKey; private List<String> extensionPoints; private String translationPackageName; private String translationPackageNameDerived; - private Translator translator; private String contentControllerClassName; - + + private String cssClass; + private String iconCssClass; + + protected final OLog log = Tracing.createLoggerFor(GenericActionExtension.class); + public GenericActionExtension() { //only for instantiation by spring } - + public void initExtensionPoints() { for (String extPoint : extensionPoints) { elements.putExtensionElement(extPoint, this); } } - + + /** + * + * @see org.olat.core.extensions.action.ActionExtension#createMenuNode(org.olat.core.gui.UserRequest) + */ + public GenericTreeNode createMenuNode(UserRequest ureq){ + GenericTreeNode node = new GenericTreeNode(); + node.setAltText(getDescription(ureq.getLocale())); + node.setTitle(getActionText(ureq.getLocale())); + node.setIconCssClass(getIconCssClass()); + node.setCssClass(getCssClass()); + + node.setUserObject(this); + return node; + } + + + public String getUniqueExtensionID(){ + StringBuilder sb = new StringBuilder(); + if (extensionPoints != null){ + for(String ext: extensionPoints) + sb.append(ext).append(":"); + } + if(getActionController() instanceof AutoCreator){ + sb.append(((AutoCreator) getActionController()).getClassName()).append(":"); + } + sb.append(getActionText(I18nManager.getInstance().getLocaleOrDefault(null))).append(":").append(getOrder()).append(":").append(getNavigationKey()); + return sb.toString(); + } + /** * @see org.olat.core.extensions.action.ActionExtension#createController(org.olat.core.gui.UserRequest, * org.olat.core.gui.control.WindowControl, java.lang.Object) @@ -85,7 +126,7 @@ public class GenericActionExtension extends AbstractExtension implements ActionE * @see org.olat.core.extensions.action.ActionExtension#getActionText(java.util.Locale) */ public String getActionText(Locale loc) { - initPackageTranslator(loc); + Translator translator = createPackageTranslator(loc); if (i18nActionKey == null) i18nActionKey = getClassNameOfCorrespondingController() + ".menu.title"; return translator.translate(i18nActionKey); } @@ -94,22 +135,28 @@ public class GenericActionExtension extends AbstractExtension implements ActionE * @see org.olat.core.extensions.action.ActionExtension#getDescription(java.util.Locale) */ public String getDescription(Locale loc) { - initPackageTranslator(loc); + Translator translator = createPackageTranslator(loc); if (i18nDescriptionKey == null) i18nDescriptionKey = getClassNameOfCorrespondingController() + ".menu.title.alt"; return translator.translate(i18nDescriptionKey); } + + public String getNavigationKey(){ + return navigationKey; + } - private String getClassNameOfCorrespondingController(){ + //fxdiff + public String getClassNameOfCorrespondingController(){ + if(contentControllerClassName == null) return ""; return contentControllerClassName.substring(contentControllerClassName.lastIndexOf(".")+1); } - private void initPackageTranslator(Locale loc){ - if (translator==null) { - if (translationPackageName==null){ - translationPackageName = translationPackageNameDerived; - } - translator = new PackageTranslator(translationPackageName, loc); + // fxdiff + private Translator createPackageTranslator(Locale loc){ + if (translationPackageName==null){ + translationPackageName = translationPackageNameDerived; } + Translator translator = new PackageTranslator(translationPackageName, loc); + return translator; } /** @@ -152,12 +199,39 @@ public class GenericActionExtension extends AbstractExtension implements ActionE this.i18nDescriptionKey = i18nDescriptionKey; } - /** - * [used by spring] - */ + public void setNavigationKey(String navKey) { + this.navigationKey = navKey; + } + public void setExtensionPoints(List<String> extensionPoints) { this.extensionPoints = extensionPoints; } + + public String getCssClass() { + return cssClass; + } + + public void setCssClass(String classname) { + cssClass = classname; + } + + public String getIconCssClass() { + return iconCssClass; + } + + public void setIconCssClass(String icon) { + iconCssClass = icon; + } + public String toString(){ + StringBuilder sb = new StringBuilder(); + // sb.append(super.toString()); + //sb.append(" controllerCreator: ").append(actionControllerCreator); + sb.append(" controller: ").append(contentControllerClassName); + sb.append(" actionKey: ").append(i18nActionKey); + sb.append(" order: ").append(getOrder()); + sb.append(" navigationKey: ").append(navigationKey); + return sb.toString(); + } } diff --git a/src/main/java/org/olat/core/extensions/security/GuestOnlyExtensionSecurityCallback.java b/src/main/java/org/olat/core/extensions/security/GuestOnlyExtensionSecurityCallback.java new file mode 100644 index 00000000000..115574ce903 --- /dev/null +++ b/src/main/java/org/olat/core/extensions/security/GuestOnlyExtensionSecurityCallback.java @@ -0,0 +1,45 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <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 +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> +* <p> +*/ +package org.olat.core.extensions.security; + +import org.olat.core.extensions.action.ActionExtensionSecurityCallback; +import org.olat.core.gui.UserRequest; + +/** + * Description:<br> + * hide extensions for normal users (show only for guests) + * + * <P> + * Initial Date: 12.09.2011 <br> + * @author Sergio Trentini, sergio.trentini@frentix.com http://www.frentix.com + */ +public class GuestOnlyExtensionSecurityCallback implements ActionExtensionSecurityCallback { + + /** + * + * @see org.olat.core.extensions.action.ActionExtensionSecurityCallback#isAllowedToLaunchActionController(org.olat.core.gui.UserRequest) + */ + @Override + public boolean isAllowedToLaunchActionController(UserRequest ureq) { + return ureq.getUserSession().getRoles().isGuestOnly(); + } + +} diff --git a/src/main/java/org/olat/core/extensions/security/UserOnlyExtensionSecurityCallback.java b/src/main/java/org/olat/core/extensions/security/UserOnlyExtensionSecurityCallback.java new file mode 100644 index 00000000000..fa1bf7b09ab --- /dev/null +++ b/src/main/java/org/olat/core/extensions/security/UserOnlyExtensionSecurityCallback.java @@ -0,0 +1,48 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <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 +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> +* <p> +*/ +package org.olat.core.extensions.security; + +import org.olat.core.extensions.action.ActionExtensionSecurityCallback; +import org.olat.core.gui.UserRequest; + +/** + * Description:<br> + * hide extensions for guests + * + * <P> + * Initial Date: 09.09.2011 <br> + * @author Sergio Trentini, sergio.trentini@frentix.com http://www.frentix.com + */ +public class UserOnlyExtensionSecurityCallback implements ActionExtensionSecurityCallback { + + /** + * + * @see org.olat.core.extensions.action.ActionExtensionSecurityCallback#isAllowedToLaunchActionController(org.olat.core.gui.UserRequest) + */ + @Override + public boolean isAllowedToLaunchActionController(UserRequest ureq) { + if(ureq == null || ureq.getUserSession() == null || ureq.getUserSession().getRoles() == null) { + return false; + } + return !ureq.getUserSession().getRoles().isGuestOnly(); + } + +} diff --git a/src/main/java/org/olat/core/gui/UserRequest.java b/src/main/java/org/olat/core/gui/UserRequest.java index 6a66907e621..febdfe62736 100644 --- a/src/main/java/org/olat/core/gui/UserRequest.java +++ b/src/main/java/org/olat/core/gui/UserRequest.java @@ -73,6 +73,10 @@ public class UserRequest { private boolean isValidDispatchURI; + //fxdiff BAKS-7 Resume function + private String uuid; + private static int count = 0; + //private String businessControlPath; @@ -89,6 +93,14 @@ public class UserRequest { params = new HashMap<String,String>(4); dispatchResult = new DispatchResult(); parseRequest(httpReq); + + //fxdiff BAKS-7 Resume function + uuid = Integer.toString(++count); + } + + //fxdiff BAKS-7 Resume function + public String getUuid() { + return uuid; } /** diff --git a/src/main/java/org/olat/core/gui/components/Window.java b/src/main/java/org/olat/core/gui/components/Window.java index 61c3943295f..6545edc46ab 100644 --- a/src/main/java/org/olat/core/gui/components/Window.java +++ b/src/main/java/org/olat/core/gui/components/Window.java @@ -67,6 +67,9 @@ import org.olat.core.gui.themes.Theme; import org.olat.core.gui.util.ReusableURLHelper; import org.olat.core.helpers.Settings; import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.HistoryPoint; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.Tracing; @@ -365,6 +368,11 @@ public class Window extends Container { //REVIEW:PB: this will be the code allowing back forward navigation //-----> if (inline) { if (inline || !validForDispatching) { + if(!validForDispatching){ + // not valid: fire oldtimestamp event and later rerender + fireEvent(ureq, OLDTIMESTAMPCALL); + } + Container top = getContentPane(); // always validate here, since we are never in the case of just rerendering (we are in the bg iframe) ValidatingVisitor vv = new ValidatingVisitor(gsettings, jsAndCssAdder); @@ -554,7 +562,9 @@ public class Window extends Container { // not a valid timestamp -> most likely a browser back or forward event (or a copy/paste of a url) -> // fire event to listening chiefcontroller - fireEvent(ureq, OLDTIMESTAMPCALL); + //fxdiff BAKS-7: resume controller + Tracing.logDebug("Removed old timestamp event", Window.class); + //fireEvent(ureq, OLDTIMESTAMPCALL); /* * * REVIEW:PB: this will be the code allowing back forward navigation diff --git a/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java b/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java index 866f55ef582..f0089fcc5c3 100644 --- a/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java +++ b/src/main/java/org/olat/core/gui/components/tabbedpane/TabbedPane.java @@ -30,16 +30,23 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentRenderer; import org.olat.core.gui.components.Container; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.util.Util; +import org.olat.core.util.resource.OresHelper; /** * enclosing_type Description: <br> * * @author Felix Jost */ -public class TabbedPane extends Container { +public class TabbedPane extends Container implements Activateable2 { private static final ComponentRenderer RENDERER = new TabbedPaneRenderer(); /** @@ -101,6 +108,15 @@ public class TabbedPane extends Container { super.put("atp", newSelComp); //setDirty(true); not needed since: line above marks this container automatically dirty } + //fxdiff BAKS-7 Resume function + public OLATResourceable getTabResource() { + return OresHelper.createOLATResourceableInstance("tab", new Long(selectedPane)); + } + //fxdiff BAKS-7 Resume function + public void addToHistory(UserRequest ureq, WindowControl wControl) { + OLATResourceable ores = getTabResource(); + BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, null, wControl, true); + } /** * @param displayName @@ -217,5 +233,14 @@ public class TabbedPane extends Container { protected Translator getCompTrans() { return compTrans; } - + + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + int pos = entries.get(0).getOLATResourceable().getResourceableId().intValue(); + if(pos != selectedPane) { + dispatchRequest(ureq, pos); + } + } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/gui/control/DefaultController.java b/src/main/java/org/olat/core/gui/control/DefaultController.java index 38a378e7347..a8c62731399 100644 --- a/src/main/java/org/olat/core/gui/control/DefaultController.java +++ b/src/main/java/org/olat/core/gui/control/DefaultController.java @@ -32,6 +32,9 @@ import org.olat.core.gui.components.Component; import org.olat.core.gui.components.panel.Panel; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -438,6 +441,35 @@ public abstract class DefaultController implements Controller, ControllerEventLi return this.getClass().getName()+" [" + sb + "]"; } + protected WindowControl addToHistory(UserRequest ureq) { + BusinessControlFactory.getInstance().addToHistory(ureq, getWindowControl()); + return getWindowControl(); + } + + protected WindowControl addToHistory(UserRequest ureq, Controller controller) { + WindowControl wControl; + if(controller instanceof DefaultController) { + wControl = ((DefaultController)controller).getWindowControl(); + } else { + wControl = controller.getWindowControlForDebug(); + } + BusinessControlFactory.getInstance().addToHistory(ureq, wControl); + return wControl; + } + + protected WindowControl addToHistory(UserRequest ureq, WindowControl wControl) { + BusinessControlFactory.getInstance().addToHistory(ureq, wControl); + return wControl; + } + + protected WindowControl addToHistory(UserRequest ureq, OLATResourceable ores, StateEntry stateEntry) { + return addToHistory(ureq, ores, stateEntry, getWindowControl(), true); + } + + protected WindowControl addToHistory(UserRequest ureq, OLATResourceable ores, StateEntry stateEntry, WindowControl wControl, boolean addToHistory) { + return BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, stateEntry, wControl, addToHistory); + } + /** * * @see org.olat.core.gui.control.Controller#isDisposed() diff --git a/src/main/java/org/olat/core/gui/control/generic/docking/DockController.java b/src/main/java/org/olat/core/gui/control/generic/docking/DockController.java index 27dee4df937..65f913e7e5b 100644 --- a/src/main/java/org/olat/core/gui/control/generic/docking/DockController.java +++ b/src/main/java/org/olat/core/gui/control/generic/docking/DockController.java @@ -123,6 +123,10 @@ public class DockController extends BasicController { if (controller != null) controller.dispose(); } // else nothing to do } + //fxdiff BAKS-7 Resume function + public Controller getController() { + return controller; + } } diff --git a/src/main/java/org/olat/core/gui/control/generic/dtabs/Activateable2.java b/src/main/java/org/olat/core/gui/control/generic/dtabs/Activateable2.java new file mode 100644 index 00000000000..58da5bf2620 --- /dev/null +++ b/src/main/java/org/olat/core/gui/control/generic/dtabs/Activateable2.java @@ -0,0 +1,44 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <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 +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <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> +* Copyright (c) 1999-2006 at Multimedia- & E-Learning Services (MELS),<br> +* University of Zurich, Switzerland. +* <p> +*/ + +package org.olat.core.gui.control.generic.dtabs; + +import java.util.List; + +import org.olat.core.gui.UserRequest; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; + +/** + * <h3>Description:</h3> + * <p> + * <p> + * Initial Date: 14 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public interface Activateable2 { + + /** + * @param ureq + * @param entries + */ + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state); +} diff --git a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTab.java b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTab.java index b3b99b8b548..ca806e9e6fe 100644 --- a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTab.java +++ b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTab.java @@ -51,6 +51,12 @@ public interface DTab extends Disposable, CustomCSSProvider { * @return the olat resourceable */ public OLATResourceable getOLATResourceable(); + + /** + * @return the olat resourceable + */ + //fxdiff BAKS-7 Resume function + public OLATResourceable getInitialOLATResourceable(); /** * @param launchController diff --git a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabImpl.java b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabImpl.java index 65a7b423e5c..6dfc9c1b062 100644 --- a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabImpl.java +++ b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabImpl.java @@ -43,6 +43,8 @@ import org.olat.core.util.i18n.I18nManager; public class DTabImpl implements Disposable, DTab { private OLATResourceable ores; + //fxdiff BAKS-7 Resume function + private OLATResourceable initialOres; private Controller controller; private GuiStack guiStackHandle; private String title; @@ -55,8 +57,9 @@ public class DTabImpl implements Disposable, DTab { * @param title * @param wControl */ - public DTabImpl(OLATResourceable ores, String title, WindowControl wOrigControl) { + public DTabImpl(OLATResourceable ores, OLATResourceable initialOres, String title, WindowControl wOrigControl) { this.ores = ores; + this.initialOres = initialOres; this.title = title; //Root the JumpInPath - typically all resources are opened in tabs StackedBusinessControl businessControl = new StackedBusinessControl(null, wOrigControl.getBusinessControl()); @@ -118,6 +121,12 @@ public class DTabImpl implements Disposable, DTab { return ores; } + @Override + //fxdiff BAKS-7 Resume function + public OLATResourceable getInitialOLATResourceable() { + return initialOres; + } + /** * @see org.olat.core.gui.control.Disposable#dispose(boolean) */ diff --git a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabs.java b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabs.java index 6bb0da29d2c..46339357656 100644 --- a/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabs.java +++ b/src/main/java/org/olat/core/gui/control/generic/dtabs/DTabs.java @@ -21,8 +21,11 @@ package org.olat.core.gui.control.generic.dtabs; +import java.util.List; + import org.olat.core.gui.UserRequest; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.ContextEntry; /** * Description:<br> @@ -45,6 +48,14 @@ public interface DTabs { */ public DTab createDTab(OLATResourceable ores, String title); + /** + * @param ores + * @param repoOres + * @param title + * @return the tab or null if the headerbar is full. if null, the implementation of the DTabs should issue a warning to the current windowcontrol + */ + public DTab createDTab(OLATResourceable ores, OLATResourceable repoOres, String title); + /** * @param ureq * @param dTab @@ -52,6 +63,14 @@ public interface DTabs { */ public void activate(UserRequest ureq, DTab dTab, String viewIdentifier); + /** + * @param ureq + * @param dTab + * @param viewIdentifier if null, no activation takes places + */ + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, DTab dTab, String viewIdentifier, List<ContextEntry> ce); + /** * FIXME:fj:b change string arg to class * @param ureq @@ -60,6 +79,14 @@ public interface DTabs { */ public void activateStatic(UserRequest ureq, String className, String viewIdentifier); + /** + * FIXME:fj:b change string arg to class + * @param ureq + * @param className the name of the class implementing the siteinstance we would like to activate + * @param viewIdentifier the subcommand (see docu of each controller implementing Activatable + */ + //fxdiff BAKS-7 Resume function + public void activateStatic(UserRequest ureq, String className, String viewIdentifier, List<ContextEntry> entries); diff --git a/src/main/java/org/olat/core/gui/control/generic/layout/GenericMainController.java b/src/main/java/org/olat/core/gui/control/generic/layout/GenericMainController.java index f98d69a226c..44b9797b5cb 100644 --- a/src/main/java/org/olat/core/gui/control/generic/layout/GenericMainController.java +++ b/src/main/java/org/olat/core/gui/control/generic/layout/GenericMainController.java @@ -9,8 +9,7 @@ * http://www.apache.org/licenses/LICENSE-2.0 * <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> + * 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. @@ -21,27 +20,39 @@ package org.olat.core.gui.control.generic.layout; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.extensions.ExtManager; import org.olat.core.extensions.Extension; import org.olat.core.extensions.action.ActionExtension; +import org.olat.core.extensions.action.GenericActionExtension; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.panel.Panel; import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.gui.components.tree.GenericTreeNode; import org.olat.core.gui.components.tree.MenuTree; +import org.olat.core.gui.components.tree.TreeEvent; import org.olat.core.gui.components.tree.TreeModel; import org.olat.core.gui.components.tree.TreeNode; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; -import org.olat.core.gui.translator.Translator; +import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; +import org.olat.core.util.CodeHelper; +import org.olat.core.util.StringHelper; import org.olat.core.util.nodes.INode; +import org.olat.core.util.resource.OresHelper; /** * Description:<br> @@ -53,10 +64,13 @@ import org.olat.core.util.nodes.INode; * Initial Date: 02.07.2008 <br> * * @author Roman Haag, frentix GmbH, roman.haag@frentix.com - * @author patrickb, www.uzh.ch, slightly changed to allow specialised forms of GenericActionExtension + * @author patrickb, www.uzh.ch, slightly changed to allow specialised forms of + * GenericActionExtension */ public abstract class GenericMainController extends MainLayoutBasicController { + private static final String GMCMT = "GMCMenuTree"; + private MenuTree olatMenuTree; private Panel content; private LayoutMain3ColsController columnLayoutCtr; @@ -81,40 +95,61 @@ public abstract class GenericMainController extends MainLayoutBasicController { */ public void init(UserRequest ureq) { olatMenuTree = new MenuTree("olatMenuTree"); - TreeModel tm = buildTreeModel(); + TreeModel tm = buildTreeModel(ureq); olatMenuTree.setTreeModel(tm); content = new Panel("content"); - INode firstNode = tm.getRootNode(); - olatMenuTree.setSelectedNodeId(firstNode.getIdent()); + TreeNode firstNode = tm.getRootNode(); + TreeNode nodeToSelect = getLastDelegate(firstNode); + + olatMenuTree.setSelectedNodeId(nodeToSelect.getIdent()); olatMenuTree.addListener(this); - Object uobject = tm.getRootNode().getUserObject(); + Object uobject = nodeToSelect.getUserObject(); contentCtr = getContentCtr(uobject, ureq); listenTo(contentCtr); // auto dispose later Component resComp = contentCtr.getInitialComponent(); content.setContent(resComp); - Component toolContent = toolCtr != null ? toolCtr.getInitialComponent() : null; - + Component toolContent = toolCtr != null ? toolCtr.getInitialComponent() : null; + columnLayoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), olatMenuTree, toolContent, content, className); listenTo(columnLayoutCtr); // auto dispose later putInitialPanel(columnLayoutCtr.getInitialComponent()); } + + /** + * get the last delegate of a TreeNode. + * + * @param node + * @return the first treeNode in the hierarchy -under the given node- that + * does not have a delegate + */ + private TreeNode getLastDelegate(TreeNode node) { + if (node.getDelegate() == null) return node; + return getLastDelegate(node.getDelegate()); + } + + protected void addCssClassToMain(String cssClass) { + columnLayoutCtr.addCssClassToMain(cssClass); + } /** - * set the column2 or the rightmost column (in left-to-right) for the tool controller. Previous toolcontroller is disposed. + * set the column2 or the rightmost column (in left-to-right) for the tool + * controller. Previous toolcontroller is disposed. + * * @param toolController */ - protected void setToolController(Controller toolController){ - if(toolCtr != null){ + protected void setToolController(Controller toolController) { + if (toolCtr != null) { // there is already a tool controller, dispose it toolCtr.dispose(); } toolCtr = toolController; - if(columnLayoutCtr != null){ + if (columnLayoutCtr != null) { columnLayoutCtr.setCol2(toolCtr.getInitialComponent()); - }//else method called from within constructor before columnLayoutCtr is initialized, see init(..) which sets the toolcontroller content + }// else method called from within constructor before columnLayoutCtr is + // initialized, see init(..) which sets the toolcontroller content } - + /** * build a node before with sth. like: GenericTreeNode gtnA = new * GenericTreeNode(); gtnA.setTitle("appended"); //or with translate @@ -152,15 +187,12 @@ public abstract class GenericMainController extends MainLayoutBasicController { "GenericTreeNode to append/prepend needs to have a UserObject set! Please use setUserObject()."); } } - private TreeModel buildTreeModel() { - GenericTreeNode gtnChild, rootTreeNode; - Translator translator = getTranslator(); + private TreeModel buildTreeModel(UserRequest ureq) { + GenericTreeNode rootTreeNode = new GenericTreeNode(); + rootTreeNode.setTitle(getTranslator().translate("main.menu.title")); + rootTreeNode.setAltText(getTranslator().translate("main.menu.title.alt")); GenericTreeModel gtm = new GenericTreeModel(); - rootTreeNode = new GenericTreeNode(); - //there should be i18n key for main.menu.title for the rootNode in package of implementing type - rootTreeNode.setTitle(translator.translate("main.menu.title")); - rootTreeNode.setAltText(translator.translate("main.menu.title.alt")); gtm.setRootNode(rootTreeNode); // Prepend @@ -178,27 +210,64 @@ public abstract class GenericMainController extends MainLayoutBasicController { // add extension menues ExtManager extm = ExtManager.getInstance(); - int cnt = extm.getExtensionCnt(); int j = 0; - for (int i = 0; i < cnt; i++) { - Extension anExt = extm.getExtension(i); + GenericTreeNode gtnChild; + Map<GenericTreeNode, String> subMenuNodes = new LinkedHashMap<GenericTreeNode, String>(); + for (Extension anExt : extm.getExtensions()) { // check for sites - ActionExtension ae = (ActionExtension) anExt - .getExtensionFor(className); - if (ae != null && anExt.isEnabled()) { - gtnChild = new GenericTreeNode(); - String menuText = ae.getActionText(getLocale()); - gtnChild.setTitle(menuText); - gtnChild.setAltText(ae.getDescription(getLocale())); - gtnChild.setUserObject(ae); - // load first node on root node - if (j == 0 && !rootNodeSet) { - rootTreeNode.setDelegate(gtnChild); - rootTreeNode.setUserObject(ae); - } else { - rootTreeNode.addChild(gtnChild); + ActionExtension ae = (ActionExtension) anExt.getExtensionFor(className, ureq); + if (ae != null && ae instanceof GenericActionExtension) { + if(anExt.isEnabled()){ + GenericActionExtension gAe = (GenericActionExtension) ae; + gtnChild = gAe.createMenuNode(ureq); + + if (gAe.getNodeIdentifierIfParent() != null) { + // it's a parent-node, set identifier + gtnChild.setIdent(gAe.getNodeIdentifierIfParent()); + } + + if (j == 0 && !rootNodeSet) { + // first node, set as delegate of rootTreenode + rootTreeNode.setDelegate(gtnChild); + rootTreeNode.setUserObject(gAe); + rootTreeNode.addChild(gtnChild); + } + + // fixdiff FXOLAT-250 :: make genericMainController aware of multi-level + // navigation (submenues) + else if (gAe.getParentTreeNodeIdentifier() != null) { + // this is a sub-menu-node, do not add to tree-model already, since + // parent tree may not yet be in model + // (parent could be "after" child, in ActionExtensions-Collection) + String parentNodeID = gAe.getParentTreeNodeIdentifier(); + subMenuNodes.put(gtnChild, parentNodeID); + } + // "normal" menu-entry + else { + rootTreeNode.addChild(gtnChild); + } + + j++; + }else{ + logInfo("found disabled GenericActionExtension for "+className+" ", ae.toString()); + } + } + }// loop over extensions + + // fixdiff FXOLAT-250 :: make genericMainController aware of multi-level + // navigation (submenues) + // loop over submenuNodes and add to their parents + for (Entry<GenericTreeNode, String> childNodeEntry : subMenuNodes.entrySet()) { + GenericTreeNode childNode = childNodeEntry.getKey(); + GenericTreeNode parentNode = (GenericTreeNode) gtm.getNodeById(childNodeEntry.getValue()); + if (parentNode != null) { + parentNode.addChild(childNode); + if (parentNode.getDelegate() == null) { + parentNode.setDelegate(childNode); + parentNode.setUserObject(childNode.getUserObject()); } - j++; + } else { + logWarn("Could not add navigation-menu (" + childNode.getTitle() + ") to parent:: " + childNodeEntry.getValue(), null); } } @@ -215,22 +284,32 @@ public abstract class GenericMainController extends MainLayoutBasicController { @Override protected void event(UserRequest ureq, Component source, Event event) { if (source == olatMenuTree) { - if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_CLICKED)) { + if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_CLICKED)) { // process menu commands TreeNode selTreeNode = olatMenuTree.getSelectedNode(); // cleanup old content controller (never null) removeAsListenerAndDispose(contentCtr); - + // create new content controller // Following cases: - // 1a) Simple Action Extension using only ureq and windowControl -> handled by default implementation of createController - // 1b) Specialised Action Extension which needs some more internals -> handled by the class extending GenericMainController, by overwriting createController - // 2) uobject is something special which needs evaluation by class extending GenericMainController + // 1a) Simple Action Extension using only ureq and windowControl -> + // handled by default implementation of createController + // 1b) Specialised Action Extension which needs some more internals -> + // handled by the class extending GenericMainController, by overwriting + // createController + // 2) uobject is something special which needs evaluation by class + // extending GenericMainController Object uobject = selTreeNode.getUserObject(); + TreeNode delegatee = selTreeNode.getDelegate(); + if (delegatee != null) { + olatMenuTree.setSelectedNode(delegatee); + } contentCtr = getContentCtr(uobject, ureq); listenTo(contentCtr); Component resComp = contentCtr.getInitialComponent(); content.setContent(resComp); + // fxdiff BAKS-7 Resume function + addToHistory(ureq, contentCtr); } else { // the action was not allowed anymore content.setContent(null); // display an empty field (empty panel) } @@ -258,12 +337,29 @@ public abstract class GenericMainController extends MainLayoutBasicController { * @return corresponding controller */ protected Controller createController(ActionExtension ae, UserRequest ureq) { - //default implementation for simple case where action extension. - return ae.createController(ureq, getWindowControl(), null); + // default implementation for simple case where action extension. + // fxdiff BAKS-7 Resume function + WindowControl bwControl = getWindowControl(); + if (olatMenuTree.getTreeModel() instanceof GenericTreeModel) { + if (ae instanceof Extension) { + Extension nE = (Extension) ae; + + // get our ores for the extension + OLATResourceable ores; + if (ae instanceof GenericActionExtension && StringHelper.containsNonWhitespace(((GenericActionExtension) ae).getNavigationKey())) { + // there is a navigation-key, use the nice way + ores = OresHelper.createOLATResourceableInstance(((GenericActionExtension) ae).getNavigationKey(), 0L); + } else { + ores = OresHelper.createOLATResourceableInstance(GMCMT, CodeHelper.getUniqueIDFromString(nE.getUniqueExtensionID())); + } + bwControl = addToHistory(ureq, ores, null); + } + } + + return ae.createController(ureq, bwControl, null); } - - private Controller getContentCtr(Object uobject, UserRequest ureq){ + private Controller getContentCtr(Object uobject, UserRequest ureq) { Controller contentCtr1Tmp = null; if (uobject instanceof ActionExtension) { ActionExtension ae = (ActionExtension) uobject; @@ -276,9 +372,96 @@ public abstract class GenericMainController extends MainLayoutBasicController { return contentCtr1Tmp; } + /** + * activates the correct treenode for a given ActionExtension + * @param ureq + * @param ae + */ + private void activateTreeNodeByActionExtension(UserRequest ureq, ActionExtension ae) { + TreeNode node = ((GenericTreeModel) olatMenuTree.getTreeModel()).findNodeByUserObject(ae); + if (node != null) { + olatMenuTree.setSelectedNodeId(node.getIdent()); + TreeEvent te = new TreeEvent(MenuTree.COMMAND_TREENODE_CLICKED, node.getIdent()); + event(ureq, olatMenuTree, te); + } + } + + + // fxdiff BAKS-7 Resume function + protected void activate(UserRequest ureq, String viewIdentifier) { + ActionExtension ae; + if (viewIdentifier != null && viewIdentifier.startsWith(GMCMT)) { + Long extensionID = Long.parseLong(viewIdentifier.substring(viewIdentifier.indexOf(':') + 1)); + Extension ee = ExtManager.getInstance().getExtensionByID(extensionID); + ae = (ActionExtension) ee.getExtensionFor(className, ureq); + } else { + int vwindex = viewIdentifier.lastIndexOf(":"); + String naviKey = viewIdentifier; + if(vwindex >= 0){ + naviKey = viewIdentifier.substring(0,viewIdentifier.indexOf(':')); + } + ae = ExtManager.getInstance().getActionExtensioByNavigationKey(naviKey); + } + + try { + if (olatMenuTree.getTreeModel() instanceof GenericTreeModel) { + activateTreeNodeByActionExtension(ureq, ae); + if (contentCtr instanceof Activateable) { + ((Activateable) contentCtr).activate(ureq, viewIdentifier); + } + } else { + // just for precaution (treenode selection won't work, but correct + // content is displayed) + contentCtr = getContentCtr(ae, ureq); + listenTo(contentCtr); + Component resComp = contentCtr.getInitialComponent(); + content.setContent(resComp); + // fxdiff BAKS-7 Resume function + addToHistory(ureq, contentCtr); + } + } catch (Exception e) { + logWarn("", e); + } + } + + + // fxdiff BAKS-7 Resume function + protected void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if (entries == null || entries.isEmpty()) return; + + ContextEntry entry = entries.get(0); + String node = entry.getOLATResourceable().getResourceableTypeName(); + if (node != null && node.startsWith(GMCMT)) { + activate(ureq, node + ":" + entries.get(0).getOLATResourceable().getResourceableId()); + if (entries.size() >= 1) { + entries = entries.subList(1, entries.size()); + } + if (contentCtr instanceof Activateable2) { + ((Activateable2) contentCtr).activate(ureq, entries, entry.getTransientState()); + } + } else { + // maybe the node is a GAE-NavigationKey ? + GenericActionExtension gAE = ExtManager.getInstance().getActionExtensioByNavigationKey(node); + if (gAE != null) { + activateTreeNodeByActionExtension(ureq, gAE); + if (entries.size() >= 1) { + entries = entries.subList(1, entries.size()); + } + if (contentCtr instanceof Activateable2) { + ((Activateable2) contentCtr).activate(ureq, entries, entry.getTransientState()); + } + } + } + } + @Override protected void doDispose() { - // nothing to do + // nothing to do + } + + // fxdiff + public MenuTree getMenuTree() { + return olatMenuTree; } } diff --git a/src/main/java/org/olat/core/gui/control/navigation/BornSiteInstance.java b/src/main/java/org/olat/core/gui/control/navigation/BornSiteInstance.java index 09f54c53de5..a0c11f54a3b 100644 --- a/src/main/java/org/olat/core/gui/control/navigation/BornSiteInstance.java +++ b/src/main/java/org/olat/core/gui/control/navigation/BornSiteInstance.java @@ -73,7 +73,8 @@ public class BornSiteInstance implements Disposable, CustomCSSProvider { // delegate to content controller if of type main layout controller if (controller != null && controller instanceof MainLayoutController) { MainLayoutController layoutController = (MainLayoutController) controller; - layoutController.getCustomCSS(); + // fxdiff: do return! + return layoutController.getCustomCSS(); } return null; } diff --git a/src/main/java/org/olat/core/id/context/BusinessControl.java b/src/main/java/org/olat/core/id/context/BusinessControl.java index 0b0f6ebb315..ccecdf6a697 100644 --- a/src/main/java/org/olat/core/id/context/BusinessControl.java +++ b/src/main/java/org/olat/core/id/context/BusinessControl.java @@ -21,6 +21,8 @@ */ package org.olat.core.id.context; +import java.util.List; + /** * Description:<br> @@ -55,6 +57,10 @@ public interface BusinessControl { */ public String getAsString(); + + //fxdiff BAKS-7 Resume function + public List<ContextEntry> getEntries(); + /** * pop context entry for further processing, this is used for spawning controllers * @return diff --git a/src/main/java/org/olat/core/id/context/BusinessControlFactory.java b/src/main/java/org/olat/core/id/context/BusinessControlFactory.java index 8cacb88d8db..340df396dd9 100644 --- a/src/main/java/org/olat/core/id/context/BusinessControlFactory.java +++ b/src/main/java/org/olat/core/id/context/BusinessControlFactory.java @@ -21,6 +21,8 @@ */ package org.olat.core.id.context; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -28,6 +30,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.olat.core.commons.servlets.util.URLEncoder; +import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.WindowControl; import org.olat.core.helpers.Settings; import org.olat.core.id.Identity; @@ -65,6 +68,12 @@ public class BusinessControlFactory { return ""; } + @Override + //fxdiff BAKS-7 Resume function + public List<ContextEntry> getEntries() { + return Collections.<ContextEntry>emptyList(); + } + public ContextEntry popLauncherContextEntry() { return null; } @@ -143,21 +152,51 @@ public class BusinessControlFactory { return wc; } - public WindowControl createBusinessWindowControl(final String type, final Long id, WindowControl origWControl) { - final OLATResourceable ores = new OLATResourceable(){ - public String getResourceableTypeName() { - return type; - } - - public Long getResourceableId() { - return id; - }}; - - ContextEntry contextEntry = new MyContextEntry(ores); - return createBusinessWindowControl(contextEntry, origWControl); + /** + * The method check for duplicate entries!!! + * @param ores + * @param wControl + * @return + */ + //fxdiff BAKS-7 Resume function + public WindowControl createBusinessWindowControl(final OLATResourceable ores, StateEntry state, WindowControl wControl) { + WindowControl bwControl; + ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(ores); + if(ce.equals(wControl.getBusinessControl().getCurrentContextEntry())) { + bwControl = wControl; + wControl.getBusinessControl().getCurrentContextEntry().setTransientState(state); + } else { + bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, wControl); + ce.setTransientState(state); + } + return bwControl; } + /** + * The method check for duplicate entries!!! + * @param ores + * @param wControl + * @return + */ + //fxdiff BAKS-7 Resume function + public WindowControl createBusinessWindowControl(UserRequest ureq, final OLATResourceable ores, StateEntry state, + WindowControl wControl, boolean addToHistory) { + WindowControl bwControl = createBusinessWindowControl(ores, state, wControl); + if(addToHistory) { + ureq.getUserSession().addToHistory(ureq, bwControl.getBusinessControl()); + } + return bwControl; + } + //fxdiff BAKS-7 Resume function + public void addToHistory(UserRequest ureq, WindowControl wControl) { + if(wControl == null || wControl.getBusinessControl() == null) return; + ureq.getUserSession().addToHistory(ureq, wControl.getBusinessControl()); + } + + public void addToHistory(UserRequest ureq, HistoryPoint historyPoint) { + ureq.getUserSession().addToHistory(ureq, historyPoint); + } public WindowControl createBusinessWindowControl(BusinessControl businessControl, WindowControl origWControl) { WindowControl wc = new StackedBusinessWindowControl(origWControl, businessControl); @@ -174,7 +213,8 @@ public class BusinessControlFactory { } public ContextEntry createContextEntry(Identity identity) { - return new IdContextEntry(identity); + OLATResourceable ores = OresHelper.createOLATResourceableInstance(Identity.class, identity.getKey()); + return new MyContextEntry(ores); } public String getAsString(BusinessControl bc) { @@ -188,7 +228,15 @@ public class BusinessControlFactory { ContextEntry rootEntry = null; if (ces.isEmpty() || ((rootEntry = ces.get(0))==null)) { Tracing.logWarn("OLAT-4103, OLAT-4047, empty or invalid business controll string. list is empty. string is "+businessControlString, new Exception("stacktrace"), getClass()); -// throw new AssertException("empty or invalid business control string, String is "+businessControlString); + } + return createFromContextEntries(ces); + } + + //fxdiff BAKS-7 Resume function + public BusinessControl createFromContextEntries(final List<ContextEntry> ces) { + ContextEntry rootEntry = null; + if (ces.isEmpty() || ((rootEntry = ces.get(0))==null)) { + Tracing.logWarn("OLAT-4103, OLAT-4047, empty or invalid business controll string. list is empty.", new Exception("stacktrace"), getClass()); } //Root businessControl with RootContextEntry which must be defined (i.e. not null) @@ -300,11 +348,67 @@ public class BusinessControlFactory { } return retVal.substring(0, retVal.length()-1); } + + //fxdiff BAKS-7 Resume function + public String getPath(ContextEntry entry) { + String path = entry.getOLATResourceable().getResourceableTypeName(); + path = path.endsWith(":0") ? path.substring(0, path.length() - 2) : path; + path = path.startsWith("path=") ? path.substring(5, path.length()) : path; + return path; + } + + public String getBusinessPathAsURIFromCEList(List<ContextEntry> ceList){ + if(ceList == null || ceList.isEmpty()) return ""; + + StringBuilder retVal = new StringBuilder(); + //see code in JumpInManager, cannot be used, as it needs BusinessControl-Elements, not the path + for (ContextEntry contextEntry : ceList) { + String ceStr = contextEntry != null ? contextEntry.toString() : "NULL_ENTRY"; + if(ceStr.startsWith("[path")) { + //the %2F make a problem on browsers. + //make the change only for path which is generally used + //TODO: find a better method or a better separator as | + ceStr = ceStr.replace("%2F", "~~"); + } + ceStr = ceStr.replace(':', '/'); + ceStr = ceStr.replaceFirst("\\]", "/"); + ceStr= ceStr.replaceFirst("\\[", ""); + retVal.append(ceStr); + } + return retVal.substring(0, retVal.length()-1); + } + + public String formatFromURI(String restPart) { + try { + restPart = URLDecoder.decode(restPart, "UTF8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + //log.error("Unsupported encoding", e); + } + + String[] split = restPart.split("/"); + if (split.length % 2 != 0) { + return null; + } + String businessPath = ""; + for (int i = 0; i < split.length; i=i+2) { + String key = split[i]; + if(key != null && key.startsWith("path=")) { + key = key.replace("~~", "/"); + } + String value = split[i+1]; + businessPath += "[" + key + ":" + value +"]"; + } + return businessPath; + } } class MyContextEntry implements ContextEntry { private final OLATResourceable olatResourceable; + //fxdiff BAKS-7 Resume function + private StateEntry state; + MyContextEntry(OLATResourceable ores) { this.olatResourceable = ores; } @@ -316,6 +420,28 @@ class MyContextEntry implements ContextEntry { return olatResourceable; } + @Override + //fxdiff BAKS-7 Resume function + public StateEntry getTransientState() { + return state; + } + + @Override + //fxdiff BAKS-7 Resume function + public void setTransientState(StateEntry state) { + this.state = state; + } + + @Override + public ContextEntry clone() { + MyContextEntry entry = new MyContextEntry(olatResourceable); + if(state != null) { + entry.state = state.clone(); + } + return entry; + } + + @Override public String toString(){ URLEncoder urlE = new URLEncoder(); String resource =urlE.encode(this.olatResourceable.getResourceableTypeName()); @@ -348,60 +474,20 @@ class MyContextEntry implements ContextEntry { if (myResName==null && itsResName!=null) return false; if (myResName!=null && itsResName==null) return false; if (myResName!=null && itsResName!=null) { - if (!myResName.equals(itsResName)) return false; - } - return true; - } else { - return super.equals(obj); - } - } - -} - -class IdContextEntry implements ContextEntry { - private final Identity identity; - - IdContextEntry(Identity identity) { - this.identity = identity; - } - - /** - * @return Returns the olatResourceable. - */ - public OLATResourceable getOLATResourceable() { - return new OLATResourceable() { - @Override - public Long getResourceableId() { - return identity.getKey(); + if (!myResName.equals(itsResName)) { + return false; + } } - - @Override - public String getResourceableTypeName() { - return "Identity"; + + if(state == null && mce.state == null) { + return true; + } else if (state != null && state.equals(mce.state)) { + return true; } - }; - } - - public String toString(){ - return "[Identity:"+identity.getKey()+"]"; - } - - @Override - public int hashCode() { - return (identity==null) ? super.hashCode() : identity.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (identity==null) { - return super.equals(obj); - } else if (obj instanceof IdContextEntry) { - IdContextEntry ice = (IdContextEntry)obj; - return identity.equals(ice.identity); + return false; } else { return super.equals(obj); } } - } diff --git a/src/main/java/org/olat/core/id/context/ContextEntry.java b/src/main/java/org/olat/core/id/context/ContextEntry.java index 713b5435bad..84c48cbbbaa 100644 --- a/src/main/java/org/olat/core/id/context/ContextEntry.java +++ b/src/main/java/org/olat/core/id/context/ContextEntry.java @@ -31,7 +31,14 @@ import org.olat.core.id.OLATResourceable; * * @author Felix Jost */ -public interface ContextEntry { +public interface ContextEntry extends Cloneable { public OLATResourceable getOLATResourceable(); - //public String translate(Locale locale); + + //fxdiff BAKS-7 Resume function + public StateEntry getTransientState(); + + //fxdiff BAKS-7 Resume function + public void setTransientState(StateEntry state); + + public ContextEntry clone(); } diff --git a/src/main/java/org/olat/core/id/context/ContextEntryControllerCreator2.java b/src/main/java/org/olat/core/id/context/ContextEntryControllerCreator2.java new file mode 100644 index 00000000000..01d5ff983be --- /dev/null +++ b/src/main/java/org/olat/core/id/context/ContextEntryControllerCreator2.java @@ -0,0 +1,30 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import org.olat.core.gui.UserRequest; + +//fxdiff BAKS-7 Resume function +public interface ContextEntryControllerCreator2 extends ContextEntryControllerCreator { + + + public String getSiteClassName(UserRequest ureq, ContextEntry ce); +} diff --git a/src/main/java/org/olat/core/id/context/HistoryManager.java b/src/main/java/org/olat/core/id/context/HistoryManager.java new file mode 100644 index 00000000000..65ebfab20d4 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/HistoryManager.java @@ -0,0 +1,106 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.id.Identity; +import org.olat.core.manager.BasicManager; +import org.olat.core.util.FileUtils; +import org.olat.core.util.xml.XStreamHelper; + +import com.thoughtworks.xstream.XStream; + +/** + * + * <h3>Description:</h3> + * <p> + * <p> + * Initial Date: 26 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public class HistoryManager extends BasicManager { + + private static HistoryManager THIS; + private static XStream historyStream = XStreamHelper.createXStreamInstance(); + static { + //xstream config + } + + private HistoryManager() { + THIS = this; + } + + public static HistoryManager getInstance() { + return THIS; + } + + public void persistHistoryPoint(Identity identity, HistoryPoint historyPoint) { + try { + String pathHomePage = FolderConfig.getCanonicalRoot() + FolderConfig.getUserHomePage(identity.getName()); + File resumeXml = new File(pathHomePage, "resume.xml"); + if(!resumeXml.getParentFile().exists()) { + resumeXml.getParentFile().mkdirs(); + } + FileOutputStream out = new FileOutputStream(resumeXml); + historyStream.toXML(historyPoint, out); + FileUtils.closeSafely(out); + } catch (Exception e) { + logError("UserSession:::logging off write resume: ", e); + } + } + + public HistoryPoint readHistoryPoint(Identity identity) { + try { + String pathHomePage = FolderConfig.getCanonicalRoot() + FolderConfig.getUserHomePage(identity.getName()); + File resumeXml = new File(pathHomePage, "resume.xml"); + if(resumeXml.exists()) { + FileInputStream in = new FileInputStream(resumeXml); + HistoryPoint point = (HistoryPoint)historyStream.fromXML(in); + FileUtils.closeSafely(in); + return point; + } + return null; + } catch (Exception e) { + logError("Cannot read resume file: ", e); + return null; + } + } + + public void deleteHistory(Identity identity) { + try { + String pathHomePage = FolderConfig.getCanonicalRoot() + FolderConfig.getUserHomePage(identity.getName()); + File resumeXml = new File(pathHomePage, "resume.xml"); + if(resumeXml.exists()) { + resumeXml.delete(); + } + } catch (Exception e) { + logError("Can not delete history file", e); + } + } + + + + +} diff --git a/src/main/java/org/olat/core/id/context/HistoryModule.java b/src/main/java/org/olat/core/id/context/HistoryModule.java new file mode 100644 index 00000000000..8094aac5314 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/HistoryModule.java @@ -0,0 +1,137 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import org.olat.core.configuration.AbstractOLATModule; +import org.olat.core.configuration.ConfigOnOff; +import org.olat.core.configuration.PersistedProperties; +import org.olat.core.util.StringHelper; + +/** + * + * <h3>Description:</h3> + * <p> + * <p> + * Initial Date: 26 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public class HistoryModule extends AbstractOLATModule implements ConfigOnOff { + + private static final String BACK_ENABLED_PROP = "back.enabled"; + private static final String BACK_ENABLED_DEFAULT_PROP = "back.enabled.default"; + private static final String MOD_ENABLED_PROP = "history.enabled"; + private static final String RESUME_ENABLED_PROP = "resume.enabled"; + private static final String RESUME_ENABLED_DEFAULT_PROP = "resume.enabled.default"; + + private boolean enabled; + private boolean backEnabled; + private boolean backDefaultSetting; + private boolean resumeEnabled; + private String resumeDefaultSetting; + + /** + * [used by Spring] + */ + private HistoryModule() { + // + } + + @Override + public void init() { + //back enabled/disabled + String enabledObj = getStringPropertyValue(MOD_ENABLED_PROP, true); + if(StringHelper.containsNonWhitespace(enabledObj)) { + enabled = "true".equals(enabledObj); + } + + String backObj = getStringPropertyValue(BACK_ENABLED_PROP, true); + if(StringHelper.containsNonWhitespace(backObj)) { + backEnabled = "true".equals(backObj); + } + + String backDefSettings = getStringPropertyValue(BACK_ENABLED_DEFAULT_PROP, true); + if(StringHelper.containsNonWhitespace(backDefSettings)) { + backDefaultSetting = "true".equals(backDefSettings); + } + + String resumeObj = getStringPropertyValue(RESUME_ENABLED_PROP, true); + if(StringHelper.containsNonWhitespace(resumeObj)) { + resumeEnabled = "true".equals(resumeObj); + } + + String resumeDefSettings = getStringPropertyValue(RESUME_ENABLED_DEFAULT_PROP, true); + if(StringHelper.containsNonWhitespace(resumeDefSettings)) { + resumeDefaultSetting = resumeDefSettings; + } + + logInfo("Back/resume module is enabled: " + Boolean.toString(enabled)); + } + + @Override + protected void initDefaultProperties() { + enabled = getBooleanConfigParameter(MOD_ENABLED_PROP, true); + backEnabled = getBooleanConfigParameter(BACK_ENABLED_PROP, true); + backDefaultSetting = getBooleanConfigParameter(BACK_ENABLED_DEFAULT_PROP, true); + resumeEnabled = getBooleanConfigParameter(RESUME_ENABLED_PROP, true); + resumeDefaultSetting = getStringConfigParameter(RESUME_ENABLED_DEFAULT_PROP, "ondemand", true); + } + + @Override + protected void initFromChangedProperties() { + init(); + } + + @Override + public void setPersistedProperties(PersistedProperties persistedProperties) { + this.moduleConfigProperties = persistedProperties; + } + + @Override + public boolean isEnabled() { + return enabled; + } + + public boolean isBackEnabled() { + return enabled && backEnabled; + } + + public boolean isBackDefaultSetting() { + return backDefaultSetting; + } + + public boolean isResumeEnabled() { + return enabled && resumeEnabled; + } + + public String getResumeDefaultSetting() { + return resumeDefaultSetting; + } + + public void setResumeDefaultSetting(String resumeDefaultSetting) { + this.resumeDefaultSetting = resumeDefaultSetting; + } + + public void setEnabled(boolean enabled) { + if(this.enabled != enabled) { + setStringProperty(BACK_ENABLED_PROP, Boolean.toString(enabled), true); + } + } +} diff --git a/src/main/java/org/olat/core/id/context/HistoryPoint.java b/src/main/java/org/olat/core/id/context/HistoryPoint.java new file mode 100644 index 00000000000..5fe149c17ba --- /dev/null +++ b/src/main/java/org/olat/core/id/context/HistoryPoint.java @@ -0,0 +1,39 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import java.util.List; + +/** + * + * <h3>Description:</h3> + * <p> + * Initial Date: 18 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public interface HistoryPoint { + + public String getUuid(); + + public String getBusinessPath(); + + public List<ContextEntry> getEntries(); +} diff --git a/src/main/java/org/olat/core/id/context/HistoryPointImpl.java b/src/main/java/org/olat/core/id/context/HistoryPointImpl.java new file mode 100644 index 00000000000..d755cf9e458 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/HistoryPointImpl.java @@ -0,0 +1,68 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ + +package org.olat.core.id.context; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * <h3>Description:</h3> + * <p> + * <p> + * Initial Date: 18 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public class HistoryPointImpl implements HistoryPoint { + + private final String uuid; + private final String businessPath; + private final List<ContextEntry> entries = new ArrayList<ContextEntry>(); + + public HistoryPointImpl(String uuid, String businessPath, List<ContextEntry> entries) { + this.uuid = uuid; + this.businessPath = businessPath; + if(entries != null) { + for(ContextEntry entry:entries) { + this.entries.add(entry.clone()); + } + } + } + + + public String getUuid() { + return uuid; + } + + public String getBusinessPath() { + return businessPath; + } + + public List<ContextEntry> getEntries() { + return entries; + } + + @Override + public String toString() { + return businessPath; + } +} diff --git a/src/main/java/org/olat/core/id/context/StackedBusinessControl.java b/src/main/java/org/olat/core/id/context/StackedBusinessControl.java index 075fb096f2a..c60627c5067 100644 --- a/src/main/java/org/olat/core/id/context/StackedBusinessControl.java +++ b/src/main/java/org/olat/core/id/context/StackedBusinessControl.java @@ -95,6 +95,19 @@ public class StackedBusinessControl implements BusinessControl { return origBusinessControl != null ? origBusinessControl.getAsString() + postfix : postfix; } + @Override + //fxdiff BAKS-7 Resume function + public List<ContextEntry> getEntries() { + if(contextEntry == null) new ArrayList<ContextEntry>(); + List<ContextEntry> entries = new ArrayList<ContextEntry>(); + if(origBusinessControl != null) { + entries.addAll(origBusinessControl.getEntries()); + } + if(contextEntry != null) { + entries.add(contextEntry); + } + return entries; + } public ContextEntry popLauncherContextEntry() { ContextEntry currentToSpawn = popInternalLaucherContextEntry(); diff --git a/src/main/java/org/olat/core/id/context/StateEntry.java b/src/main/java/org/olat/core/id/context/StateEntry.java new file mode 100644 index 00000000000..9755bba2a21 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/StateEntry.java @@ -0,0 +1,34 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +/** + * + * <h3>Description:</h3> + * <p>marke interface for state object + * <p> + * Initial Date: 18 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public interface StateEntry extends Cloneable { + + public StateEntry clone(); +} diff --git a/src/main/java/org/olat/core/id/context/StateMapped.java b/src/main/java/org/olat/core/id/context/StateMapped.java new file mode 100644 index 00000000000..e7ca10e6cc0 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/StateMapped.java @@ -0,0 +1,79 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * <h3>Description:</h3> + * <p>A simple implementation of StateEntry, + * <p> + * Initial Date: 18 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public class StateMapped implements StateEntry{ + + private Map<String,String> delegate = new HashMap<String,String>(); + + public StateMapped() { + //make XStream happy + } + + public Map<String, String> getDelegate() { + return delegate; + } + + public void setDelegate(Map<String, String> delegate) { + this.delegate = delegate; + } + + @Override + public String toString() { + return delegate == null ? "{empty}" : delegate.toString(); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof StateMapped) { + StateMapped map = (StateMapped)obj; + if((map.delegate == null || map.delegate.isEmpty()) && (delegate == null || delegate.isEmpty())) { + return true; + } else if(map.delegate != null && delegate != null && map.delegate.equals(delegate)) { + return true; + } + } + return false; + } + + @Override + public StateEntry clone() { + StateMapped state = new StateMapped(); + if(delegate != null) { + state.delegate.putAll(delegate); + } + return state; + } +} diff --git a/src/main/java/org/olat/core/id/context/StateSite.java b/src/main/java/org/olat/core/id/context/StateSite.java new file mode 100644 index 00000000000..62c2f90aefb --- /dev/null +++ b/src/main/java/org/olat/core/id/context/StateSite.java @@ -0,0 +1,62 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.core.id.context; + +import org.olat.core.gui.control.navigation.SiteInstance; + +/** + * + * <h3>Description:</h3> + * <p>A simple implementation of StateEntry, + * <p> + * Initial Date: 18 jan. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, www.frentix.com + */ +public class StateSite implements StateEntry{ + + private transient SiteInstance site; + + public StateSite() { + //make XStream happy + } + + public StateSite(SiteInstance site) { + this.site = site; + } + + public SiteInstance getSite() { + return site; + } + + public void setSite(SiteInstance site) { + this.site = site; + } + + @Override + public String toString() { + return site == null ? "{empty}" : site.toString(); + } + + @Override + public StateEntry clone() { + return new StateSite(site); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/core/id/context/_spring/historyCorecontext.xml b/src/main/java/org/olat/core/id/context/_spring/historyCorecontext.xml new file mode 100644 index 00000000000..7bed7adef77 --- /dev/null +++ b/src/main/java/org/olat/core/id/context/_spring/historyCorecontext.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <context:property-placeholder location="classpath:serviceconfig/olat.properties, classpath:olat.local.properties" /> + + <bean id="historyModule" class="org.olat.core.id.context.HistoryModule" > + <property name="persistedProperties"> + <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy" + depends-on="coordinatorManager,org.olat.core.util.WebappHelper"> + <constructor-arg index="0" ref="coordinatorManager"/> + <constructor-arg index="1" ref="historyModule" /> + </bean> + </property> + </bean> + + <!-- default configuration --> + <bean id="historyModuleDefaultConfiguration" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> + <property name="targetObject" ref="historyModule" /> + <property name="targetMethod" value="init" /> + <property name="arguments"> + <value> + history.enabled=true + back.enabled=${history.back.enabled} + back.enabled.default=${history.back.enabled.default} + resume.enabled=${history.resume.enabled} + resume.enabled.default=${history.resume.enabled.default} + </value> + </property> + </bean> + + + <bean id="historyManager" class="org.olat.core.id.context.HistoryManager" > + + </bean> + +</beans> diff --git a/src/main/java/org/olat/core/util/CodeHelper.java b/src/main/java/org/olat/core/util/CodeHelper.java index 8e6483fa8b8..180eeeacd11 100644 --- a/src/main/java/org/olat/core/util/CodeHelper.java +++ b/src/main/java/org/olat/core/util/CodeHelper.java @@ -74,6 +74,12 @@ public class CodeHelper { return timeuniqueId.incrementAndGet(); //o_clusterNOK synchronized check what of data generated with that long is persisted } + public static long getUniqueIDFromString(String base){ + int code = Math.abs(base.hashCode()); + Long l = new Long(code); + return l; + } + /** * a simple counter which is garanteed to be unique ONLY within one instance of a virtual machine. * Best effort is taken to make it "globally unique" by instantiating it by System.currentTimeMilis * 64, so that diff --git a/src/main/java/org/olat/core/util/UserSession.java b/src/main/java/org/olat/core/util/UserSession.java index c659fe8efc3..9327e36811a 100644 --- a/src/main/java/org/olat/core/util/UserSession.java +++ b/src/main/java/org/olat/core/util/UserSession.java @@ -27,9 +27,11 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.Stack; import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; @@ -39,12 +41,18 @@ import javax.servlet.http.HttpSessionBindingListener; import org.apache.log4j.Logger; import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Disposable; import org.olat.core.gui.control.Event; import org.olat.core.id.Identity; import org.olat.core.id.IdentityEnvironment; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.HistoryManager; +import org.olat.core.id.context.HistoryPoint; +import org.olat.core.id.context.HistoryPointImpl; import org.olat.core.logging.AssertException; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.CoreLoggingResourceable; @@ -89,9 +97,8 @@ public class UserSession implements HttpSessionBindingListener, GenericEventList private boolean registeredWithBus = false; private Preferences guiPreferences; private EventBus singleUserSystemBus; - - // brasato:: find a better place? - private Map<String, Object> sessionServiceInstances; + //fxdiff BAKS-7 Resume function + private Stack<HistoryPoint> history = new Stack<HistoryPoint>(); private UserSession() { @@ -114,7 +121,6 @@ public class UserSession implements HttpSessionBindingListener, GenericEventList singleUserSystemBus = CoordinatorManager.getInstance().getCoordinator().createSingleUserInstance(); authenticated = false; sessionInfo = null; - sessionServiceInstances = new HashMap<String, Object>(); } /** @@ -270,6 +276,62 @@ public class UserSession implements HttpSessionBindingListener, GenericEventList identityEnvironment.setRoles(roles); } + //fxdiff BAKS-7 Resume function + public List<HistoryPoint> getHistoryStack() { + return history; + } + + public HistoryPoint getLastHistoryPoint() { + if(history.isEmpty()) { + return null; + } + return history.lastElement(); + } + + //fxdiff BAKS-7 Resume function + public HistoryPoint popLastHistoryEntry() { + if(history.isEmpty()) return null; + history.pop();//current point + if(history.isEmpty()) return null; + return history.pop();//remove last point from history + } + + //fxdiff BAKS-7 Resume function + public void addToHistory(UserRequest ureq, HistoryPoint point) { + if(point == null) return; + if(Tracing.isDebugEnabled(UserSession.class)) { + Tracing.logDebug(ureq.getUuid() + " Add business path: " + point.getBusinessPath(), UserSession.class); + } + //System.out.println(ureq.getUuid() + " Add business path: " + point.getBusinessPath()); + history.add(new HistoryPointImpl(ureq.getUuid(), point.getBusinessPath(), point.getEntries())); + } + + //fxdiff BAKS-7 Resume function + public void addToHistory(UserRequest ureq, BusinessControl businessControl) { + List<ContextEntry> entries = businessControl.getEntries(); + String businessPath = businessControl.getAsString(); + if(StringHelper.containsNonWhitespace(businessPath)) { + if(Tracing.isDebugEnabled(UserSession.class)) { + Tracing.logDebug(ureq.getUuid() + " Add business path: " + businessPath, UserSession.class); + } + //System.out.println(ureq.getUuid() + " Add business path: " + businessPath); + String uuid = ureq.getUuid(); + if(!history.isEmpty()) { + //consolidate + for(Iterator<HistoryPoint> it=history.iterator(); it.hasNext(); ) { + HistoryPoint p = it.next(); + if(uuid.equals(p.getUuid())) { + it.remove(); + } + } + } + history.push(new HistoryPointImpl(ureq.getUuid(), businessPath, entries)); + if(history.size() > 20) { + history.remove(0); + } + } + } + /** * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent) */ @@ -327,6 +389,10 @@ public class UserSession implements HttpSessionBindingListener, GenericEventList if (isDebug) { Tracing.logDebug("UserSession:::logging off: " + sessionInfo, this.getClass()); } + //fxdiff BAKS-7 Resume function + if(isAuthenticated() && getLastHistoryPoint() != null && !getRoles().isGuestOnly()) { + HistoryManager.getInstance().persistHistoryPoint(ident, getLastHistoryPoint()); + } /** * use not RunnableWithException, as exceptionHandlng is inside the run diff --git a/src/main/java/org/olat/core/util/controller/OLATResourceableListeningWrapperController.java b/src/main/java/org/olat/core/util/controller/OLATResourceableListeningWrapperController.java index 26af7c03619..6698b278fe4 100644 --- a/src/main/java/org/olat/core/util/controller/OLATResourceableListeningWrapperController.java +++ b/src/main/java/org/olat/core/util/controller/OLATResourceableListeningWrapperController.java @@ -24,6 +24,7 @@ package org.olat.core.util.controller; import java.util.Iterator; import java.util.List; +import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Controller; @@ -31,8 +32,11 @@ import org.olat.core.gui.control.ControllerEventListener; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; @@ -49,9 +53,10 @@ import org.olat.core.util.resource.OLATResourceableJustBeforeDeletedEvent; * * @author Felix Jost */ -public class OLATResourceableListeningWrapperController extends MainLayoutBasicController implements GenericEventListener { +public class OLATResourceableListeningWrapperController extends MainLayoutBasicController implements GenericEventListener, Activateable2 { private Controller realController; private OLATResourceable ores; + private Activateable2 delegate;//fxdiff BAKS-7 Resume function /** * !Use only from within Manager-Classes. * @@ -60,9 +65,10 @@ public class OLATResourceableListeningWrapperController extends MainLayoutBasicC * @param owner * */ - public OLATResourceableListeningWrapperController(UserRequest ureq, WindowControl wControl, OLATResourceable ores, Controller realController, Identity owner) { + public OLATResourceableListeningWrapperController(UserRequest ureq, WindowControl wControl, OLATResourceable ores, Controller realController, Activateable2 delegate, Identity owner) { super(ureq, wControl); this.realController = realController; + this.delegate = delegate;//fxdiff BAKS-7 Resume function this.ores = ores; realController.addControllerListener(this); CoordinatorManager.getInstance().getCoordinator().getEventBus().registerFor(this, owner, ores); @@ -127,6 +133,16 @@ public class OLATResourceableListeningWrapperController extends MainLayoutBasicC throw new AssertException("wrapperComponent should never listen to a componenent! source="+source.getComponentName()+", event "+event); } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(delegate != null) { + delegate.activate(ureq, entries, state); + } else if(realController instanceof Activateable2) { + ((Activateable2)realController).activate(ureq, entries, state); + } + } + /** * @see java.lang.Object#toString() */ diff --git a/src/main/java/org/olat/core/util/event/EventAgency.java b/src/main/java/org/olat/core/util/event/EventAgency.java index 6d9bd6146a3..75c23c33579 100644 --- a/src/main/java/org/olat/core/util/event/EventAgency.java +++ b/src/main/java/org/olat/core/util/event/EventAgency.java @@ -147,23 +147,10 @@ class EventAgency { */ void addListener(GenericEventListener gel, Identity identity) { synchronized (listeners) { //o_clusterOK by:fj - if (listeners.containsKey(gel)) throw new AssertException(" already added gel:" + gel.getClass().getName() + " to eventagency " - + this.toString()); - - // here: look at the latest event fired. (1 sticky) - // if it is younger that this agency's ttl, then immediately fire it to the registrant. - // - /*if (latestEvent != null) { - long now = System.currentTimeMillis(); - if (now - latestEventTimestamp < ttl) { - gel.event(latestEvent); - // by design: the latestEvent is never consumed; - // an eventlistener could receive the same message more than once if a) the ttl is high, and b) - // it registers/deregisters more than once. - } else { - latestEvent = null; // object is too old to be considered as missed update - } - }*/ + if (listeners.containsKey(gel)) { + //already registered, do nothing + return; + } String identityName = (identity != null? identity.getName() : null); listeners.put(gel, identityName); diff --git a/src/main/java/org/olat/core/util/tree/TreeHelper.java b/src/main/java/org/olat/core/util/tree/TreeHelper.java index 2bbdc4a14b1..3ebffa12b69 100644 --- a/src/main/java/org/olat/core/util/tree/TreeHelper.java +++ b/src/main/java/org/olat/core/util/tree/TreeHelper.java @@ -21,6 +21,8 @@ package org.olat.core.util.tree; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.olat.core.gui.components.tree.TreeModel; @@ -88,6 +90,16 @@ public class TreeHelper { return conPath.toString(); } + //fxdiff FXOLAT-163: back/resume + public static List<TreeNode> getTreePath(TreeNode node) { + List<TreeNode> conPath = new ArrayList<TreeNode>(); + for (TreeNode cur = node; cur != null; cur = (TreeNode) cur.getParent()) { + conPath.add(cur); + } + Collections.reverse(conPath); + return conPath; + } + /** * from tree structure to a flat list * @param node diff --git a/src/main/java/org/olat/course/DisposedCourseRestartController.java b/src/main/java/org/olat/course/DisposedCourseRestartController.java index f71b4e0777b..78650941f49 100644 --- a/src/main/java/org/olat/course/DisposedCourseRestartController.java +++ b/src/main/java/org/olat/course/DisposedCourseRestartController.java @@ -49,7 +49,7 @@ import org.olat.resource.OLATResourceManager; * * @author patrickb */ -class DisposedCourseRestartController extends BasicController { +public class DisposedCourseRestartController extends BasicController { private VelocityContainer initialContent; private Link restartLink; @@ -97,7 +97,8 @@ class DisposedCourseRestartController extends BasicController { /* * create new tab with "refreshed course run" and activate the course */ - dt = dts.createDTab(ores, courseRepositoryEntry.getDisplayname()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, courseRepositoryEntry, courseRepositoryEntry.getDisplayname()); if (dt == null) return; // full tabs -> warning already set by // dts.create... Controller launchController = ControllerFactory.createLaunchController(ores, null, ureq, dt.getWindowControl(), true); diff --git a/src/main/java/org/olat/course/archiver/ArchiverMainController.java b/src/main/java/org/olat/course/archiver/ArchiverMainController.java index 85c407f580d..7479981e4cf 100644 --- a/src/main/java/org/olat/course/archiver/ArchiverMainController.java +++ b/src/main/java/org/olat/course/archiver/ArchiverMainController.java @@ -108,7 +108,7 @@ public class ArchiverMainController extends MainLayoutBasicController { // Navigation menu menuTree = new MenuTree("menuTree"); - TreeModel tm = buildTreeModel(); + TreeModel tm = buildTreeModel(ureq); menuTree.setTreeModel(tm); menuTree.setSelectedNodeId(tm.getRootNode().getIdent()); menuTree.addListener(this); @@ -171,7 +171,7 @@ public class ArchiverMainController extends MainLayoutBasicController { * Generates the archiver menu * @return The generated menu tree model */ - private TreeModel buildTreeModel() { + private TreeModel buildTreeModel(UserRequest ureq) { GenericTreeNode root, gtn; GenericTreeModel gtm = new GenericTreeModel(); @@ -245,7 +245,7 @@ public class ArchiverMainController extends MainLayoutBasicController { for (int i = 0; i < cnt; i++) { Extension anExt = extm.getExtension(i); // check for sites - ActionExtension ae = (ActionExtension) anExt.getExtensionFor(extensionPointMenu.getName()); + ActionExtension ae = (ActionExtension) anExt.getExtensionFor(extensionPointMenu.getName(), ureq); if (ae != null) { gtn = new GenericTreeNode(); String menuText = ae.getActionText(locale); diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementsListController.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementsListController.java index 90f587f055c..e275a51adcd 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatementsListController.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementsListController.java @@ -88,7 +88,7 @@ public class EfficiencyStatementsListController extends BasicController { * @param wControl * @param ureq */ - public EfficiencyStatementsListController(WindowControl wControl, UserRequest ureq) { + public EfficiencyStatementsListController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); TableGuiConfiguration tableConfig = new TableGuiConfiguration(); @@ -162,7 +162,8 @@ public class EfficiencyStatementsListController extends BasicController { DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, efficiencyStatement.getCourseTitle()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, re, efficiencyStatement.getCourseTitle()); if (dt == null) return; Controller launchController = ControllerFactory.createLaunchController(ores, null, ureq, dt.getWindowControl(), true); dt.setController(launchController); diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java b/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java index 0d21da49213..0d7a11be199 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatementsPortletRunController.java @@ -30,9 +30,9 @@ import java.util.Locale; import java.util.Map; import org.apache.commons.lang.StringEscapeUtils; +import org.olat.NewControllerFactory; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; @@ -47,7 +47,6 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.creator.ControllerCreator; -import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; import org.olat.core.gui.control.generic.portal.AbstractPortletRunController; import org.olat.core.gui.control.generic.portal.PortletDefaultTableDataModel; @@ -56,11 +55,12 @@ import org.olat.core.gui.control.generic.portal.PortletToolSortingControllerImpl import org.olat.core.gui.control.generic.portal.SortingCriteria; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.event.GenericEventListener; import org.olat.course.CourseModule; -import org.olat.home.site.HomeSite; /** @@ -184,10 +184,11 @@ public class EfficiencyStatementsPortletRunController extends AbstractPortletRun */ public void event(UserRequest ureq, Component source, Event event) { if (source == showAllLink){ - // activate homes tab in top navigation and active efficiencyStatements menu item - //was brasato:: getWindowControl().getDTabs().activateStatic(ureq, HomeSite.class.getName(), "efficiencyStatements"); - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - dts.activateStatic(ureq, HomeSite.class.getName(), "efficiencyStatements"); + // activate homes tab in top navigation and active calendar menu item + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][effstatements:0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); } else if (event == ComponentUtil.VALIDATE_EVENT && needReloadModel) { reloadModel(sortingCriteria); } diff --git a/src/main/java/org/olat/course/nodes/CourseNodeFactory.java b/src/main/java/org/olat/course/nodes/CourseNodeFactory.java index 507b9a90822..45f6adb981c 100644 --- a/src/main/java/org/olat/course/nodes/CourseNodeFactory.java +++ b/src/main/java/org/olat/course/nodes/CourseNodeFactory.java @@ -163,7 +163,8 @@ public class CourseNodeFactory { DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, repositoryEntry.getDisplayname()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, repositoryEntry, repositoryEntry.getDisplayname()); if (dt == null){ //null means DTabs are full -> warning is shown return; diff --git a/src/main/java/org/olat/course/nodes/STCourseNode.java b/src/main/java/org/olat/course/nodes/STCourseNode.java index bbf8121bdf7..8d02de71504 100644 --- a/src/main/java/org/olat/course/nodes/STCourseNode.java +++ b/src/main/java/org/olat/course/nodes/STCourseNode.java @@ -276,8 +276,8 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Assess sd = new StatusDescription(StatusDescription.ERROR, shortKey, longKey, params, translPackage); sd.setDescriptionForUnit(getIdent()); // set which pane is affected by error - sd.setActivateableViewIdentifier(STCourseNodeEditController.PANE_TAB_ST_CONFIG); - } + sd.setActivateableViewIdentifier(STCourseNodeEditController.PANE_TAB_ST_CONFIG); + } } return sd; } diff --git a/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java index 07b0d891c3c..9e1fb55116d 100644 --- a/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java @@ -21,6 +21,8 @@ package org.olat.course.nodes.bc; +import java.util.List; + import org.olat.core.commons.modules.bc.FolderRunController; import org.olat.core.commons.modules.bc.vfs.OlatNamedContainerImpl; import org.olat.core.gui.UserRequest; @@ -29,6 +31,10 @@ import org.olat.core.gui.control.DefaultController; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.id.Identity; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.util.notifications.SubscriptionContext; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.course.CourseModule; @@ -42,7 +48,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * * @author gnaegi */ -public class BCCourseNodeRunController extends DefaultController implements Activateable { +public class BCCourseNodeRunController extends DefaultController implements Activateable, Activateable2 { private FolderRunController frc; @@ -103,4 +109,12 @@ public class BCCourseNodeRunController extends DefaultController implements Acti } } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if (frc != null) { + frc.activate(ureq, entries, state); + } + } } diff --git a/src/main/java/org/olat/course/nodes/cp/CPRunController.java b/src/main/java/org/olat/course/nodes/cp/CPRunController.java index ca0a5b97680..0149beeeb1b 100644 --- a/src/main/java/org/olat/course/nodes/cp/CPRunController.java +++ b/src/main/java/org/olat/course/nodes/cp/CPRunController.java @@ -22,6 +22,7 @@ package org.olat.course.nodes.cp; import java.io.File; +import java.util.List; import org.olat.core.gui.UserRequest; import org.olat.core.gui.Windows; @@ -34,9 +35,12 @@ import org.olat.core.gui.control.ControllerEventListener; 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.id.OLATResourceable; import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -62,7 +66,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * @author Felix Jost * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>) */ -public class CPRunController extends BasicController implements ControllerEventListener { +public class CPRunController extends BasicController implements ControllerEventListener, Activateable2 { private static final OLog log = Tracing.createLoggerFor(CPRunController.class); private String attrFromStartpage; @@ -161,6 +165,14 @@ public class CPRunController extends BasicController implements ControllerEventL fireEvent(ureq, event); } } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + cpDispC.activate(ureq, entries, state); + } private void doLaunch(UserRequest ureq) { if (cpRoot == null) { diff --git a/src/main/java/org/olat/course/nodes/fo/FOCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/fo/FOCourseNodeRunController.java index b24d1484c4a..73f777bfa7c 100644 --- a/src/main/java/org/olat/course/nodes/fo/FOCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/fo/FOCourseNodeRunController.java @@ -21,6 +21,8 @@ package org.olat.course.nodes.fo; +import java.util.List; + import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; import org.olat.core.gui.UserRequest; @@ -34,6 +36,10 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.docking.DockController; import org.olat.core.gui.control.generic.docking.DockLayoutControllerCreatorCallback; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.gui.control.generic.title.TitledWrapperController; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.course.CourseFactory; import org.olat.course.nodes.FOCourseNode; import org.olat.course.nodes.TitledWrapperHelper; @@ -50,7 +56,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * @author gnaegi * @author BPS (<a href="http://www.bps-system.de/">BPS Bildungsportal Sachsen GmbH</a>) */ -public class FOCourseNodeRunController extends BasicController { +public class FOCourseNodeRunController extends BasicController implements Activateable2 { private DockController dockC; private FOCourseNode courseNode; @@ -128,5 +134,14 @@ public class FOCourseNodeRunController extends BasicController { // } - + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(dockC != null && dockC.getController() instanceof TitledWrapperController) { + TitledWrapperController wrapper2 = (TitledWrapperController)dockC.getController(); + if(wrapper2.getContentController() instanceof Activateable2) { + ((Activateable2)wrapper2.getContentController()).activate(ureq, entries, state); + } + } + } } diff --git a/src/main/java/org/olat/course/nodes/iq/IQRunController.java b/src/main/java/org/olat/course/nodes/iq/IQRunController.java index 0fcf4d20396..52b9b9498f7 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java @@ -40,10 +40,14 @@ import org.olat.core.gui.control.Controller; 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.iframe.IFrameDisplayController; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.util.Formatter; @@ -88,7 +92,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * Initial Date: Oct 13, 2004 * @author Felix Jost */ -public class IQRunController extends BasicController implements GenericEventListener { +public class IQRunController extends BasicController implements GenericEventListener, Activateable2 { private VelocityContainer myContent; @@ -371,7 +375,11 @@ public class IQRunController extends BasicController implements GenericEventList long callingResId = userCourseEnv.getCourseEnvironment().getCourseResourceableId().longValue(); String callingResDetail = courseNode.getIdent(); removeAsListenerAndDispose(displayController); - Controller returnController = IQManager.getInstance().createIQDisplayController(modConfig, secCallback, ureq, getWindowControl(), callingResId, callingResDetail); + + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableTypeWithoutCheck("test"); + WindowControl bwControl = addToHistory(ureq, ores, null); + Controller returnController = IQManager.getInstance().createIQDisplayController(modConfig, secCallback, ureq, bwControl, callingResId, callingResDetail); /* * either returnController is a MessageController or it is a IQDisplayController * this should not serve as pattern to be copy&pasted. @@ -611,4 +619,14 @@ public class IQRunController extends BasicController implements GenericEventList } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry ce = entries.remove(0); + if("test".equals(ce.getOLATResourceable().getResourceableTypeName())) { + event(ureq, startButton, Event.CHANGED_EVENT); + } + } } diff --git a/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java index dc51e0b7d0b..8cc63a3c4b2 100644 --- a/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/portfolio/PortfolioCourseNodeRunController.java @@ -53,7 +53,7 @@ import org.olat.course.run.scoring.ScoreAccounting; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.NodeEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; import org.olat.modules.ModuleConfiguration; import org.olat.portfolio.EPLoggingAction; import org.olat.portfolio.manager.EPFrontendManager; diff --git a/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java b/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java index 76aa93b7ce7..61016c30b94 100644 --- a/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java +++ b/src/main/java/org/olat/course/nodes/wiki/WikiEditController.java @@ -213,7 +213,8 @@ public class WikiEditController extends ActivateableTabbableDefaultController im DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, repositoryEntry.getDisplayname()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, repositoryEntry, repositoryEntry.getDisplayname()); if (dt == null){ //null means DTabs are full -> warning is shown return; diff --git a/src/main/java/org/olat/course/nodes/wiki/WikiRunController.java b/src/main/java/org/olat/course/nodes/wiki/WikiRunController.java index 4d6a953373e..4bcece1df72 100644 --- a/src/main/java/org/olat/course/nodes/wiki/WikiRunController.java +++ b/src/main/java/org/olat/course/nodes/wiki/WikiRunController.java @@ -21,6 +21,8 @@ package org.olat.course.nodes.wiki; +import java.util.List; + import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; import org.olat.core.gui.UserRequest; @@ -34,9 +36,11 @@ import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.clone.CloneController; import org.olat.core.gui.control.generic.clone.CloneLayoutControllerCreatorCallback; import org.olat.core.gui.control.generic.clone.CloneableController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; 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.notifications.SubscriptionContext; import org.olat.course.CourseFactory; import org.olat.course.nodes.TitledWrapperHelper; @@ -59,7 +63,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * Initial Date: Oct 12, 2004 * @author Guido Schnider */ -public class WikiRunController extends BasicController { +public class WikiRunController extends BasicController implements Activateable2 { private Panel main; @@ -142,6 +146,13 @@ public class WikiRunController extends BasicController { } } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + wikiCtr.activate(ureq, entries, state); + } + /** * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, * org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index 12a34f96039..0dec9a9b897 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -53,11 +53,13 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.messages.MessageController; import org.olat.core.gui.control.generic.messages.MessageUIFactory; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; import org.olat.core.gui.control.generic.textmarker.GlossaryMarkupItemController; +import org.olat.core.gui.control.generic.title.TitledWrapperController; import org.olat.core.gui.control.generic.tool.ToolController; import org.olat.core.gui.control.generic.tool.ToolFactory; import org.olat.core.gui.translator.PackageTranslator; @@ -66,6 +68,7 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATSecurityException; import org.olat.core.logging.Tracing; @@ -130,7 +133,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * * @author Felix Jost */ -public class RunMainController extends MainLayoutBasicController implements GenericEventListener, Activateable { +public class RunMainController extends MainLayoutBasicController implements GenericEventListener, Activateable, Activateable2 { private static final String COMMAND_EDIT = "gotoeditor"; private static final String TOOLBOX_LINK_COURSECONFIG = "courseconfig"; @@ -498,6 +501,11 @@ public class RunMainController extends MainLayoutBasicController implements Gene * @return true if the node jumped to is visible */ private boolean updateTreeAndContent(UserRequest ureq, CourseNode calledCourseNode, String nodecmd) { + return updateTreeAndContent(ureq, calledCourseNode, nodecmd, null, null); + } + + //fxdiff BAKS-7 Resume function + private boolean updateTreeAndContent(UserRequest ureq, CourseNode calledCourseNode, String nodecmd, List<ContextEntry> entries, StateEntry state) { // build menu (treemodel) // dispose old node controller before creating the NodeClickedRef which creates // the new node controller. It is important that the old node controller is @@ -529,6 +537,19 @@ public class RunMainController extends MainLayoutBasicController implements Gene // get new run controller. currentNodeController = nclr.getRunController(); + //fxdiff BAKS-7 Resume function + if(currentNodeController instanceof Activateable2) { + ((Activateable2)currentNodeController).activate(ureq, entries, state); + } else if (currentNodeController instanceof TitledWrapperController) { + Controller contentcontroller = ((TitledWrapperController)currentNodeController).getContentController(); + if(contentcontroller instanceof Activateable2) { + ((Activateable2)contentcontroller).activate(ureq, entries, state); + } else { + addToHistory(ureq, currentNodeController); + } + } else { + addToHistory(ureq, currentNodeController); + } contentP.setContent(currentNodeController.getInitialComponent()); // enableCustomCourseCSS(ureq); @@ -585,6 +606,8 @@ public class RunMainController extends MainLayoutBasicController implements Gene currentNodeController = nclr.getRunController(); Component nodeComp = currentNodeController.getInitialComponent(); contentP.setContent(nodeComp); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, currentNodeController); // set glossary wrapper dirty after menu click to make it reload the glossary // stuff properly when in AJAX mode @@ -1319,7 +1342,11 @@ public class RunMainController extends MainLayoutBasicController implements Gene if (currentNodeController != null) { currentNodeController.dispose(); } - + //fxdiff BAKS-7 Resume function + if (viewIdentifier.startsWith("CourseNode:")) { + viewIdentifier = viewIdentifier.substring("CourseNode:".length()); + } + CourseNode cn = null; cn = (viewIdentifier == null ? null : course.getRunStructure().getNode(viewIdentifier)); String subsubId = null; @@ -1350,4 +1377,44 @@ public class RunMainController extends MainLayoutBasicController implements Gene uce.getCourseEnvironment(), glossaryMarkerCtr); listenTo(glossaryToolCtr); } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry firstEntry = entries.get(0); + if("CourseNode".equals(firstEntry.getOLATResourceable().getResourceableTypeName())) { + CourseNode cn = course.getRunStructure().getNode(firstEntry.getOLATResourceable().getResourceableId().toString()); + + // FIXME:fj:b is this needed in some cases?: currentCourseNode = cn; + getWindowControl().makeFlat(); + + // add loggin information for case course gets started via jumpin + // link/search + addLoggingResourceable(LoggingResourceable.wrap(course)); + if (cn != null) { + addLoggingResourceable(LoggingResourceable.wrap(cn)); + } + + if(entries.size() > 1) { + entries = entries.subList(1, entries.size()); + } + updateTreeAndContent(ureq, cn, null, entries, firstEntry.getTransientState()); + } + } + + // fxdiff: allow disabling after instantiation + public void disableToolController(boolean disable) { + columnLayoutCtr.hideCol2(disable); + } + + /** + * @see org.olat.core.gui.control.DefaultController#setDisposedMsgController(org.olat.core.gui.control.Controller) + */ + @Override + // fxdiff: exchange dispose controller + public void setDisposedMsgController(Controller disposeMsgController) { + super.setDisposedMsgController(disposeMsgController); + } } \ No newline at end of file diff --git a/src/main/java/org/olat/group/site/GroupsManagementSite.java b/src/main/java/org/olat/group/site/GroupsManagementSite.java index cba0d57ef68..e725b32a4d9 100644 --- a/src/main/java/org/olat/group/site/GroupsManagementSite.java +++ b/src/main/java/org/olat/group/site/GroupsManagementSite.java @@ -34,6 +34,8 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; import org.olat.group.ui.context.BGContextManagementController; @@ -75,7 +77,10 @@ public class GroupsManagementSite implements SiteInstance { * org.olat.core.gui.control.WindowControl) */ public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { - MainLayoutController c = ControllerFactory.createLaunchController(ORES_GROUPSMANAGEMENT, null, ureq, wControl, true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(GroupsManagementSite.class, 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); + MainLayoutController c = ControllerFactory.createLaunchController(ORES_GROUPSMANAGEMENT, null, ureq, bwControl, true); return c; } diff --git a/src/main/java/org/olat/group/site/GroupsSite.java b/src/main/java/org/olat/group/site/GroupsSite.java index 5218d5a8767..781b793073c 100644 --- a/src/main/java/org/olat/group/site/GroupsSite.java +++ b/src/main/java/org/olat/group/site/GroupsSite.java @@ -34,6 +34,8 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; import org.olat.group.ui.main.BGMainController; @@ -75,7 +77,10 @@ public class GroupsSite implements SiteInstance { * org.olat.core.gui.control.WindowControl) */ public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { - MainLayoutController c = ControllerFactory.createLaunchController(ORES_GROUPS, null, ureq, wControl, true); + //fxdiff BAKS-7 Resume function + OLATResourceable libraryOres = OresHelper.createOLATResourceableInstance(GroupsSite.class, 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, libraryOres, new StateSite(this), wControl, true); + MainLayoutController c = ControllerFactory.createLaunchController(ORES_GROUPS, null, ureq, bwControl, true); return c; } diff --git a/src/main/java/org/olat/group/ui/BGControllerFactory.java b/src/main/java/org/olat/group/ui/BGControllerFactory.java index 5997d2dacc6..ba2745290b1 100644 --- a/src/main/java/org/olat/group/ui/BGControllerFactory.java +++ b/src/main/java/org/olat/group/ui/BGControllerFactory.java @@ -179,7 +179,7 @@ public class BGControllerFactory { dt.setController(bgMrc); dts.addDTab(dt); } - dts.activate(ureq, dt, null); // null: do not activate to a certain view + dts.activate(ureq, dt, "", null); // null: do not activate to a certain view return bgMrc; } diff --git a/src/main/java/org/olat/group/ui/context/BGContextManagementController.java b/src/main/java/org/olat/group/ui/context/BGContextManagementController.java index 4afd620aef3..7124fb35b2b 100644 --- a/src/main/java/org/olat/group/ui/context/BGContextManagementController.java +++ b/src/main/java/org/olat/group/ui/context/BGContextManagementController.java @@ -43,13 +43,20 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.gui.control.generic.tool.ToolController; import org.olat.core.gui.control.generic.tool.ToolFactory; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.MultiUserEvent; +import org.olat.core.util.resource.OresHelper; import org.olat.group.BusinessGroup; import org.olat.group.context.BGContext; import org.olat.group.context.BGContextManager; @@ -70,7 +77,7 @@ import org.olat.group.ui.management.BGManagementController; * Initial Date: Jan 24, 2005 * @author gnaegi */ -public class BGContextManagementController extends MainLayoutBasicController { +public class BGContextManagementController extends MainLayoutBasicController implements Activateable, Activateable2 { // Menu commands private static final String CMD_INDEX = "cmd.index"; @@ -166,9 +173,13 @@ public class BGContextManagementController extends MainLayoutBasicController { String cmd = event.getCommand(); if (source == this.toolC) { handleToolCommands(ureq, cmd); - } else if (source == this.groupManagementController) { + } else if (source == groupManagementController) { if (event == Event.DONE_EVENT) { getWindowControl().pop(); + //fxdiff BAKS-7 Resume function + if(contextListCtr != null) {//de facto -> contextlist + addToHistory(ureq, contextListCtr); + } } } else if (source == this.confirmDeleteContext) { if (DialogBoxUIFactory.isYesEvent(event)) { @@ -281,9 +292,58 @@ public class BGContextManagementController extends MainLayoutBasicController { this.contextListVC = createVelocityContainer("contextlist"); } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, String viewIdentifier) { + if(viewIdentifier != null && viewIdentifier.endsWith(":0")) { + viewIdentifier = viewIdentifier.substring(0, viewIdentifier.length() - 2); + } + + if(CMD_CONTEXTLIST.equals(viewIdentifier)) { + TreeNode node = ((GenericTreeModel)olatMenuTree.getTreeModel()).findNodeByUserObject(CMD_CONTEXTLIST); + olatMenuTree.setSelectedNode(node); + doContextList(ureq, true); + } + } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry ce = entries.remove(0); + String type = ce.getOLATResourceable().getResourceableTypeName(); + TreeNode node = ((GenericTreeModel)olatMenuTree.getTreeModel()).findNodeByUserObject(type); + if(node != null) { + olatMenuTree.setSelectedNode(node); + + handleMenuCommands(ureq); + if(CMD_CONTEXTLIST.equals(ce.getOLATResourceable().getResourceableTypeName())) { + //try to select a context if there is one + if(!entries.isEmpty()) { + ContextEntry groupCe = entries.remove(0); + List<BGContext> contexts = contextTableModel.getObjects(); + for(BGContext context:contexts) { + if(context.getKey().equals(groupCe.getOLATResourceable().getResourceableId())) { + currentGroupContext = context; + break; + } + } + + if(currentGroupContext != null) { + doContextRun(ureq); + } + } + } + } + } + private void doIndex(UserRequest ureq) { this.content.setContent(this.indexVC); setTools(false); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_INDEX, 0l); + addToHistory(ureq, ores, null); } private void doContextCreateForm(UserRequest ureq, String type) { @@ -318,7 +378,10 @@ public class BGContextManagementController extends MainLayoutBasicController { private void doContextRun(UserRequest ureq) { removeAsListenerAndDispose(groupManagementController); - groupManagementController = BGControllerFactory.getInstance().createManagementController(ureq, getWindowControl(), this.currentGroupContext, false); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(BGContext.class, currentGroupContext.getKey()); + WindowControl bwControl = addToHistory(ureq, ores, null, contextListCtr.getWindowControlForDebug(), true); + groupManagementController = BGControllerFactory.getInstance().createManagementController(ureq, bwControl, this.currentGroupContext, false); listenTo (groupManagementController); //FIXME fg: no layout ctr in a modal panel! @@ -350,7 +413,10 @@ public class BGContextManagementController extends MainLayoutBasicController { tableConfig.setTableEmptyMessage(translate("contextlist.no.contexts")); // init group list filter controller removeAsListenerAndDispose(contextListCtr); - contextListCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator()); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_CONTEXTLIST, 0l); + WindowControl bwControl = addToHistory(ureq, ores, null, getWindowControl(), false); + contextListCtr = new TableController(tableConfig, ureq, bwControl, getTranslator()); listenTo(contextListCtr); this.contextListCtr.addColumnDescriptor(new DefaultColumnDescriptor("contextlist.table.name", 0, CMD_CONTEXT_RUN, ureq.getLocale())); @@ -368,6 +434,8 @@ public class BGContextManagementController extends MainLayoutBasicController { this.contextTableModel = new BGContextTableModel(contexts, getTranslator(), true, false); this.contextListCtr.setTableDataModel(this.contextTableModel); } + //fxdiff BAKS-7 Resume function + addToHistory(ureq, contextListCtr); this.content.setContent(this.contextListVC); setTools(false); } diff --git a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java index f64f540ed6b..0c709135909 100644 --- a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java +++ b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditController.java @@ -21,6 +21,7 @@ package org.olat.group.ui.edit; +import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -42,15 +43,20 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.choice.Choice; import org.olat.core.gui.components.tabbedpane.TabbedPane; +import org.olat.core.gui.components.tabbedpane.TabbedPaneChangedEvent; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.ControllerEventListener; 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.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.id.Identity; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.activity.ActionType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; @@ -98,7 +104,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * @author patrick */ -public class BusinessGroupEditController extends BasicController implements ControllerEventListener, GenericEventListener { +public class BusinessGroupEditController extends BasicController implements ControllerEventListener, GenericEventListener, Activateable2 { //needed for complicated fall back translator chaining private static final String PACKAGE = Util.getPackageName(BusinessGroupEditController.class); @@ -221,6 +227,13 @@ public class BusinessGroupEditController extends BasicController implements Cont listenTo(alreadyLockedDialogController); alreadyLockedDialogController.activate(); } + //fxdiff BAKS-7 Resume function + ContextEntry ce = wControl.getBusinessControl().popLauncherContextEntry(); + if(ce != null) { + wControl.getBusinessControl().setCurrentContextEntry(BusinessControlFactory.getInstance().createContextEntry(currBusinessGroup));//tab are not in the regular path + tabbedPane.activate(ureq, Collections.singletonList(ce), null); + tabbedPane.addToHistory(ureq, wControl); + } } /** @@ -256,8 +269,10 @@ public class BusinessGroupEditController extends BasicController implements Cont // notify current active users of this business group BusinessGroupModifiedEvent.fireModifiedGroupEvents(BusinessGroupModifiedEvent.GROUPRIGHTS_MODIFIED_EVENT, currBusinessGroup, null); } + //fxdiff BAKS-7 Resume function + } else if (source == tabbedPane && event instanceof TabbedPaneChangedEvent) { + tabbedPane.addToHistory(ureq, getWindowControl()); } - } /** @@ -628,6 +643,12 @@ public class BusinessGroupEditController extends BasicController implements Cont dispose(); } } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + tabbedPane.activate(ureq, entries, state); + } /** * @return true if lock on group has been acquired, flase otherwhise diff --git a/src/main/java/org/olat/group/ui/main/BGMainController.java b/src/main/java/org/olat/group/ui/main/BGMainController.java index 6715e191be3..af4cd8630b8 100644 --- a/src/main/java/org/olat/group/ui/main/BGMainController.java +++ b/src/main/java/org/olat/group/ui/main/BGMainController.java @@ -54,11 +54,17 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.gui.control.generic.tool.ToolController; import org.olat.core.gui.control.generic.tool.ToolFactory; import org.olat.core.id.Identity; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.Util; @@ -66,6 +72,7 @@ import org.olat.core.util.mail.ContactList; import org.olat.core.util.notifications.NotificationsManager; import org.olat.core.util.notifications.Publisher; import org.olat.core.util.notifications.SubscriptionContext; +import org.olat.core.util.resource.OresHelper; import org.olat.core.util.tree.TreeHelper; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupManager; @@ -103,7 +110,7 @@ import de.bps.olat.util.notifications.SubscriptionProviderImpl; * @author patrick */ -public class BGMainController extends MainLayoutBasicController implements Activateable { +public class BGMainController extends MainLayoutBasicController implements Activateable, Activateable2 { private static final String PACKAGE = Util.getPackageName(BGMainController.class); /* * things a controller needs during its lifetime @@ -135,6 +142,9 @@ public class BGMainController extends MainLayoutBasicController implements Activ private static final String CMD_MENU_BUDDY = "cmd.menu.buddy"; private static final String CMD_MENU_LEARN = "cmd.menu.learn"; private static final String CMD_MENU_RIGHT = "cmd.menu.right"; + //fxdiff VCRP-1,2: access control of resources + private static final String CMD_MENU_OPEN = "cmd.menu.open"; + private static final String CMD_MENU_OPEN_SEARCH = "cmd.menu.open.search"; /** * @param ureq @@ -224,7 +234,11 @@ public class BGMainController extends MainLayoutBasicController implements Activ String trnslP = currBusinessGroup.getName(); if (actionid.equals(TABLE_ACTION_LAUNCH)) { - BGControllerFactory.getInstance().createRunControllerAsTopNavTab(currBusinessGroup, ureq, getWindowControl(), false, null); + //fxdiff BAKS-7 Resume function + Controller ctrl = BGControllerFactory.getInstance().createRunControllerAsTopNavTab(currBusinessGroup, ureq, getWindowControl(), false, null); + if(ctrl != null) { + addToHistory(ureq, ctrl); + } } else if (actionid.equals(TABLE_ACTION_DELETE) && currBusinessGroup.getType().equals(BusinessGroup.TYPE_BUDDYGROUP)) { // only for buddygroups allowed deleteDialogBox = activateYesNoDialog(ureq, null, translate("dialog.modal.bg.delete.text", trnslP), deleteDialogBox); @@ -433,6 +447,9 @@ public class BGMainController extends MainLayoutBasicController implements Activ main.setPage(Util.getPackageVelocityRoot(this.getClass()) + "/index.html"); // 4) update toolboxe columnLayoutCtr.hideCol2(false); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_INDEX, 0l); + addToHistory(ureq, ores, null, wControl, true); } /** @@ -450,6 +467,9 @@ public class BGMainController extends MainLayoutBasicController implements Activ main.setPage(Util.getPackageVelocityRoot(this.getClass()) + "/buddy.html"); // 4) update toolboxe columnLayoutCtr.hideCol2(false); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_BUDDY, 0l); + addToHistory(ureq, ores, null, wControl, true); } /** @@ -467,6 +487,9 @@ public class BGMainController extends MainLayoutBasicController implements Activ main.setPage(Util.getPackageVelocityRoot(this.getClass()) + "/learning.html"); // 4) update toolboxe columnLayoutCtr.hideCol2(true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_LEARN, 0l); + addToHistory(ureq, ores, null, wControl, true); } /** @@ -484,6 +507,9 @@ public class BGMainController extends MainLayoutBasicController implements Activ main.setPage(Util.getPackageVelocityRoot(this.getClass()) + "/right.html"); // 4) update toolboxe columnLayoutCtr.hideCol2(true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_RIGHT, 0l); + addToHistory(ureq, ores, null, wControl, true); } /** @@ -685,6 +711,11 @@ public class BGMainController extends MainLayoutBasicController implements Activ public void activate(UserRequest ureq, String viewIdentifier) { // find the menu node that has the user object that represents the // viewIdentifyer + //fxdiff BAKS-7 Resume function + if(viewIdentifier != null && viewIdentifier.endsWith(":0")) { + viewIdentifier = viewIdentifier.substring(0, viewIdentifier.length() - 2); + } + GenericTreeNode rootNode = (GenericTreeNode) this.menuTree.getTreeModel().getRootNode(); TreeNode activatedNode = TreeHelper.findNodeByUserObject(viewIdentifier, rootNode); if (activatedNode != null) { @@ -701,6 +732,39 @@ public class BGMainController extends MainLayoutBasicController implements Activ } } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry entry = entries.get(0); + String type = entry.getOLATResourceable().getResourceableTypeName(); + + TreeNode rootNode = menuTree.getTreeModel().getRootNode(); + TreeNode activatedNode = TreeHelper.findNodeByUserObject(type, rootNode); + if (activatedNode != null) { + menuTree.setSelectedNode(activatedNode); + activateContent(ureq, activatedNode.getUserObject()); + } else if(CMD_MENU_OPEN_SEARCH.equals(type)) { + //segmented view ? + activatedNode = TreeHelper.findNodeByUserObject(CMD_MENU_OPEN, rootNode); + if(activatedNode != null) { + menuTree.setSelectedNode(activatedNode); + activateContent(ureq, CMD_MENU_OPEN_SEARCH); + } + } + + if(activatedNode == null) { + // not found, activate the root node + menuTree.setSelectedNode(rootNode); + activateContent(ureq, rootNode.getUserObject()); + //check for toolbox activation points + if (type.equals(ACTION_ADD_BUDDYGROUP)) { + initAddBuddygroupWorkflow(ureq); + } + } + } + /** * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) */ diff --git a/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java b/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java index c1c40793fdb..a65b908d29f 100644 --- a/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java +++ b/src/main/java/org/olat/group/ui/run/BusinessGroupMainRunController.java @@ -50,6 +50,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.dtabs.DTab; import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.messages.MessageUIFactory; @@ -59,6 +60,7 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.activity.OlatResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; @@ -103,7 +105,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * @author patrick */ -public class BusinessGroupMainRunController extends MainLayoutBasicController implements GenericEventListener { +public class BusinessGroupMainRunController extends MainLayoutBasicController implements GenericEventListener, Activateable2 { private static final String INITVIEW_TOOLFOLDER = "toolfolder"; public static final OLATResourceable ORES_TOOLFOLDER = OresHelper.createOLATResourceableType(INITVIEW_TOOLFOLDER); @@ -119,6 +121,12 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im public static final String INITVIEW_TOOLCAL = "action.calendar.group"; public static final OLATResourceable ORES_TOOLCAL = OresHelper.createOLATResourceableType(INITVIEW_TOOLCAL); + //fxdiff BAKS-7 Resume function + public static final OLATResourceable ORES_TOOLMSG = OresHelper.createOLATResourceableType("toolmsg"); + public static final OLATResourceable ORES_TOOLADMIN = OresHelper.createOLATResourceableType("tooladmin"); + public static final OLATResourceable ORES_TOOLCONTACT = OresHelper.createOLATResourceableType("toolcontact"); + public static final OLATResourceable ORES_TOOLMEMBERS = OresHelper.createOLATResourceableType("toolmembers"); + public static final OLATResourceable ORES_TOOLRESOURCES = OresHelper.createOLATResourceableType("toolresources"); private static final String PACKAGE = Util.getPackageName(BusinessGroupMainRunController.class); @@ -186,6 +194,12 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im private GenericTreeNode nodeWiki; private GenericTreeNode nodeCal; private GenericTreeNode nodePortfolio; + //fxdiff BAKS-7 Resume function + private GenericTreeNode nodeContact; + private GenericTreeNode nodeGroupOwners; + private GenericTreeNode nodeResources; + private GenericTreeNode nodeInformation; + private GenericTreeNode nodeAdmin; private boolean groupRunDisabled; private OLATResourceable assessmentEventOres; @@ -393,6 +407,10 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im TreeNode selTreeNode = bgTree.getSelectedNode(); String cmd = (String) selTreeNode.getUserObject(); handleTreeActions(ureq, cmd); + //fxdiff BAKS-7 Resume function + if(collabToolCtr != null) { + addToHistory(ureq, collabToolCtr); + } } else if (groupRunDisabled) { handleTreeActions(ureq, ACTIVITY_MENUSELECT_OVERVIEW); this.showError("grouprun.disabled"); @@ -405,14 +423,7 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im * org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) */ public void event(UserRequest ureq, Controller source, Event event) { - if (source == collabToolCtr) { - if (event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.BACK_EVENT || event == Event.FAILED_EVENT) { - // In all cases (success or failure) we - // go back to the group overview page. - bgTree.setSelectedNodeId(bgTree.getTreeModel().getRootNode().getIdent()); - mainPanel.setContent(main); - } - } else if (source == bgEditCntrllr) { + if (source == bgEditCntrllr) { // changes from the admin controller if (event == Event.CHANGED_EVENT) { TreeModel trMdl = buildTreeModel(); @@ -442,7 +453,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, title); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, currentRepoEntry, title); if (dt == null) return; Controller ctrl = ControllerFactory.createLaunchController(ores, null, ureq, dt.getWindowControl(), true); dt.setController(ctrl); @@ -463,8 +475,16 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im bgTree.setSelectedNodeId(bgTree.getTreeModel().getRootNode().getIdent()); mainPanel.setContent(main); } - } - + //fxdiff BAKS-7 Resume function -> need to be at the end, sendToChooserForm are collabToolCtr too + } else if (source == collabToolCtr) { + if (event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.BACK_EVENT || event == Event.FAILED_EVENT) { + // In all cases (success or failure) we + // go back to the group overview page. + bgTree.setSelectedNodeId(bgTree.getTreeModel().getRootNode().getIdent()); + mainPanel.setContent(main); + } + //fxdiff VCRP-1,2: access control of resources + } } /** @@ -639,7 +659,10 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im listenTo(collabToolCtr); mainPanel.setContent(collabToolCtr.getInitialComponent()); } else if (ACTIVITY_MENUSELECT_INFORMATION.equals(cmd)) { - collabToolCtr = collabTools.createNewsController(ureq, getWindowControl()); + //fxdiff BAKS-7 Resume function + ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(ORES_TOOLMSG); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, getWindowControl()); + collabToolCtr = collabTools.createNewsController(ureq, bwControl); listenTo(collabToolCtr); mainPanel.setContent(collabToolCtr.getInitialComponent()); } else if (ACTIVITY_MENUSELECT_FOLDER.equals(cmd)) { @@ -690,7 +713,9 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im private void doAdministration(UserRequest ureq) { removeAsListenerAndDispose(bgEditCntrllr); - bgEditCntrllr = BGControllerFactory.getInstance().createEditControllerFor(ureq, getWindowControl(), businessGroup); + //fxdiff BAKS-7 Resume function + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ORES_TOOLADMIN, null, getWindowControl()); + collabToolCtr = bgEditCntrllr = BGControllerFactory.getInstance().createEditControllerFor(ureq, bwControl, businessGroup); listenTo(bgEditCntrllr); mainPanel.setContent(bgEditCntrllr.getInitialComponent()); } @@ -698,7 +723,9 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im private void doContactForm(UserRequest ureq) { if (vc_sendToChooserForm == null) vc_sendToChooserForm = createVelocityContainer("cosendtochooser"); removeAsListenerAndDispose(sendToChooserForm); - sendToChooserForm = new BusinessGroupSendToChooserForm(ureq, getWindowControl(), businessGroup, isAdmin); + //fxdiff BAKS-7 Resume function + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ORES_TOOLCONTACT, null, getWindowControl()); + sendToChooserForm = new BusinessGroupSendToChooserForm(ureq, bwControl, businessGroup, isAdmin); listenTo(sendToChooserForm); vc_sendToChooserForm.put("vc_sendToChooserForm", sendToChooserForm.getInitialComponent()); mainPanel.setContent(vc_sendToChooserForm); @@ -739,6 +766,9 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im membersVc.contextPut("showWaitingList", Boolean.FALSE); } mainPanel.setContent(membersVc); + //fxdiff BAKS-7 Resume function + collabToolCtr = null; + addToHistory(ureq, ORES_TOOLMEMBERS, null); } /** @@ -765,6 +795,101 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im userSession.getSingleUserEventCenter().deregisterFor(this, assessmentEventOres); } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry ce = entries.remove(0); + activate(ureq, ce); + if(collabToolCtr instanceof Activateable2) { + ((Activateable2)collabToolCtr).activate(ureq, entries, ce.getTransientState()); + } + } + + //fxdiff BAKS-7 Resume function + private void activate(UserRequest ureq, ContextEntry ce) { + OLATResourceable ores = ce.getOLATResourceable(); + if (OresHelper.equals(ores, ORES_TOOLFORUM)) { + // start the forum + if (nodeForum != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_FORUM); + bgTree.setSelectedNode(nodeForum); + } else { // not enabled + String text = translate("warn.forumnotavailable"); + Controller mc = MessageUIFactory.createInfoMessage(ureq, getWindowControl(), null, text); + listenTo(mc); // cleanup on dispose + mainPanel.setContent(mc.getInitialComponent()); + } + } else if (OresHelper.equals(ores, ORES_TOOLFOLDER)) { + if (nodeFolder != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_FOLDER); + bgTree.setSelectedNode(nodeFolder); + } else { // not enabled + String text = translate("warn.foldernotavailable"); + Controller mc = MessageUIFactory.createInfoMessage(ureq, getWindowControl(), null, text); + listenTo(mc); // cleanup on dispose + mainPanel.setContent(mc.getInitialComponent()); + } + } else if (OresHelper.equals(ores, ORES_TOOLWIKI)) { + if (nodeWiki != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_WIKI); + bgTree.setSelectedNode(nodeWiki); + } else { // not enabled + String text = translate("warn.wikinotavailable"); + Controller mc = MessageUIFactory.createInfoMessage(ureq, getWindowControl(), null, text); + listenTo(mc); // cleanup on dispose + mainPanel.setContent(mc.getInitialComponent()); + } + } else if (OresHelper.equals(ores, ORES_TOOLCAL)) { + if (nodeCal != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_CALENDAR); + bgTree.setSelectedNode(nodeCal); + } else { // not enabled + String text = translate("warn.calnotavailable"); + Controller mc = MessageUIFactory.createInfoMessage(ureq, getWindowControl(), null, text); + listenTo(mc); // cleanup on dispose + mainPanel.setContent(mc.getInitialComponent()); + } + } else if (OresHelper.equals(ores, ORES_TOOLPORTFOLIO)) { + if (nodePortfolio != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_PORTFOLIO); + bgTree.setSelectedNode(nodePortfolio); + } else { // not enabled + String text = translate("warn.portfolionotavailable"); + Controller mc = MessageUIFactory.createInfoMessage(ureq, getWindowControl(), null, text); + listenTo(mc); // cleanup on dispose + mainPanel.setContent(mc.getInitialComponent()); + } + //fxdiff BAKS-7 Resume function + } else if (OresHelper.equals(ores, ORES_TOOLADMIN)) { + if (this.nodeAdmin != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_ADMINISTRATION); + bgTree.setSelectedNode(nodeAdmin); + } + } else if (OresHelper.equals(ores, ORES_TOOLMSG)) { + if (this.nodeInformation != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_INFORMATION); + bgTree.setSelectedNode(nodeInformation); + } + } else if (OresHelper.equals(ores, ORES_TOOLCONTACT)) { + if (this.nodeContact != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_CONTACTFORM); + bgTree.setSelectedNode(nodeContact); + } + } else if (OresHelper.equals(ores, ORES_TOOLMEMBERS)) { + if (this.nodeGroupOwners != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_MEMBERSLIST); + bgTree.setSelectedNode(nodeGroupOwners); + } + } else if (OresHelper.equals(ores, ORES_TOOLRESOURCES)) { + if (this.nodeResources != null) { + handleTreeActions(ureq, ACTIVITY_MENUSELECT_SHOW_RESOURCES); + bgTree.setSelectedNode(nodeResources); + } + } + } + /** * @see org.olat.core.util.event.GenericEventListener#event(org.olat.core.gui.control.Event) */ @@ -828,6 +953,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im // add table model to table resourcesCtr.setTableDataModel(repoTableModel); mainPanel.setContent(resourcesVC); + //fxdiff BAKS-7 Resume function + addToHistory(ureq, ORES_TOOLRESOURCES, null); } /** @@ -864,6 +991,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im gtnChild.setAltText(translate("menutree.news.alt")); gtnChild.setIconCssClass("o_news_icon"); root.addChild(gtnChild); + //fxdiff BAKS-7 Resume function + nodeInformation = gtnChild; } if (collabTools.isToolEnabled(CollaborationTools.TOOL_CALENDAR)) { @@ -883,6 +1012,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im gtnChild.setAltText(translate("menutree.resources.alt")); gtnChild.setIconCssClass("o_course_icon"); root.addChild(gtnChild); + //fxdiff BAKS-7 Resume function + nodeResources = gtnChild; } if ((flags.isEnabled(BGConfigFlags.GROUP_OWNERS) && bgpm.showOwners()) || bgpm.showPartips()) { @@ -894,6 +1025,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im gtnChild.setAltText(translate("menutree.members.alt")); gtnChild.setIconCssClass("b_group_icon"); root.addChild(gtnChild); + //fxdiff BAKS-7 Resume function + nodeGroupOwners = gtnChild; } if (collabTools.isToolEnabled(CollaborationTools.TOOL_CONTACT)) { @@ -903,6 +1036,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im gtnChild.setAltText(translate("menutree.contactform.alt")); gtnChild.setIconCssClass("o_co_icon"); root.addChild(gtnChild); + //fxdiff BAKS-7 Resume function + nodeContact = gtnChild; } if (collabTools.isToolEnabled(CollaborationTools.TOOL_FOLDER)) { @@ -971,6 +1106,8 @@ public class BusinessGroupMainRunController extends MainLayoutBasicController im gtnChild.setIconCssClass("o_admin_icon"); root.addChild(gtnChild); adminNodeId = gtnChild.getIdent(); + //fxdiff BAKS-7 Resume function + nodeAdmin = gtnChild; } return gtm; diff --git a/src/main/java/org/olat/home/GuestHomeInfoController.java b/src/main/java/org/olat/home/GuestHomeInfoController.java new file mode 100644 index 00000000000..c5341392c1f --- /dev/null +++ b/src/main/java/org/olat/home/GuestHomeInfoController.java @@ -0,0 +1,63 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <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 +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> +* <p> +*/ +package org.olat.home; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; + +/** + * + * Description:<br> + * this controller displays a header and a message (used for guest-info in minimalHome for guests) + * header and message are set in translation-properties + * + * + * <P> + * Initial Date: 12.09.2011 <br> + * @author strentini, sergio.trentini@frentix.com, www.frentix.com + */ +public class GuestHomeInfoController extends BasicController { + + private VelocityContainer vc; + + public GuestHomeInfoController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + vc = createVelocityContainer("guestinfo"); + putInitialPanel(vc); + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // TODO Auto-generated method stub + + } + + @Override + protected void doDispose() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/org/olat/home/HomeMainController.java b/src/main/java/org/olat/home/HomeMainController.java index c7775753d3b..549cec1e79b 100644 --- a/src/main/java/org/olat/home/HomeMainController.java +++ b/src/main/java/org/olat/home/HomeMainController.java @@ -1,614 +1,68 @@ /** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <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 -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <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> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <p> -*/ - + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ package org.olat.home; -import org.apache.commons.lang.StringEscapeUtils; -import org.olat.admin.user.UserSearchController; -import org.olat.basesecurity.events.SingleIdentityChosenEvent; -import org.olat.bookmark.ManageBookmarkController; -import org.olat.commons.rss.RSSUtil; -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; -import org.olat.core.commons.modules.bc.FolderRunController; -import org.olat.core.defaults.dispatcher.StaticMediaDispatcher; -import org.olat.core.extensions.ExtManager; -import org.olat.core.extensions.Extension; -import org.olat.core.extensions.action.ActionExtension; -import org.olat.core.extensions.action.GenericActionExtension; +import java.util.List; + import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.htmlheader.HtmlHeaderComponent; -import org.olat.core.gui.components.link.Link; -import org.olat.core.gui.components.link.LinkFactory; -import org.olat.core.gui.components.panel.Panel; -import org.olat.core.gui.components.tree.GenericTreeModel; -import org.olat.core.gui.components.tree.GenericTreeNode; -import org.olat.core.gui.components.tree.MenuTree; -import org.olat.core.gui.components.tree.TreeModel; -import org.olat.core.gui.components.tree.TreeNode; -import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.generic.dtabs.Activateable; -import org.olat.core.gui.control.generic.dtabs.DTab; -import org.olat.core.gui.control.generic.dtabs.DTabs; -import org.olat.core.gui.control.generic.portal.PortalImpl; -import org.olat.core.gui.render.StringOutput; -import org.olat.core.id.Identity; -import org.olat.core.id.OLATResourceable; -import org.olat.core.id.User; -import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.gui.control.generic.layout.GenericMainController; import org.olat.core.id.context.ContextEntry; -import org.olat.core.logging.AssertException; -import org.olat.core.util.UserSession; -import org.olat.core.util.resource.OresHelper; -import org.olat.core.util.tree.TreeHelper; -import org.olat.course.assessment.EfficiencyStatementsListController; -import org.olat.note.NoteListController; -import org.olat.notifications.NotificationUIFactory; -import org.olat.portfolio.EPUIFactory; -import org.olat.portfolio.PortfolioModule; -import org.olat.portfolio.manager.EPFrontendManager; -import org.olat.user.HomePageConfigManager; -import org.olat.user.HomePageConfigManagerImpl; -import org.olat.user.PersonalFolderManager; -import org.olat.user.PersonalSettingsController; -import org.olat.user.UserInfoMainController; -import org.olat.util.logging.activity.LoggingResourceable; - -import de.bps.olat.user.ChangeEMailExecuteController; +import org.olat.core.id.context.StateEntry; /** - * <!--**************--> - * <h3>Responsability:</h3> - * display the first page the user sees after she logged in successfully. This - * is the users individual dashboard within the learning management system.<br> - * The guest login has it's own {@link org.olat.home.GuestHomeMainController first page} ! - * <p> - * <!--**************--> - * <h3>Workflow:</h3> - * <ul> - * <li><i>Mainflow:</i><br> - * display portal.</li> - * <li><i>Portal editing:</i><br> - * Switch portal to edit mode.<br> - * edit portal.<br> - * switch to display mode.</li> - * <li><i>Activate target XYZ:</i><br> - * display activated component, i.e. jump to the personal briefcase</li> - * </ul> - * <p> - * <!--**************--> - * <h3>Activateable targets:</h3> - * <ul> - * <li><i>{@link #MENU_ROOT}</i>:<br> - * main entry point, the portal view.</li> - * <li><i>{@link #MENU_BC}</i>:<br> - * jump to personal briefcase.</li> - * <li><i>{@link #MENU_NOTE}</i>:<br> - * list of user notes.</li> - * <li><i>{@link #MENU_BOOKMARKS}</i>:<br> - * users bookmarks list.</li> - * <li><i>{@link #MENU_ADMINNOTIFICATIONS}</i>:<br> - * notifications list.</li> - * <li><i>{@link #MENU_OTHERUSERS}</i>:<br> - * search other users workflow.</li> - * <li><i>{@link #MENU_EFFICIENCY_STATEMENTS}</i>:<br> - * list of users efficency statements.</li> - * </ul> - * <p> - * <!--**************--> - * <h3>Hints:</h3> - * TODO:fg:a add here the hints/special notes for the HomeMainController - * <p> + * <h3>Description:</h3> Creates a MainController, which is configurable by + * olat_extensions * - * Initial Date: Apr 27, 2004 - * @author Felix Jost + * Initial Date: 06.05.2010 <br> + * + * @author Roman Haag, roman.haag@frentix.com, www.frentix.com */ -public class HomeMainController extends MainLayoutBasicController implements Activateable { - - // Menu commands. These are also used in velocity containers. When changing - // the values make sure you performed a full text search first - private static final String MENU_NOTE = "note"; - private static final String MENU_BC = "bc"; - private static final String MENU_CALENDAR = "cal"; - private static final String MENU_BOOKMARKS = "bookmarks"; - private static final String MENU_EFFICIENCY_STATEMENTS = "efficiencyStatements"; - private static final String MENU_ADMINNOTIFICATIONS = "adminnotifications"; - private static final String MENU_MYSETTINGS = "mysettings"; - private static final String MENU_ROOT = "root"; - private static final String MENU_OTHERUSERS = "otherusers"; - private static final String MENU_PORTFOLIO = "portfolio"; - private static final String MENU_PORTFOLIO_ARTEFACTS = "AbstractArtefact"; - private static final String MENU_PORTFOLIO_MY_MAPS = "portfolioMyMaps"; - private static final String MENU_PORTFOLIO_MY_STRUCTURED_MAPS = "portfolioMyStructuredMaps"; - private static final String MENU_PORTFOLIO_OTHERS_MAPS = "portfolioOthersMaps"; - private static final String PRESENTED_EMAIL_CHANGE_REMINDER = "presentedemailchangereminder"; - - private static boolean extensionLogged = false; - - private MenuTree olatMenuTree; - private VelocityContainer welcome; - private Link portalBackButton; - private Link portalEditButton; - private VelocityContainer inclTitle; - private Panel content; +public class HomeMainController extends GenericMainController implements Activateable, Activateable2 { - private LayoutMain3ColsController columnLayoutCtr; - private Controller resC; - private String titleStr; - private PortalImpl myPortal; - - /** - * Constructor of the home main controller - * - * @param ureq The user request - * @param wControl The current window controller - */ public HomeMainController(UserRequest ureq, WindowControl wControl) { - super(ureq, updateBusinessPath(ureq,wControl)); - - addLoggingResourceable(LoggingResourceable.wrap(ureq.getIdentity())); - - olatMenuTree = new MenuTree("olatMenuTree"); - TreeModel tm = buildTreeModel(ureq); - olatMenuTree.setTreeModel(tm); - olatMenuTree.setSelectedNodeId(tm.getRootNode().getIdent()); - olatMenuTree.addListener(this); - // Activate correct position in menu - olatMenuTree.setSelectedNode(tm.getRootNode()); - - // prepare main panel - content = new Panel("content"); - content.setContent(createRootComponent(ureq)); - - columnLayoutCtr = new LayoutMain3ColsController(ureq, getWindowControl(), olatMenuTree, null, content, "homemain"); - listenTo(columnLayoutCtr);// cleanup on dispose - // add background image to home site - columnLayoutCtr.addCssClassToMain("o_home"); - putInitialPanel(columnLayoutCtr.getInitialComponent()); - - // check if an existing session was killed, this is detected in UserSession.signOn() - Object killedExistingSession = ureq.getUserSession().getEntry(UserSession.STORE_KEY_KILLED_EXISTING_SESSION); - if (killedExistingSession != null && (killedExistingSession instanceof Boolean) ) { - if ( ((Boolean)killedExistingSession).booleanValue() ) { - this.showInfo("warn.session.was.killed"); - ureq.getUserSession().removeEntry(UserSession.STORE_KEY_KILLED_EXISTING_SESSION); - } - } - - // check running of email change workflow - if (ureq.getIdentity().getUser().getProperty("emchangeKey", null) != null) { - ChangeEMailExecuteController mm = new ChangeEMailExecuteController(ureq, wControl); - if (mm.isLinkTimeUp()) { - mm.deleteRegistrationKey(); - } else { - if (mm.isLinkClicked()) { - mm.changeEMail(wControl); - activateContent(ureq, MENU_MYSETTINGS, null); - } else { - Boolean alreadySeen = ((Boolean)ureq.getUserSession().getEntry(PRESENTED_EMAIL_CHANGE_REMINDER)); - if (alreadySeen == null) { - getWindowControl().setWarning(mm.getPackageTranslator().translate("email.change.reminder")); - ureq.getUserSession().putEntry(PRESENTED_EMAIL_CHANGE_REMINDER, Boolean.TRUE); - } - } - } - } else { - User user = ureq.getIdentity().getUser(); - String value = user.getProperty("emailDisabled", null); - if (value != null && value.equals("true")) { - wControl.setWarning(translate("email.disabled")); - } - } - } - - - private static WindowControl updateBusinessPath(UserRequest ureq, WindowControl wControl) { - ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(ureq.getIdentity()); - WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, wControl); - return bwControl; + super(ureq, wControl); + init(ureq); + addCssClassToMain("o_home"); } /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) + * @see org.olat.core.gui.control.generic.layout.GenericMainController#handleOwnMenuTreeEvent(java.lang.Object, + * org.olat.core.gui.UserRequest) */ - public void event(UserRequest ureq, Component source, Event event) { - if (source == portalBackButton){ - this.myPortal.setIsEditMode(ureq, Boolean.FALSE); - welcome.contextPut("portalEditMode", Boolean.FALSE); - } else if (source == portalEditButton){ - this.myPortal.setIsEditMode(ureq, Boolean.TRUE); - welcome.contextPut("portalEditMode", Boolean.TRUE); - } else if (source == olatMenuTree) { - if (event.getCommand().equals(MenuTree.COMMAND_TREENODE_CLICKED)) { - // process menu commands - TreeNode selTreeNode = olatMenuTree.getSelectedNode(); - if (selTreeNode.getDelegate() != null) { - selTreeNode = selTreeNode.getDelegate(); - olatMenuTree.setSelectedNode(selTreeNode); // enable right element - } - // test for extension commands - Object uObj = selTreeNode.getUserObject(); - activateContent(ureq, uObj, null); - } else { // FIXME:fj:b what is this...the action was not allowed anymore - content.setContent(null); // display an empty field (empty panel) - } - } else { - logWarn("Unhandled olatMenuTree event: " + event.getCommand(), null); - } - } - - /** - * Activate the content in the content area based on a user object - * representing the identifyer of the content - * - * @param ureq - * @param uObj - * @param activation args null or argument that is passed to child - */ - private void activateContent(UserRequest ureq, Object uObj, String activationArgs) { - if (uObj instanceof ActionExtension) { - ActionExtension ae = (ActionExtension) uObj; - removeAsListenerAndDispose(resC); - Controller extC = ae.createController(ureq, getWindowControl(), null); - content.setContent(extC.getInitialComponent()); - this.resC = extC; - listenTo(resC); - if(resC instanceof Activateable) { - ((Activateable)resC).activate(ureq, activationArgs); - } - - } else { - String cmd = (String) uObj; - doActivate(cmd, ureq, activationArgs); - } - } - - private void doActivate(String cmd, UserRequest ureq, String activationArgs) { - if (cmd.equals(MENU_ROOT)) { // check for root node clicked - content.setContent(createRootComponent(ureq)); - } else { // create a controller - removeAsListenerAndDispose(resC); - this.resC = createController(cmd, ureq); - listenTo(resC); - // activate certain state on controller - if (activationArgs != null && resC instanceof Activateable){ - Activateable activatableCtr = (Activateable) resC; - activatableCtr.activate(ureq, activationArgs); - } - Component resComp = resC.getInitialComponent(); - inclTitle = createVelocityContainer("incltitle"); - inclTitle.contextPut("titleString", titleStr); - inclTitle.contextPut("command", cmd); - inclTitle.put("exclTitle", resComp); - content.setContent(inclTitle); - } - } - - - /** - * @param ureq - * @param source - * @param event - */ - public void event(UserRequest ureq, Controller source, Event event) { - if (source == resC) { - // TODO:as:a move to own controller (homepage whatever controller) - if (event instanceof SingleIdentityChosenEvent) { - SingleIdentityChosenEvent foundEvent = (SingleIdentityChosenEvent) event; - Identity chosenIdentity = foundEvent.getChosenIdentity(); - if (chosenIdentity != null) { - HomePageConfigManager hpcm = HomePageConfigManagerImpl.getInstance(); - OLATResourceable ores = hpcm.loadConfigFor(chosenIdentity.getName()); - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - //was brasato:: DTabs dts = getWindowControl().getDTabs(); - DTab dt = dts.getDTab(ores); - if (dt == null) { - // does not yet exist -> create and add - dt = dts.createDTab(ores, chosenIdentity.getName()); - if (dt == null) return; - UserInfoMainController uimc = new UserInfoMainController(ureq, dt.getWindowControl(), chosenIdentity); - dt.setController(uimc); - dts.addDTab(dt); - } - dts.activate(ureq, dt, null); - } - } - } - } - - private Component createRootComponent(UserRequest ureq) { - // start screen - welcome = createVelocityContainer("welcome"); - portalBackButton = LinkFactory.createButtonXSmall("command.portal.back", welcome, this); - portalEditButton = LinkFactory.createButtonXSmall("command.portal.edit", welcome, this); - - // rss link - String rssLink = RSSUtil.getPersonalRssLink(ureq); - welcome.contextPut("rssLink", rssLink); - StringOutput staticUrl = new StringOutput(); - StaticMediaDispatcher.renderStaticURI(staticUrl, "js/egg.js"); - welcome.put("htmlHeader", new HtmlHeaderComponent("rss", null, "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"" - + StringEscapeUtils.escapeHtml(translate("welcome.rss")) + "\" href=\"" + rssLink + "\" />\n" + "<script type=\"text/javascript\" src=\"" - + staticUrl.toString() + "\"></script>")); - - // add portal - if (myPortal == null) myPortal = ((PortalImpl)CoreSpringFactory.getBean("homeportal")).createInstance(getWindowControl(), ureq); - welcome.put("myPortal", myPortal.getInitialComponent()); - welcome.contextPut("portalEditMode", Boolean.FALSE); - - return welcome; - } - - private Controller createController(String uobject, UserRequest ureq) { - if (uobject.equals(MENU_BC)) { - titleStr = translate("menu.bc"); - return new FolderRunController(PersonalFolderManager.getInstance().getContainer(ureq.getIdentity()), true, true, ureq, getWindowControl()); - } else if (uobject.equals(MENU_MYSETTINGS)) { - titleStr = translate("menu.mysettings"); - return new PersonalSettingsController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_CALENDAR)) { - titleStr = translate("menu.calendar"); - return new HomeCalendarController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_BOOKMARKS)) { - titleStr = translate("menu.bookmarks"); - return new ManageBookmarkController(ureq, getWindowControl(), true, ManageBookmarkController.SEARCH_TYPE_ALL); - } else if (uobject.equals(MENU_EFFICIENCY_STATEMENTS)) { - titleStr = translate("menu.efficiencyStatements"); - return new EfficiencyStatementsListController(getWindowControl(), ureq); - } else if (uobject.equals(MENU_ADMINNOTIFICATIONS)) { - titleStr = translate("menu.notifications"); - return NotificationUIFactory.createCombinedSubscriptionsAndNewsController(ureq.getIdentity(), ureq, getWindowControl()); - } else if (uobject.equals(MENU_NOTE)) { - titleStr = translate("menu.note"); - return new NoteListController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_OTHERUSERS)) { - titleStr = translate("menu.otherusers"); - return new UserSearchController(ureq, getWindowControl(), false); - } else if (uobject.equals(MENU_PORTFOLIO_ARTEFACTS)) { - titleStr = ""; - return EPUIFactory.createPortfolioPoolController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_PORTFOLIO_MY_MAPS)) { - titleStr = ""; - return EPUIFactory.createPortfolioMapsController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_PORTFOLIO_MY_STRUCTURED_MAPS)) { - titleStr = ""; - return EPUIFactory.createPortfolioStructuredMapsController(ureq, getWindowControl()); - } else if (uobject.equals(MENU_PORTFOLIO_OTHERS_MAPS)) { - titleStr = ""; - return EPUIFactory.createPortfolioMapsFromOthersController(ureq, getWindowControl()); - } + @Override + protected Controller handleOwnMenuTreeEvent(Object uobject, UserRequest ureq) { return null; } - private TreeModel buildTreeModel(UserRequest ureq) { - GenericTreeNode root, gtn; - - GenericTreeModel gtm = new GenericTreeModel(); - root = new GenericTreeNode(); - root.setTitle(translate("menu.root")); - root.setUserObject(MENU_ROOT); - root.setAltText(translate("menu.root.alt")); - gtm.setRootNode(root); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.mysettings")); - gtn.setUserObject(MENU_MYSETTINGS); - gtn.setAltText(translate("menu.mysettings.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.calendar")); - gtn.setUserObject(MENU_CALENDAR); - gtn.setAltText(translate("menu.calendar.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.notifications")); - gtn.setUserObject(MENU_ADMINNOTIFICATIONS); - gtn.setAltText(translate("menu.notifications.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.bookmarks")); - gtn.setUserObject(MENU_BOOKMARKS); - gtn.setAltText(translate("menu.bookmarks.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.bc")); - gtn.setUserObject(MENU_BC); - gtn.setAltText(translate("menu.bc.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.note")); - gtn.setUserObject(MENU_NOTE); - gtn.setAltText(translate("menu.note.alt")); - root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.efficiencyStatements")); - gtn.setUserObject(MENU_EFFICIENCY_STATEMENTS); - gtn.setAltText(translate("menu.efficiencyStatements.alt")); - root.addChild(gtn); - - //not yet active -// gtn = new GenericTreeNode(); -// gtn.setTitle(translate("menu.weblog")); -// gtn.setUserObject(MENU_WEBLOG); -// gtn.setAltText(translate("menu.weblog.alt")); -// root.addChild(gtn); - - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.otherusers")); - gtn.setUserObject(MENU_OTHERUSERS); - gtn.setAltText(translate("menu.otherusers.alt")); - root.addChild(gtn); - - PortfolioModule portfolioModule = (PortfolioModule)CoreSpringFactory.getBean("portfolioModule"); - if(portfolioModule.isEnabled()) { - //node portfolio - gtn = new GenericTreeNode(); - gtn.setTitle(translate("menu.portfolio")); - gtn.setUserObject(MENU_PORTFOLIO); - gtn.setAltText(translate("menu.portfolio.alt")); - root.addChild(gtn); - - //my artefacts - GenericTreeNode pgtn = new GenericTreeNode(); - pgtn.setTitle(translate("menu.portfolio.myartefacts")); - pgtn.setUserObject(MENU_PORTFOLIO_ARTEFACTS); - pgtn.setAltText(translate("menu.portfolio.myartefacts.alt")); - gtn.setDelegate(pgtn); - gtn.addChild(pgtn); - - //my maps - pgtn = new GenericTreeNode(); - pgtn.setTitle(translate("menu.portfolio.mymaps")); - pgtn.setUserObject(MENU_PORTFOLIO_MY_MAPS); - pgtn.setAltText(translate("menu.portfolio.mymaps.alt")); - gtn.addChild(pgtn); - - //my exercises - pgtn = new GenericTreeNode(); - pgtn.setTitle(translate("menu.portfolio.mystructuredmaps")); - pgtn.setUserObject(MENU_PORTFOLIO_MY_STRUCTURED_MAPS); - pgtn.setAltText(translate("menu.portfolio.mystructuredmaps.alt")); - gtn.addChild(pgtn); - - //others maps - pgtn = new GenericTreeNode(); - pgtn.setTitle(translate("menu.portfolio.othermaps")); - pgtn.setUserObject(MENU_PORTFOLIO_OTHERS_MAPS); - pgtn.setAltText(translate("menu.portfolio.othermaps.alt")); - gtn.addChild(pgtn); - } - - // add extension menues - ExtManager extm = ExtManager.getInstance(); - Class<? extends HomeMainController> extensionPointMenu = this.getClass(); - int cnt = extm.getExtensionCnt(); - for (int i = 0; i < cnt; i++) { - Extension anExt = extm.getExtension(i); - // check for extensions - ActionExtension ae = (ActionExtension) anExt.getExtensionFor(extensionPointMenu.getName()); - if (ae != null) { - if (anExt.isEnabled()) { - gtn = new GenericTreeNode(); - String menuText = ae.getActionText(getLocale()); - gtn.setTitle(menuText); - gtn.setUserObject(ae); - gtn.setAltText(ae.getDescription(getLocale())); - - if (ae instanceof GenericActionExtension && ((GenericActionExtension) ae).getNodeIdentifierIfParent() != null) gtn.setIdent(((GenericActionExtension) ae).getNodeIdentifierIfParent()); - if (ae instanceof GenericActionExtension && ((GenericActionExtension) ae).getParentTreeNodeIdentifier() != null){ - GenericTreeNode parentNode = (GenericTreeNode) gtm.getNodeById(((GenericActionExtension) ae).getParentTreeNodeIdentifier()); - if (parentNode == null) throw new AssertException("could not find parent treeNode: " + ((GenericActionExtension) ae).getParentTreeNodeIdentifier() + ", make sure it gets loaded before child!"); - parentNode.addChild(gtn); - if (parentNode.getDelegate() == null) parentNode.setDelegate(gtn); - } else { - root.addChild(gtn); - } - - } - } - } - - return gtm; - } - - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ - protected void doDispose() { - // controllers are disposed in BasicController - if (myPortal != null) { - myPortal.dispose(); - myPortal = null; - } - } - - /** - * @see org.olat.core.gui.control.generic.dtabs.Activateable#activate(org.olat.core.gui.UserRequest, - * java.lang.String) - */ + @Override public void activate(UserRequest ureq, String viewIdentifier) { - - String subViewIdentifier = null; - int firstDot = viewIdentifier.indexOf("."); - if (firstDot != -1) { - subViewIdentifier = viewIdentifier.substring(firstDot + 1, viewIdentifier.length()); - viewIdentifier = viewIdentifier.substring(0,firstDot); - } - String[] parsedViewIdentifyers = viewIdentifier.split(":"); - - // find the menu node that has the user object that represents the - // viewIdentifyer - TreeNode rootNode = this.olatMenuTree.getTreeModel().getRootNode(); - TreeNode activatedNode = TreeHelper.findNodeByUserObject(parsedViewIdentifyers[0], rootNode); - if(activatedNode == null) { - activatedNode = findPortfolioNode(rootNode, parsedViewIdentifyers); - if(activatedNode != null) { - subViewIdentifier = parsedViewIdentifyers[1]; - } - } - - if (activatedNode != null) { - this.olatMenuTree.setSelectedNodeId(activatedNode.getIdent()); - activateContent(ureq, activatedNode.getUserObject(), subViewIdentifier); - } else { - // not found, activate the root node - this.olatMenuTree.setSelectedNodeId(rootNode.getIdent()); - activateContent(ureq, rootNode.getUserObject(), subViewIdentifier); - } + super.activate(ureq, viewIdentifier); } - - public TreeNode findPortfolioNode(TreeNode rootNode, String[] parsedViewIdentifyers) { - String context = parsedViewIdentifyers[0]; - if("EPDefaultMap".equals(context) || "EPStructuredMap".equals(context)) { - //it's my problem - EPFrontendManager ePFMgr = (EPFrontendManager)CoreSpringFactory.getBean("epFrontendManager"); - - Long key = Long.parseLong(parsedViewIdentifyers[1]); - OLATResourceable ores = OresHelper.createOLATResourceableInstance(context, key); - boolean owner = ePFMgr.isMapOwner(getIdentity(), ores); - if(owner) { - if("EPDefaultMap".equals(context)) { - return TreeHelper.findNodeByUserObject(MENU_PORTFOLIO_MY_MAPS, rootNode); - } else if("EPStructuredMap".equals(context)) { - return TreeHelper.findNodeByUserObject(MENU_PORTFOLIO_MY_STRUCTURED_MAPS, rootNode); - } else { - logWarn("Unhandled portfolio map type: " + parsedViewIdentifyers, null); - } - } else { - return TreeHelper.findNodeByUserObject(MENU_PORTFOLIO_OTHERS_MAPS, rootNode); - } - } - return null; + + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + super.activate(ureq, entries, state); } -} \ No newline at end of file +} diff --git a/src/main/java/org/olat/home/HomeSite.java b/src/main/java/org/olat/home/HomeSite.java new file mode 100644 index 00000000000..2a44f3ec44a --- /dev/null +++ b/src/main/java/org/olat/home/HomeSite.java @@ -0,0 +1,95 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home; + +import org.olat.core.commons.chiefcontrollers.BaseChiefController; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.layout.MainLayoutController; +import org.olat.core.gui.control.navigation.DefaultNavElement; +import org.olat.core.gui.control.navigation.NavElement; +import org.olat.core.gui.control.navigation.SiteInstance; +import org.olat.core.gui.translator.Translator; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; +import org.olat.core.util.Util; +import org.olat.core.util.resource.OresHelper; + +/** + * <h3>Description:</h3> Instantiates the genericmainctrl for a minimal home + * site. Initial Date: 10.05.2010 <br> + * + * @author Roman Haag, roman.haag@frentix.com, www.frentix.com + */ +public class HomeSite implements SiteInstance { + + private DefaultNavElement curNavElem; + private NavElement origNavElem; + + public HomeSite(UserRequest ureq) { + Translator trans = Util.createPackageTranslator(BaseChiefController.class, ureq.getLocale()); + + if(ureq.getUserSession().getRoles().isGuestOnly()){ + origNavElem = new DefaultNavElement(trans.translate("topnav.guesthome"), trans.translate("topnav.guesthome.alt"), "o_site_home"); + }else{ + origNavElem = new DefaultNavElement(trans.translate("topnav.home"), trans.translate("topnav.home.alt"), "o_site_home"); + } + curNavElem = new DefaultNavElement(origNavElem); + } + + /** + * @see org.olat.core.gui.control.navigation.SiteInstance#createController(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { + OLATResourceable ores = OresHelper.createOLATResourceableInstance(HomeSite.class, ureq.getIdentity().getKey()); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); + MainLayoutController c = new HomeMainController(ureq, bwControl); + return c; + } + + /** + * @see org.olat.core.gui.control.navigation.SiteInstance#getNavElement() + */ + @Override + public NavElement getNavElement() { + return curNavElem; + } + + /** + * @see org.olat.core.gui.control.navigation.SiteInstance#isKeepState() + */ + @Override + public boolean isKeepState() { + return true; + } + + /** + * @see org.olat.core.gui.control.navigation.SiteInstance#reset() + */ + @Override + public void reset() { + curNavElem = new DefaultNavElement(origNavElem); + } + +} diff --git a/src/main/java/org/olat/home/HomeSiteDef.java b/src/main/java/org/olat/home/HomeSiteDef.java new file mode 100644 index 00000000000..865948e53cf --- /dev/null +++ b/src/main/java/org/olat/home/HomeSiteDef.java @@ -0,0 +1,52 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.navigation.AbstractSiteDefinition; +import org.olat.core.gui.control.navigation.SiteDefinition; +import org.olat.core.gui.control.navigation.SiteInstance; + +/** + * <h3>Description:</h3> + * <p> + * Site Def. for a minimal Home Initial Date: 10.05.2010 <br> + * + * @author Roman Haag, roman.haag@frentix.com, www.frentix.com + */ +public class HomeSiteDef extends AbstractSiteDefinition implements SiteDefinition { + + /** + * @see org.olat.core.gui.control.navigation.SiteDefinition#createSite(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public SiteInstance createSite(UserRequest ureq, WindowControl wControl) { + //fxdiff FXOLAT-151: better check invitation + if(ureq.getUserSession().getRoles().isInvitee()) { + return null; + } + + return new HomeSite(ureq); + } + +} diff --git a/src/main/java/org/olat/home/UserSearchAndInfoController.java b/src/main/java/org/olat/home/UserSearchAndInfoController.java new file mode 100644 index 00000000000..1469b58737c --- /dev/null +++ b/src/main/java/org/olat/home/UserSearchAndInfoController.java @@ -0,0 +1,107 @@ +/** +* OLAT - Online Learning and Training<br> +* http://www.olat.org +* <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 +* <p> +* http://www.apache.org/licenses/LICENSE-2.0 +* <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> +* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> +* University of Zurich, Switzerland. +* <p> +*/ +package org.olat.home; + +import org.olat.admin.user.UserSearchController; +import org.olat.basesecurity.events.SingleIdentityChosenEvent; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.Windows; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.control.Controller; +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.DTab; +import org.olat.core.gui.control.generic.dtabs.DTabs; +import org.olat.core.id.Identity; +import org.olat.core.id.OLATResourceable; +import org.olat.user.HomePageConfigManager; +import org.olat.user.HomePageConfigManagerImpl; +import org.olat.user.UserInfoMainController; + +/** + * Description:<br> + * This controller wrapps the usersearchcontroller. + * it catches the "singleIdentityChosenEvent" and displays a new OLAT-Tab with the users's info. + * + * (implemented for use in minimalHomeController) + * + * <P> + * Initial Date: 13.09.2011 <br> + * @author strentini, sergio.trentini@frentix.com, www.frentix.com + */ +public class UserSearchAndInfoController extends BasicController { + + + private UserSearchController userCtrl; + + public UserSearchAndInfoController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + userCtrl = new UserSearchController(ureq, wControl); + listenTo(userCtrl); + putInitialPanel(userCtrl.getInitialComponent()); + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if(source.equals(userCtrl)){ + if (event instanceof SingleIdentityChosenEvent) { + SingleIdentityChosenEvent foundEvent = (SingleIdentityChosenEvent) event; + Identity chosenIdentity = foundEvent.getChosenIdentity(); + if (chosenIdentity != null) { + HomePageConfigManager hpcm = HomePageConfigManagerImpl.getInstance(); + OLATResourceable ores = hpcm.loadConfigFor(chosenIdentity.getName()); + DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); + //was brasato:: DTabs dts = getWindowControl().getDTabs(); + DTab dt = dts.getDTab(ores); + if (dt == null) { + // does not yet exist -> create and add + dt = dts.createDTab(ores, null, chosenIdentity.getName()); + if (dt == null) return; + UserInfoMainController uimc = new UserInfoMainController(ureq, dt.getWindowControl(), chosenIdentity); + dt.setController(uimc); + dts.addDTab(dt); + } + dts.activate(ureq, dt, null); + } + } + } + } + + /** + * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) + */ + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // TODO Auto-generated method stub + + } + + /** + * @see org.olat.core.gui.control.DefaultController#doDispose() + */ + @Override + protected void doDispose() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/org/olat/home/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/home/_i18n/LocalStrings_de.properties index 664ea6974ac..00e6be2d6f1 100644 --- a/src/main/java/org/olat/home/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/home/_i18n/LocalStrings_de.properties @@ -64,8 +64,8 @@ menu.portfolio.mystructuredmaps=Meine Portfolioaufgaben menu.portfolio.mystructuredmaps.alt=Alle meine Sammelmappen aus einer Portfolioaufgabe anzeigen und verwalten menu.portfolio.othermaps=Freigegebene Sammelmappen menu.portfolio.othermaps.alt=Von anderen Benutzern für mich freigegebene Sammelmappen -menu.root=Home -menu.root.alt=Ihre Einstiegsseite in OLAT +main.menu.title=Home +main.menu.title.alt=Ihre Einstiegsseite in OLAT warn.session.was.killed=Sie hatten OLAT bereits in einem anderen Browser offen. Man kann sich in OLAT nicht gleichzeitig mehrmals einloggen. Ihre bisherige Sitzung wurde beendet. welcome.header=Willkommen bei OLAT welcome.intro=<\!-- --> diff --git a/src/main/java/org/olat/home/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/home/_i18n/LocalStrings_en.properties index c07d3733fec..bb6c7300888 100644 --- a/src/main/java/org/olat/home/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/home/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Wed Jan 19 19:20:57 CET 2011 +#Mon May 16 17:21:30 CEST 2011 chelp.firefox=Firefox plugin chelp.home-rss.title=RSS chelp.mac=MacOSX @@ -64,8 +64,8 @@ menu.portfolio.mystructuredmaps=My portfolio tasks menu.portfolio.mystructuredmaps.alt=Show and manage all my accumulative folders of portfolio tasks menu.portfolio.othermaps=Released accumulative folders menu.portfolio.othermaps.alt=Accumulative folders released for me by others -menu.root=Home -menu.root.alt=Your personal home page in OLAT +main.menu.title=Home +main.menu.title.alt=Your personal home page in OLAT warn.session.was.killed=You are using OLAT in another browser. You cannot log in several times at once. Your previous session has been terminated. welcome.header=Welcome to OLAT welcome.intro=<\!-- --> diff --git a/src/main/java/org/olat/home/_spring/homeContext.xml b/src/main/java/org/olat/home/_spring/homeContext.xml new file mode 100644 index 00000000000..42d34b7a8b7 --- /dev/null +++ b/src/main/java/org/olat/home/_spring/homeContext.xml @@ -0,0 +1,209 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> + + <!-- The Default Home-tab (navigation-tree) Setting --> + <!-- the "portal" (notifications + subscriptions + news ) --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="100" /> + <property name="enabled" value="${minimalhome.ext.portal}"></property> + <property name="navigationKey" value="portal" /> + <property name="actionController"> + <bean class="org.olat.home.controllerCreators.HomePortalControllerCreator" scope="prototype"/> + </property> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="main.menu.title"/> + <property name="i18nDescriptionKey" value="main.menu.title.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- personal-Settings --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="101" /> + <property name="enabled" value="${minimalhome.ext.mysettings}"></property> + <property name="navigationKey" value="mysettings" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.user.PersonalSettingsController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.mysettings"/> + <property name="i18nDescriptionKey" value="menu.mysettings"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the weekly calendar --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="102" /> + <property name="enabled" value="${minimalhome.ext.calendar}"></property> + <property name="navigationKey" value="calendar" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.home.HomeCalendarController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="i18nActionKey" value="menu.calendar"/> + <property name="i18nDescriptionKey" value="menu.calendar.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- notifications --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="103" /> + <property name="enabled" value="${minimalhome.ext.notifications}"></property> + <property name="navigationKey" value="notifications" /> + <property name="actionController"> + <bean class="org.olat.home.controllerCreators.NotificationsControllerCreator" scope="prototype"/> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.notifications"/> + <property name="i18nDescriptionKey" value="menu.notifications.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- bookmarks --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="104" /> + <property name="enabled" value="${minimalhome.ext.bookmarks}"></property> + <property name="navigationKey" value="bookmarks" /> + <property name="actionController"> + <bean class="org.olat.home.controllerCreators.ManageBookmarkControllerCreator" scope="prototype"/> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.bookmarks"/> + <property name="i18nDescriptionKey" value="menu.bookmarks.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the users personal folder --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="105" /> + <property name="enabled" value="${minimalhome.ext.userfolder}"></property> + <property name="navigationKey" value="userfolder" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.core.commons.modules.bc.FolderRunController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.bc"/> + <property name="i18nDescriptionKey" value="menu.bc.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + + <!-- the users notes ("Notizen") --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="106" /> + <property name="enabled" value="${minimalhome.ext.notelist}"></property> + <property name="navigationKey" value="notelist" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.note.NoteListController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.note"/> + <property name="i18nDescriptionKey" value="menu.note.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the users assessments ("Leistungsnachweise") --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="107" /> + <property name="enabled" value="${minimalhome.ext.efficiencystatement}"></property> + <property name="navigationKey" value="effstatements" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.course.assessment.EfficiencyStatementsListController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.efficiencyStatements"/> + <property name="i18nDescriptionKey" value="menu.efficiencyStatements.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the other users aka Usersearch --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="110" /> + <property name="enabled" value="${minimalhome.ext.otherusers}"/> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.home.UserSearchAndInfoController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.otherusers"/> + <property name="i18nDescriptionKey" value="menu.otherusers.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + + <!-- the info-message for guest-user --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.home.GuestHomeInfoController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.GuestOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.home" /> + <property name="i18nActionKey" value="menu.guestinfo"/> + <property name="i18nDescriptionKey" value="menu.guestinfo.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + +</beans> \ No newline at end of file diff --git a/src/main/java/org/olat/home/controllerCreators/GuestHomeCEControllerCreator.java b/src/main/java/org/olat/home/controllerCreators/GuestHomeCEControllerCreator.java new file mode 100644 index 00000000000..f67596aa1c4 --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/GuestHomeCEControllerCreator.java @@ -0,0 +1,61 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home.controllerCreators; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.ContextEntryControllerCreator; +import org.olat.home.HomeSite; + +/** + * + * Description:<br> + * Context entry creator for business path "../olat/url/guest/0?guest=true" + * + * <P> + * Initial Date: 15 juil. 2011 <br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class GuestHomeCEControllerCreator implements ContextEntryControllerCreator { + + public GuestHomeCEControllerCreator() { + + } + + public Controller createController(ContextEntry ce, UserRequest ureq, WindowControl wControl) { + return null; + } + + public String getSiteClassName(ContextEntry ce) { + return HomeSite.class.getName(); + } + + public String getTabName(ContextEntry ce) { + return null; + } + + @Override + public boolean validateContextEntryAndShowError(ContextEntry ce, UserRequest ureq, WindowControl wControl) { + return ureq.getUserSession().getRoles().isGuestOnly(); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/home/controllerCreators/HomePortalControllerCreator.java b/src/main/java/org/olat/home/controllerCreators/HomePortalControllerCreator.java new file mode 100644 index 00000000000..6fdf8ee12ba --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/HomePortalControllerCreator.java @@ -0,0 +1,137 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home.controllerCreators; + +import org.olat.commons.rss.RSSUtil; +import org.olat.core.CoreSpringFactory; +import org.olat.core.defaults.dispatcher.StaticMediaDispatcher; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.htmlheader.HtmlHeaderComponent; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; +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.creator.AutoCreator; +import org.olat.core.gui.control.generic.portal.PortalImpl; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.util.Util; +import org.olat.home.InviteeHomeMainController; + + +/** + * + * <h3>Description:</h3> + * Wrapper to create the notification in home + * with a panel for quick jump to other areas of Olat + * <p> + * Initial Date: 29 nov. 2010 <br> + * @author srosse, srosse@frentix.com, www.frentix.com + */ +public class HomePortalControllerCreator extends AutoCreator { + + /** + * @see org.olat.core.gui.control.creator.AutoCreator#getClassName() + */ + @Override + public String getClassName() { + return this.getClass().getCanonicalName(); + } + + public HomePortalControllerCreator() { + super(); + } + + /** + * @see org.olat.core.gui.control.creator.ControllerCreator#createController(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public Controller createController(UserRequest ureq, WindowControl lwControl) { + return new HomePortalController(ureq, lwControl); + } + + public class HomePortalController extends BasicController { + + private final VelocityContainer welcome; + private final Link portalBackButton; + private final Link portalEditButton; + private PortalImpl myPortal; + + public HomePortalController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl, Util.createPackageTranslator(InviteeHomeMainController.class, ureq.getLocale())); + // start screen + welcome = createVelocityContainer("welcome"); + portalBackButton = LinkFactory.createButtonXSmall("command.portal.back", welcome, this); + portalEditButton = LinkFactory.createButtonXSmall("command.portal.edit", welcome, this); + + if(CoreSpringFactory.containsBean("baksModule")){ + welcome.contextPut("isbaks", true); + }else{ + welcome.contextPut("isbaks", false); + } + + // rss link + String rssLink = RSSUtil.getPersonalRssLink(ureq); + welcome.contextPut("rssLink", rssLink); + StringOutput staticUrl = new StringOutput(); + StaticMediaDispatcher.renderStaticURI(staticUrl, "js/egg.js"); + welcome.put("htmlHeader", new HtmlHeaderComponent("rss", null, "<link rel=\"alternate\" type=\"application/rss+xml\" title=\"" + + translate("welcome.rss") + "\" href=\"" + rssLink + "\" />\n" + "<script type=\"text/javascript\" src=\"" + + staticUrl.toString() + "\"></script>")); + + // add portal + if (myPortal == null) { + if(ureq.getUserSession().getRoles().isGuestOnly()){ + myPortal = ((PortalImpl)CoreSpringFactory.getBean("guestportal")).createInstance(getWindowControl(), ureq); + portalEditButton.setEnabled(false); + portalEditButton.setVisible(false); + }else{ + myPortal = ((PortalImpl)CoreSpringFactory.getBean("homeportal")).createInstance(getWindowControl(), ureq); + } + } + + welcome.put("myPortal", myPortal.getInitialComponent()); + welcome.contextPut("portalEditMode", Boolean.FALSE); + + putInitialPanel(welcome); + } + + @Override + protected void doDispose() { + // + } + + @Override + public void event(UserRequest ureq, Component source, Event event) { + if (source == portalBackButton){ + this.myPortal.setIsEditMode(ureq, Boolean.FALSE); + welcome.contextPut("portalEditMode", Boolean.FALSE); + } else if (source == portalEditButton){ + this.myPortal.setIsEditMode(ureq, Boolean.TRUE); + welcome.contextPut("portalEditMode", Boolean.TRUE); + } + } + } +} diff --git a/src/main/java/org/olat/home/controllerCreators/ManageBookmarkControllerCreator.java b/src/main/java/org/olat/home/controllerCreators/ManageBookmarkControllerCreator.java new file mode 100644 index 00000000000..0d16b374073 --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/ManageBookmarkControllerCreator.java @@ -0,0 +1,60 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home.controllerCreators; + +import org.olat.bookmark.ManageBookmarkController; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.creator.AutoCreator; + +/** + * + * <h3>Description:</h3> + * Wrapper to create the bookmarks in home + * <p> + * Initial Date: 29 nov. 2010 <br> + * @author srosse, srosse@frentix.com, www.frentix.com + */ +public class ManageBookmarkControllerCreator extends AutoCreator { + + /** + * @see org.olat.core.gui.control.creator.AutoCreator#getClassName() + */ + @Override + public String getClassName() { + return this.getClass().getCanonicalName(); + } + + public ManageBookmarkControllerCreator() { + super(); + } + + /** + * @see org.olat.core.gui.control.creator.ControllerCreator#createController(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public Controller createController(UserRequest ureq, WindowControl lwControl) { + return new ManageBookmarkController(ureq, lwControl, true, ManageBookmarkController.SEARCH_TYPE_ALL); + } + +} diff --git a/src/main/java/org/olat/home/controllerCreators/NotificationsControllerCreator.java b/src/main/java/org/olat/home/controllerCreators/NotificationsControllerCreator.java new file mode 100644 index 00000000000..5170934b408 --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/NotificationsControllerCreator.java @@ -0,0 +1,60 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home.controllerCreators; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.creator.AutoCreator; +import org.olat.notifications.NotificationUIFactory; + +/** + * wrapper to create a notificationcontroller with the uifactory. + * usable with default arguments (by config in minimalHome). + * + * Initial Date: 10.06.2010 <br> + * + * @author Roman Haag, roman.haag@frentix.com, www.frentix.com + */ +public class NotificationsControllerCreator extends AutoCreator { + + /** + * @see org.olat.core.gui.control.creator.AutoCreator#getClassName() + */ + @Override + public String getClassName() { + return this.getClass().getCanonicalName(); + } + + public NotificationsControllerCreator() { + super(); + } + + /** + * @see org.olat.core.gui.control.creator.ControllerCreator#createController(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public Controller createController(UserRequest ureq, WindowControl lwControl) { + return NotificationUIFactory.createCombinedSubscriptionsAndNewsController(ureq.getIdentity(), ureq, lwControl); + } + +} diff --git a/src/main/java/org/olat/home/controllerCreators/PersonalFolderControllerCreator.java b/src/main/java/org/olat/home/controllerCreators/PersonalFolderControllerCreator.java new file mode 100644 index 00000000000..e84e09ab092 --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/PersonalFolderControllerCreator.java @@ -0,0 +1,60 @@ +/** + * OLAT - Online Learning and Training<br> + * http://www.olat.org + * <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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <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> + * Copyright (c) frentix GmbH<br> + * http://www.frentix.com<br> + * <p> + */ +package org.olat.home.controllerCreators; + +import org.olat.core.commons.modules.bc.FolderRunController; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.creator.AutoCreator; +import org.olat.user.PersonalFolderManager; + +/** + * + * <h3>Description:</h3> + * Wrapper to create the personal folder in home + * <p> + * Initial Date: 29 nov. 2010 <br> + * @author srosse, srosse@frentix.com, www.frentix.com + */ +public class PersonalFolderControllerCreator extends AutoCreator { + + /** + * @see org.olat.core.gui.control.creator.AutoCreator#getClassName() + */ + @Override + public String getClassName() { + return this.getClass().getCanonicalName(); + } + + public PersonalFolderControllerCreator() { + super(); + } + + /** + * @see org.olat.core.gui.control.creator.ControllerCreator#createController(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.WindowControl) + */ + @Override + public Controller createController(UserRequest ureq, WindowControl lwControl) { + return new FolderRunController(PersonalFolderManager.getInstance().getContainer(ureq.getIdentity()), true, true, ureq, lwControl); + } +} diff --git a/src/main/java/org/olat/home/controllerCreators/_content/welcome.html b/src/main/java/org/olat/home/controllerCreators/_content/welcome.html new file mode 100644 index 00000000000..a23a5df2366 --- /dev/null +++ b/src/main/java/org/olat/home/controllerCreators/_content/welcome.html @@ -0,0 +1,96 @@ +<div class="o_home_portaleditlink"> +#if ($portalEditMode) + $r.render("command.portal.back") +#else + $r.render("command.portal.edit") +#end +</div> +<div class="o_home_main"> + <h4>$r.translate("welcome.header")</h4> + #set ($intro = $r.translate("welcome.intro")) + #if ($intro != "") + $intro <br><br> + #end +</div> + +#if($isbaks) +<div id="baks_home_launcher"> + <img src="$r.staticLink("themes/baks/images/portal_launcher_bg.png")" onclick="gotoSite(event);"/> + <div id="baks_goto_repository" class="baks_goto_wrapper" onclick="gotoSite(event);"><a href="#" onclick="gotoSite(event);">Meine Veranstaltungen</a></div> + <div id="baks_goto_members" class="baks_goto_wrapper" onclick="gotoSite(event);"><a href="#" onclick="gotoSite(event);">Mitglieder</a></div> + <div id="baks_goto_library" class="baks_goto_wrapper" onclick="gotoSite(event);"><a href="#" onclick="gotoSite(event);">Bibliothek</a></div> + <div id="baks_goto_friends" class="baks_goto_wrapper" onclick="gotoSite(event);"><a href="#" onclick="gotoSite(event);">Freundeskreis</a></div> + <div id="baks_goto_network" class="baks_goto_wrapper" onclick="gotoSite(event);"><a href="#" onclick="gotoSite(event);">Netzwerk</a></div> +</div> + +<script type="text/javascript"> +/* <![CDATA[ */ +function gotoSite(event) { + var el = $("baks_home_launcher"); + var dim = Element.getDimensions(el); + var pos = Element.positionedOffset(el); + var offsetLeft = pos.left; + var offsetTop = pos.top; + + var i=0; + for(var offsetParent = Element.getOffsetParent(el); offsetParent.id != 'b_body'; offsetParent = Element.getOffsetParent(offsetParent)) { + var posn = Element.positionedOffset(offsetParent); + if(offsetParent.id != "b_col3" && offsetParent.id != "b_page") {//ie give it an offset which is the same as _content + offsetLeft += posn.left; + offsetTop += posn.top; + } + if(i++==10) { break; }//security + } + + //inner square is difficult + var centerX = dim.width / 2; + var centerY = dim.height / 2; + //shift 0,0 coordinate to center + var px = Event.pointerX(event) - offsetLeft - centerX; + var py = centerY - (Event.pointerY(event) - offsetTop); + //calculate the x position on the line x = -y + centerY; + var theoy = (centerY - 5) - Math.abs(px); + if(Math.abs(py) < theoy) { + launchSite('site_demo_icon'); + } + else if(px > 0 && py < 0) { + launchSite('baks_friends'); + } + else if(px > 0 && py > 0) { + launchSite('fx_members'); + } + else if(px < 0 && py > 0) { + launchSite('o_site_repository'); + } + else { + launchSite('f_site_library'); + } +} + +function launchSite(site) { + var siteLinks = $$('li.' + site + ' a'); + if (siteLinks && siteLinks.length > 0) { + var siteLink = siteLinks[0]; + if (o2cl()) { + var target = siteLink.target; + if (target == 'oaa0') { + $('oaa0').src=siteLink.href; + } else { + document.location.href=siteLink.href; + } + } + } else { + alert("Diese Funktion ist noch nicht vorhanden"); + } +} +/* ]]> */ +</script> + +#end ##end of baks-check + +$r.render("myPortal") + +<div class="o_home_rsslink"> + $r.contextHelp("org.olat.home","home-rss.html","help.hover.rss") + <a class="o_home_rsslink" href="$rssLink" title="$r.translate("welcome.rss")" target="_blank"></a> +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/home/site/HomeSite.java b/src/main/java/org/olat/home/site/HomeSite.java deleted file mode 100644 index 2a40f348f33..00000000000 --- a/src/main/java/org/olat/home/site/HomeSite.java +++ /dev/null @@ -1,90 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <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 -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <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> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <p> -*/ - -package org.olat.home.site; - -import java.util.Locale; - -import org.olat.ControllerFactory; -import org.olat.core.commons.chiefcontrollers.BaseChiefController; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.generic.layout.MainLayoutController; -import org.olat.core.gui.control.navigation.DefaultNavElement; -import org.olat.core.gui.control.navigation.NavElement; -import org.olat.core.gui.control.navigation.SiteInstance; -import org.olat.core.gui.translator.PackageTranslator; -import org.olat.core.gui.translator.Translator; -import org.olat.core.id.OLATResourceable; -import org.olat.core.util.Util; -import org.olat.core.util.resource.OresHelper; -import org.olat.home.HomeMainController; -/** - * Initial Date: 19.07.2005 <br> - * - * @author Felix Jost - */ -public class HomeSite implements SiteInstance { - private static final OLATResourceable ORES_AUTHUSER = OresHelper.lookupType(HomeMainController.class); - - // refer to the definitions in org.olat - private static final String PACKAGE = Util.getPackageName(BaseChiefController.class); - - private NavElement origNavElem; - private NavElement curNavElem; - /** - * - */ - public HomeSite(Locale loc) { - Translator trans = new PackageTranslator(PACKAGE, loc); - origNavElem = new DefaultNavElement(trans.translate("topnav.home"), trans.translate("topnav.home.alt"), "o_site_home"); - origNavElem.setAccessKey("h".charAt(0)); - curNavElem = new DefaultNavElement(origNavElem); -} - - /** - * @see org.olat.navigation.SiteInstance#getNavElement() - */ - public NavElement getNavElement() { - return curNavElem; - } - - /** - * @see org.olat.navigation.SiteInstance#createController(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) - */ - public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { - MainLayoutController c = ControllerFactory.createLaunchController(ORES_AUTHUSER, null, ureq, wControl, true); - return c; - } - - /** - * @see org.olat.navigation.SiteInstance#isKeepState() - */ - public boolean isKeepState() { - return true; - } - - public void reset() { - curNavElem = new DefaultNavElement(origNavElem); - } - -} - diff --git a/src/main/java/org/olat/home/site/HomeSiteDef.java b/src/main/java/org/olat/home/site/HomeSiteDef.java deleted file mode 100644 index 0ebbbf588c5..00000000000 --- a/src/main/java/org/olat/home/site/HomeSiteDef.java +++ /dev/null @@ -1,95 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <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 -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <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> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <p> -*/ - -package org.olat.home.site; - -import java.util.List; - -import org.olat.core.extensions.ExtensionResource; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.navigation.AbstractSiteDefinition; -import org.olat.core.gui.control.navigation.SiteDefinition; -import org.olat.core.gui.control.navigation.SiteInstance; -import org.olat.core.logging.AssertException; -import org.olat.home.GuestHomeSite; -import org.olat.home.InviteeHomeSite; - -/** - * Initial Date: 12.07.2005 <br> - * - * @author Felix Jost - */ -public class HomeSiteDef extends AbstractSiteDefinition implements SiteDefinition { - - /** - * - */ - public HomeSiteDef() { - super(); - } - - /** - * @see org.olat.core.extensions.OLATExtension#getName() - */ - public String getName() { - return "homesite"; - } - - - - /** - * @see org.olat.core.extensions.OLATExtension#getExtensionResources() - */ - public List getExtensionResources() { - // no ressources, part of main css - return null; - } - - /** - * @see org.olat.core.extensions.OLATExtension#getExtensionCSS() - */ - public ExtensionResource getExtensionCSS() { - // no ressources, part of main css - return null; - } - - /** - * @see org.olat.navigation.SiteDefinition#createSite(org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) - */ - public SiteInstance createSite(UserRequest ureq, WindowControl wControl) { - SiteInstance si = null; - if (ureq == null) throw new AssertException("HomeSiteDef.createSite: ureq was null"); - if (ureq.getUserSession() == null) throw new AssertException("HomeSiteDef.createSite: ureq.getUserSession() was null"); - if (ureq.getUserSession().getRoles() == null) throw new AssertException("HomeSiteDef.createSite: ureq.getUserSession().getRoles() was null"); - if (ureq.getUserSession().getRoles().isGuestOnly()) { - // guest see this site (restricted rights and navigation) - si = new GuestHomeSite(ureq.getLocale()); - } else if(ureq.getUserSession().getRoles().isInvitee()) { - si = new InviteeHomeSite(ureq.getLocale());//no home for invitee - } else { // all others see a normal homesite - si = new HomeSite(ureq.getLocale()); - } - return si; - } - -} - diff --git a/src/main/java/org/olat/ldap/ui/LDAPAdminExtension.java b/src/main/java/org/olat/ldap/ui/LDAPAdminExtension.java index 808a7de76ec..1205181ae9b 100644 --- a/src/main/java/org/olat/ldap/ui/LDAPAdminExtension.java +++ b/src/main/java/org/olat/ldap/ui/LDAPAdminExtension.java @@ -27,7 +27,7 @@ import org.olat.admin.SystemAdminMainController; import org.olat.core.extensions.AbstractExtension; import org.olat.core.extensions.Extension; import org.olat.core.extensions.ExtensionElement; -import org.olat.core.extensions.action.ActionExtension; +import org.olat.core.extensions.action.GenericActionExtension; import org.olat.core.extensions.helpers.ExtensionElements; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; @@ -60,7 +60,7 @@ public class LDAPAdminExtension extends AbstractExtension implements Extension { * Constructor to create an extension that registers in the admin site */ public LDAPAdminExtension() { - elements.putExtensionElement(SystemAdminMainController.class.getName(), new ActionExtension() { + elements.putExtensionElement(SystemAdminMainController.class.getName(), new GenericActionExtension() { /** * @see org.olat.core.extensions.action.ActionExtension#getActionText(java.util.Locale) diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java index 2f18a3fe16c..d0d7158ad38 100644 --- a/src/main/java/org/olat/login/OLATAuthenticationController.java +++ b/src/main/java/org/olat/login/OLATAuthenticationController.java @@ -37,7 +37,11 @@ import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.Identity; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATSecurityException; import org.olat.core.logging.Tracing; import org.olat.core.util.Encoder; @@ -64,7 +68,7 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle * * @author Mike Stock */ -public class OLATAuthenticationController extends AuthenticationController { +public class OLATAuthenticationController extends AuthenticationController implements Activateable2 { public static final String PARAM_LOGINERROR = "loginerror"; @@ -228,6 +232,12 @@ public class OLATAuthenticationController extends AuthenticationController { } } + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + } + /** * @param login * @param pass diff --git a/src/main/java/org/olat/modules/cp/CPDisplayController.java b/src/main/java/org/olat/modules/cp/CPDisplayController.java index c4cb738712a..155ceda539a 100644 --- a/src/main/java/org/olat/modules/cp/CPDisplayController.java +++ b/src/main/java/org/olat/modules/cp/CPDisplayController.java @@ -22,6 +22,8 @@ package org.olat.modules.cp; +import java.util.List; + import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.search.ui.SearchServiceUIFactory; import org.olat.core.commons.services.search.ui.SearchServiceUIFactory.DisplayOption; @@ -37,11 +39,15 @@ import org.olat.core.gui.control.Controller; 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.iframe.IFrameDisplayController; import org.olat.core.gui.control.generic.iframe.NewIframeUriEvent; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.NotFoundMediaResource; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.activity.CourseLoggingAction; @@ -63,7 +69,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * * @author Felix Jost */ -public class CPDisplayController extends BasicController { +public class CPDisplayController extends BasicController implements Activateable2 { private static final String FILE_SUFFIX_HTM = "htm"; private static final String FILE_SUFFIX_XML = "xml"; @@ -149,6 +155,13 @@ public class CPDisplayController extends BasicController { selNodeId = node.getIdent(); nodeInfo = LoggingResourceable.wrapCpNode(nodeUri); + //fxdiff BAKS-7 Resume function + if(node.getUserObject() != null) { + String identifierRes = (String)node.getUserObject(); + Long id = Long.parseLong(node.getIdent()); + OLATResourceable pOres = OresHelper.createOLATResourceableInstanceWithoutCheck("path=" + identifierRes, id); + addToHistory(ureq, pOres, null); + } } } else if (initialUri != null) { // set page @@ -163,6 +176,13 @@ public class CPDisplayController extends BasicController { } else { selNodeId = newNode.getIdent(); } + //fxdiff BAKS-7 Resume function + if(newNode.getUserObject() != null) { + String identifierRes = (String)newNode.getUserObject(); + Long id = Long.parseLong(newNode.getIdent()); + OLATResourceable pOres = OresHelper.createOLATResourceableInstanceWithoutCheck("path=" + identifierRes, id); + addToHistory(ureq, pOres, null); + } } nodeInfo = LoggingResourceable.wrapCpNode(initialUri); } @@ -235,6 +255,26 @@ public class CPDisplayController extends BasicController { // contentpackaging file) } } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + Long id = entries.get(0).getOLATResourceable().getResourceableId(); + TreeNode newNode = null; + if(id != null && id.longValue() > 0l) { + newNode = ctm.getNodeById(id.toString()); + } + if(newNode == null) { + String path = BusinessControlFactory.getInstance().getPath(entries.get(0)); + newNode = ctm.lookupTreeNodeByHref(path); + } + if(newNode != null) { + selectTreeNode(ureq, newNode); + switchToPage(ureq, new TreeEvent(TreeEvent.COMMAND_TREENODES_SELECTED, newNode.getIdent())); + } + } /** * adjust the cp menu tree with the page selected with a link clicked in the content @@ -243,6 +283,12 @@ public class CPDisplayController extends BasicController { */ public void selectTreeNode(UserRequest ureq, String newUri) { TreeNode newNode = ctm.lookupTreeNodeByHref(newUri); + selectTreeNode(ureq, newNode); + ThreadLocalUserActivityLogger.log(CourseLoggingAction.CP_GET_FILE, getClass(), LoggingResourceable.wrapCpNode(newUri)); + } + + //fxdiff VCRP-13: cp navigation + public void selectTreeNode(UserRequest ureq, TreeNode newNode) { if (newNode != null) { // user clicked on a link which is listed in the // toc if (cpTree != null) { @@ -253,7 +299,6 @@ public class CPDisplayController extends BasicController { fireEvent(ureq, new TreeNodeEvent(newNode)); } } - ThreadLocalUserActivityLogger.log(CourseLoggingAction.CP_GET_FILE, getClass(), LoggingResourceable.wrapCpNode(newUri)); } /** @@ -269,6 +314,10 @@ public class CPDisplayController extends BasicController { String nodeId = te.getNodeId(); TreeNode tn = ctm.getNodeById(nodeId); String identifierRes = (String) tn.getUserObject(); + //fxdiff BAKS-7 Resume function + Long id = Long.parseLong(tn.getIdent()); + OLATResourceable ores = OresHelper.createOLATResourceableInstanceWithoutCheck("path=" + identifierRes, id); + addToHistory(ureq, ores, null); // security check if (identifierRes.indexOf("../") != -1) throw new AssertException("a non-normalized url encountered in a manifest item:" diff --git a/src/main/java/org/olat/modules/cp/CPUIFactory.java b/src/main/java/org/olat/modules/cp/CPUIFactory.java index 340a3eb63ea..af701302066 100644 --- a/src/main/java/org/olat/modules/cp/CPUIFactory.java +++ b/src/main/java/org/olat/modules/cp/CPUIFactory.java @@ -155,8 +155,11 @@ public class CPUIFactory { * @return the resource listening wrapper */ public OLATResourceableListeningWrapperController createMainLayoutResourceableListeningWrapperController(OLATResourceable res, UserRequest ureq, WindowControl wControl, VFSContainer rootContainer, boolean showMenu, boolean activateFirstPage, String initialUri) { - MainLayout3ColumnsController layoutCtr = createMainLayoutController(ureq, wControl, rootContainer, showMenu, activateFirstPage, initialUri, res); - return new OLATResourceableListeningWrapperController(ureq, wControl, res, layoutCtr, ureq.getIdentity()); + //fxdiff BAKS-7 Resume function + CPDisplayController cpCtr = new CPDisplayController(ureq, wControl, rootContainer, showMenu, activateFirstPage, initialUri, res); + MainLayout3ColumnsController layoutCtr = new LayoutMain3ColsController(ureq, wControl, cpCtr.getMenuComponent(), null, cpCtr.getInitialComponent(), rootContainer.getName()); + layoutCtr.addDisposableChildController(cpCtr); + return new OLATResourceableListeningWrapperController(ureq, wControl, res, layoutCtr, cpCtr, ureq.getIdentity()); } diff --git a/src/main/java/org/olat/modules/fo/ForumController.java b/src/main/java/org/olat/modules/fo/ForumController.java index f13424a54cf..537a7a45563 100644 --- a/src/main/java/org/olat/modules/fo/ForumController.java +++ b/src/main/java/org/olat/modules/fo/ForumController.java @@ -69,6 +69,7 @@ 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.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.id.Identity; @@ -78,6 +79,7 @@ import org.olat.core.id.UserConstants; import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATSecurityException; import org.olat.core.logging.activity.ILoggingAction; @@ -123,7 +125,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * @author Felix Jost * @author Refactorings: Roman Haag, roman.haag@frentix.com, frentix GmbH */ -public class ForumController extends BasicController implements GenericEventListener { +public class ForumController extends BasicController implements GenericEventListener, Activateable2 { protected static final String TINYMCE_EMPTYLINE_CODE = "<p> </p>"; //is pre/appended to quote message to allow writing inside. @@ -319,6 +321,20 @@ public class ForumController extends BasicController implements GenericEventList vcFilterView = createVelocityContainer("filter_view"); } + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + Long resId = entries.get(0).getOLATResourceable().getResourceableId(); + if (resId.longValue() != 0) { + currentMsg = fm.findMessage(resId); + if (currentMsg != null) { + showThreadView(ureq, currentMsg, null); + scrollToCurrentMessage(); + } + } + } + /** * If event received, must update thread overview. */ @@ -1330,9 +1346,8 @@ public class ForumController extends BasicController implements GenericEventList private void adjustBusinessControlPath(UserRequest ureq, Message m) { ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrap(m)); OLATResourceable ores = OresHelper.createOLATResourceableInstance(Message.class,m.getKey()); - ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(ores); - - WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, getWindowControl()); + //fxdiff BAKS-7 Resume function + WindowControl bwControl = addToHistory(ureq, ores, null); //Simple way to "register" the new ContextEntry although only a VelocityPage was flipped. Controller dummy = new BasicController(ureq, bwControl) { diff --git a/src/main/java/org/olat/modules/fo/ForumManager.java b/src/main/java/org/olat/modules/fo/ForumManager.java index 348a159bc88..e29af48d4e3 100644 --- a/src/main/java/org/olat/modules/fo/ForumManager.java +++ b/src/main/java/org/olat/modules/fo/ForumManager.java @@ -127,7 +127,7 @@ public class ForumManager extends BasicManager { List<Long> tmpRes = DBFactory.getInstance().find("select key from org.olat.modules.fo.ForumImpl"); return tmpRes; } - + /** * * @param forum_id @@ -155,7 +155,8 @@ public class ForumManager extends BasicManager { * @param forum * @return */ - public List<Message> getMessagesByForum(Forum forum){ + public List<Message> getMessagesByForum(Forum forum){ + if (forum == null) return new ArrayList<Message>(0); // fxdiff: while indexing it can somehow occur, that forum is null! return getMessagesByForumID(forum.getKey(), 0, -1, null, true); } diff --git a/src/main/java/org/olat/modules/iq/IQDisplayController.java b/src/main/java/org/olat/modules/iq/IQDisplayController.java index 2fd3039a47f..ae6ebf9aa61 100644 --- a/src/main/java/org/olat/modules/iq/IQDisplayController.java +++ b/src/main/java/org/olat/modules/iq/IQDisplayController.java @@ -23,6 +23,7 @@ package org.olat.modules.iq; import java.io.File; import java.util.Iterator; +import java.util.List; import java.util.Set; import org.apache.log4j.Logger; @@ -37,17 +38,24 @@ import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.DefaultController; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.activity.LearningResourceLoggingAction; import org.olat.core.logging.activity.StringResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; +import org.olat.core.util.resource.OresHelper; import org.olat.course.nodes.iq.IQEditController; import org.olat.ims.qti.QTIConstants; import org.olat.ims.qti.container.AssessmentContext; +import org.olat.ims.qti.container.ItemsInput; +import org.olat.ims.qti.container.SectionContext; import org.olat.ims.qti.navigator.Navigator; import org.olat.ims.qti.process.AssessmentFactory; import org.olat.ims.qti.process.AssessmentInstance; @@ -63,7 +71,7 @@ import org.olat.util.logging.activity.LoggingResourceable; /** * @author Felix Jost */ -public class IQDisplayController extends DefaultController { +public class IQDisplayController extends DefaultController implements Activateable2 { private static final String PACKAGE = Util.getPackageName(IQDisplayController.class); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(IQDisplayController.class); @@ -296,6 +304,22 @@ public class IQDisplayController extends DefaultController { if (!ai.isResuming()) { Navigator navigator = ai.getNavigator(); navigator.startAssessment(); + } else { + //fxdiff BAKS-7 Resume function + AssessmentContext act = ai.getAssessmentContext(); + if (act.getCurrentSectionContextPos() >= 0) { + int sectionPos = act.getCurrentSectionContextPos(); + OLATResourceable sres = OresHelper.createOLATResourceableInstance("gse", new Long(sectionPos)); + WindowControl bwControl = addToHistory(ureq, sres, null, getWindowControl(), false); + if(!ai.isSectionPage()) { + SectionContext sct = act.getCurrentSectionContext(); + int itemPos = sct.getCurrentItemContextPos(); + if(itemPos >= 0) { + OLATResourceable ires = OresHelper.createOLATResourceableInstance("git", new Long(itemPos)); + addToHistory(ureq, ires, null, bwControl, true); + } + } + } } qtistatus.update(ai); @@ -334,6 +358,13 @@ public class IQDisplayController extends DefaultController { ); } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + } + /** * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, * org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) @@ -363,7 +394,10 @@ public class IQDisplayController extends DefaultController { logAudit(ureq); if (wfCommand.equals("sitse")) { // submitItemorSection - navig.submitItems(iqm.getItemsInput(ureq)); // + ItemsInput iInp = iqm.getItemsInput(ureq); + if(iInp.getItemCount() > 0) { + navig.submitItems(iInp); + } if (ai.isClosed()) { // do all the finishing stuff event(ureq, source, new Event(QTIConstants.QTI_WF_SUBMIT)); return; @@ -381,12 +415,22 @@ public class IQDisplayController extends DefaultController { int sectionPos = Integer.parseInt(seid); int itemPos = Integer.parseInt(itid); navig.goToItem(sectionPos, itemPos); + + //fxdiff BAKS-7 Resume function + OLATResourceable sres = OresHelper.createOLATResourceableInstance("gse", new Long(sectionPos)); + WindowControl bwControl = addToHistory(ureq, sres, null, getWindowControl(), false); + OLATResourceable ires = OresHelper.createOLATResourceableInstance("git", new Long(itemPos)); + addToHistory(ureq, ires, null, bwControl, true); } } else if (wfCommand.equals("gse")) { // goToSection String seid = ureq.getParameter("seid"); if (seid!=null && seid.length()!=0) { int sectionPos = Integer.parseInt(seid); navig.goToSection(sectionPos); + + //fxdiff BAKS-7 Resume function + OLATResourceable sres = OresHelper.createOLATResourceableInstance("gse", new Long(sectionPos)); + addToHistory(ureq, sres, null); } } else if (wfCommand.equals(QTIConstants.QTI_WF_SUBMIT)) { // submit // Assessment diff --git a/src/main/java/org/olat/modules/iq/IQManager.java b/src/main/java/org/olat/modules/iq/IQManager.java index a74df678c1a..d87355c109b 100644 --- a/src/main/java/org/olat/modules/iq/IQManager.java +++ b/src/main/java/org/olat/modules/iq/IQManager.java @@ -181,7 +181,8 @@ public class IQManager extends BasicManager implements UserDataDeletable { return glc; }else{ Controller controller = new IQDisplayController(resolver, type, secCallback, ureq, wControl); - OLATResourceableListeningWrapperController dwc = new OLATResourceableListeningWrapperController(ureq, wControl, res, controller, ureq.getIdentity()); + //fxdiff BAKS-7 Resume function + OLATResourceableListeningWrapperController dwc = new OLATResourceableListeningWrapperController(ureq, wControl, res, controller, null, ureq.getIdentity()); return dwc; } } diff --git a/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java b/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java index afee13ffc27..a41c05c0382 100644 --- a/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java +++ b/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java @@ -89,7 +89,7 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController { private String scorm_lesson_mode; private VelocityContainer myContent; private MenuTree menuTree; - private Controller columnLayoutCtr; + private Controller columnLayoutCtr; private ScormCPManifestTreeModel treeModel; private IFrameDisplayController iframectr; private OLATApiAdapter scormAdapter; diff --git a/src/main/java/org/olat/modules/wiki/WikiMainController.java b/src/main/java/org/olat/modules/wiki/WikiMainController.java index 70fbbce0d9e..96fdad6c3cb 100644 --- a/src/main/java/org/olat/modules/wiki/WikiMainController.java +++ b/src/main/java/org/olat/modules/wiki/WikiMainController.java @@ -56,12 +56,14 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.clone.CloneableController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; @@ -85,6 +87,7 @@ import org.olat.modules.fo.ForumCallback; import org.olat.modules.fo.ForumManager; import org.olat.modules.fo.ForumUIFactory; import org.olat.modules.wiki.gui.components.wikiToHtml.ErrorEvent; +import org.olat.modules.wiki.gui.components.wikiToHtml.FilterUtil; import org.olat.modules.wiki.gui.components.wikiToHtml.RequestImageEvent; import org.olat.modules.wiki.gui.components.wikiToHtml.RequestMediaEvent; import org.olat.modules.wiki.gui.components.wikiToHtml.RequestNewPageEvent; @@ -106,7 +109,7 @@ import org.olat.util.logging.activity.LoggingResourceable; * * @author guido */ -public class WikiMainController extends BasicController implements CloneableController { +public class WikiMainController extends BasicController implements CloneableController, Activateable2 { OLog log = Tracing.createLoggerFor(this.getClass()); @@ -313,6 +316,22 @@ public class WikiMainController extends BasicController implements CloneableCont this.pageId = page.getPageId(); } + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + String path = BusinessControlFactory.getInstance().getPath(entries.get(0)); + Wiki wiki = getWiki(); + String activatePageId = WikiManager.generatePageId(FilterUtil.normalizeWikiLink(path)); + if(wiki.pageExists(activatePageId)) { + WikiPage page = wiki.getPage(activatePageId, true); + if(page != null) { + this.pageId = page.getPageId(); + } + updatePageContext(ureq, page); + } + } public void event(UserRequest ureq, Component source, Event event) { @@ -905,6 +924,9 @@ public class WikiMainController extends BasicController implements CloneableCont } else { clearPortfolioLink(); } + //fxdiff BAKS-7, FXOLAT-160 Resume function + OLATResourceable pageRes = OresHelper.createOLATResourceableInstanceWithoutCheck("path=" + page.getPageName(), 0l); + addToHistory(ureq, pageRes, null); } private void clearPortfolioLink(){ diff --git a/src/main/java/org/olat/modules/wiki/WikiManager.java b/src/main/java/org/olat/modules/wiki/WikiManager.java index c9b35469d48..0ac7e50d43f 100644 --- a/src/main/java/org/olat/modules/wiki/WikiManager.java +++ b/src/main/java/org/olat/modules/wiki/WikiManager.java @@ -134,7 +134,8 @@ public class WikiManager extends BasicManager { */ public Controller createWikiMainControllerDisposeOnOres(UserRequest ureq, WindowControl wControl, OLATResourceable ores, WikiSecurityCallback securityCallback, String initialPageName) { Controller controller = new WikiMainController(ureq, wControl, ores, securityCallback, initialPageName); - OLATResourceableListeningWrapperController dwc = new OLATResourceableListeningWrapperController(ureq, wControl, ores, controller, ureq.getIdentity()); + //fxdiff BAKS-7 Resume function + OLATResourceableListeningWrapperController dwc = new OLATResourceableListeningWrapperController(ureq, wControl, ores, controller, null, ureq.getIdentity()); return dwc; } diff --git a/src/main/java/org/olat/note/NotesPortletRunController.java b/src/main/java/org/olat/note/NotesPortletRunController.java index 27dbc477da2..c5f3eaa1d73 100644 --- a/src/main/java/org/olat/note/NotesPortletRunController.java +++ b/src/main/java/org/olat/note/NotesPortletRunController.java @@ -30,10 +30,10 @@ import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; import org.olat.ControllerFactory; +import org.olat.NewControllerFactory; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.Windows; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; @@ -48,7 +48,6 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.creator.ControllerCreator; -import org.olat.core.gui.control.generic.dtabs.DTabs; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; import org.olat.core.gui.control.generic.portal.AbstractPortletRunController; import org.olat.core.gui.control.generic.portal.PortletDefaultTableDataModel; @@ -58,10 +57,11 @@ import org.olat.core.gui.control.generic.portal.SortingCriteria; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OresHelper; -import org.olat.home.site.HomeSite; /** * Description:<br> @@ -194,12 +194,13 @@ public class NotesPortletRunController extends AbstractPortletRunController impl * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) */ public void event(UserRequest ureq, Component source, Event event) { - if (source == showAllLink){ - // activate homes tab in top navigation and active notes menu item - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - //was brasato:: getWindowControl().getDTabs().activateStatic(ureq, HomeSite.class.getName(), "note"); - dts.activateStatic(ureq, HomeSite.class.getName(), "note"); - } + if (source == showAllLink) { + // fxdiff: activate homes tab in top navigation and activate correct menu item + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][notelist:0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); + } } /** diff --git a/src/main/java/org/olat/notifications/NotificationNewsController.java b/src/main/java/org/olat/notifications/NotificationNewsController.java index 1ce4b04195b..2374f5a8ae7 100644 --- a/src/main/java/org/olat/notifications/NotificationNewsController.java +++ b/src/main/java/org/olat/notifications/NotificationNewsController.java @@ -40,7 +40,10 @@ 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.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.Identity; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.util.StringHelper; import org.olat.core.util.notifications.NotificationHelper; import org.olat.core.util.notifications.NotificationsManager; @@ -60,7 +63,7 @@ import org.olat.core.util.notifications.SubscriptionItem; * * @author gnaegi */ -class NotificationNewsController extends BasicController implements Activateable { +class NotificationNewsController extends BasicController implements Activateable, Activateable2 { private VelocityContainer newsVC; private Date compareDate; private String newsType; @@ -185,7 +188,7 @@ class NotificationNewsController extends BasicController implements Activateable dateChooserCtr.setDate(compareDate); changed = true; } catch (ParseException e) { - e.printStackTrace(); + logWarn("Error parsing the date after activate: " + token, e); } } } @@ -195,7 +198,39 @@ class NotificationNewsController extends BasicController implements Activateable } } - + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + boolean changed = false; + String path = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if(path.startsWith("type=")) { + newsType = extractValue("type=", path); + dateChooserCtr.setType(newsType); + changed = true; + //consume the entry + entries = entries.subList(1, entries.size()); + } + if(!entries.isEmpty()) { + String dateEntry = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if(dateEntry.startsWith("date=")) { + try { + String date = extractValue("date=", dateEntry); + DateFormat format = new SimpleDateFormat("yyyyMMdd"); + compareDate = format.parse(date); + dateChooserCtr.setDate(compareDate); + changed = true; + } catch (ParseException e) { + logWarn("Error parsing the date after activate: " + dateEntry, e); + } + } + } + + if(changed) { + updateNewsDataModel(); + } + } + private String extractValue(String str, String identifier) { if(identifier.startsWith(str)) { int sepIndex = identifier.indexOf(':'); diff --git a/src/main/java/org/olat/notifications/NotificationSubscriptionAndNewsController.java b/src/main/java/org/olat/notifications/NotificationSubscriptionAndNewsController.java index d6acb772552..f13ea4acaf2 100644 --- a/src/main/java/org/olat/notifications/NotificationSubscriptionAndNewsController.java +++ b/src/main/java/org/olat/notifications/NotificationSubscriptionAndNewsController.java @@ -21,6 +21,7 @@ package org.olat.notifications; import java.util.Date; +import java.util.List; import org.olat.commons.rss.RSSUtil; import org.olat.core.gui.UserRequest; @@ -34,9 +35,12 @@ 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.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.id.Identity; import org.olat.core.id.User; import org.olat.core.id.UserConstants; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.util.Util; import org.olat.home.GuestHomeSite; @@ -50,7 +54,7 @@ import org.olat.home.GuestHomeSite; * * @author gnaegi */ -public class NotificationSubscriptionAndNewsController extends BasicController implements Activateable { +public class NotificationSubscriptionAndNewsController extends BasicController implements Activateable, Activateable2 { private Identity subscriberIdentity; private TabbedPane tabbedPane; private Panel subscriptionPanel, rssPanel; @@ -115,6 +119,8 @@ public class NotificationSubscriptionAndNewsController extends BasicController i notificationsRssVC.contextPut("fullName", fullName); rssPanel.setContent(notificationsRssVC); } + //fxdiff BAKS-7 Resume function + tabbedPane.addToHistory(ureq, getWindowControl()); } } } @@ -141,4 +147,20 @@ public class NotificationSubscriptionAndNewsController extends BasicController i newsCtr.activate(ureq, selection); } } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + String path = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if("news".equals(path)) { + activate(ureq, "[news:0]"); + } else if("notifications".equals(path)) { + List<ContextEntry> subEntries = entries.subList(1, entries.size()); + newsCtr.activate(ureq, subEntries, entries.get(0).getTransientState()); + } else { + tabbedPane.activate(ureq, entries, state); + } + } } diff --git a/src/main/java/org/olat/notifications/NotificationsPortletRunController.java b/src/main/java/org/olat/notifications/NotificationsPortletRunController.java index 2b131c8bb15..3640ff3a13a 100644 --- a/src/main/java/org/olat/notifications/NotificationsPortletRunController.java +++ b/src/main/java/org/olat/notifications/NotificationsPortletRunController.java @@ -72,7 +72,6 @@ import org.olat.core.util.notifications.SubscriptionInfo; import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseModule; import org.olat.group.BusinessGroupManagerImpl; -import org.olat.home.site.HomeSite; /** * Description:<br> @@ -226,9 +225,10 @@ public class NotificationsPortletRunController extends AbstractPortletRunControl public void event(UserRequest ureq, Component source, Event event) { if (source == showAllLink){ // activate homes tab in top navigation and active bookmarks menu item - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - //was brasato:: getWindowControl().getDTabs().activateStatic(ureq, HomeSite.class.getName(), "adminnotifications"); - dts.activateStatic(ureq, HomeSite.class.getName(), "adminnotifications"); + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][notifications:0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); } else if (event == ComponentUtil.VALIDATE_EVENT && needsModelReload) { //updateTableModel(ureq.getLocale(), ureq.getIdentity()); reloadModel(sortingCriteria); diff --git a/src/main/java/org/olat/portal/calendar/CalendarPortletRunController.java b/src/main/java/org/olat/portal/calendar/CalendarPortletRunController.java index f2f0d3b5be2..79d1300580c 100644 --- a/src/main/java/org/olat/portal/calendar/CalendarPortletRunController.java +++ b/src/main/java/org/olat/portal/calendar/CalendarPortletRunController.java @@ -31,6 +31,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; +import org.olat.NewControllerFactory; import org.olat.commons.calendar.CalendarUtils; import org.olat.commons.calendar.model.KalendarEvent; import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; @@ -53,9 +54,11 @@ 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.DTabs; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.logging.OLATRuntimeException; import org.olat.home.HomeCalendarController; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; /** * @@ -154,10 +157,11 @@ public class CalendarPortletRunController extends BasicController { */ public void event(UserRequest ureq, Component source, Event event) { if (source == showAllLink) { - String activationCmd = "cal." + new SimpleDateFormat("yyyy.MM.dd").format(new Date()); - DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs"); - //was brasato:: getWindowControl().getDTabs().activateStatic(ureq, HomeSite.class.getName(), activationCmd); - dts.activateStatic(ureq, HomeSite.class.getName(), activationCmd); + // activate homes tab in top navigation and active calendar menu item + String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][calendar:0]"; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); } else if (event == ComponentUtil.VALIDATE_EVENT && dirty) { List events = getMatchingEvents(ureq, getWindowControl()); tableController.setTableDataModel(new EventsModel(events)); diff --git a/src/main/java/org/olat/portal/quickstart/QuickstartPortletRunController.java b/src/main/java/org/olat/portal/quickstart/QuickstartPortletRunController.java index bb89392720a..591cb6b0ee9 100644 --- a/src/main/java/org/olat/portal/quickstart/QuickstartPortletRunController.java +++ b/src/main/java/org/olat/portal/quickstart/QuickstartPortletRunController.java @@ -41,7 +41,7 @@ import org.olat.core.id.Roles; import org.olat.core.util.Util; import org.olat.course.CourseFactory; import org.olat.group.site.GroupsSite; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; import org.olat.repository.site.RepositorySite; /** diff --git a/src/main/java/org/olat/portfolio/EPArtefactPoolExtension.java b/src/main/java/org/olat/portfolio/EPArtefactPoolExtension.java index c6905db9596..6f177192638 100644 --- a/src/main/java/org/olat/portfolio/EPArtefactPoolExtension.java +++ b/src/main/java/org/olat/portfolio/EPArtefactPoolExtension.java @@ -26,7 +26,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.ContextEntryControllerCreator; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; import org.olat.portfolio.model.artefacts.AbstractArtefact; /** diff --git a/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java b/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java index e4a1ab794e9..e84637a3948 100644 --- a/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java +++ b/src/main/java/org/olat/portfolio/EPMapOnInvitationExtension.java @@ -54,6 +54,7 @@ public class EPMapOnInvitationExtension { @Override public Controller createController(ContextEntry ce, UserRequest ureq, WindowControl wControl) { + PortfolioStructureMap map = getMapFromContext(ce); EPSecurityCallback secCallback = new EPSecurityCallbackImpl(false, true); Controller epCtr = EPUIFactory.createMapViewController(ureq, wControl, map, secCallback); diff --git a/src/main/java/org/olat/portfolio/EPMyMapsExtension.java b/src/main/java/org/olat/portfolio/EPMyMapsExtension.java index a57886558d1..ede6e0d48d9 100644 --- a/src/main/java/org/olat/portfolio/EPMyMapsExtension.java +++ b/src/main/java/org/olat/portfolio/EPMyMapsExtension.java @@ -20,21 +20,13 @@ */ package org.olat.portfolio; -import java.util.ArrayList; -import java.util.List; - import org.olat.NewControllerFactory; -import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; -import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.ContextEntryControllerCreator; -import org.olat.core.util.resource.OresHelper; -import org.olat.home.HomeMainController; -import org.olat.home.site.HomeSite; -import org.olat.portfolio.manager.EPFrontendManager; +import org.olat.home.HomeSite; import org.olat.portfolio.model.structel.EPDefaultMap; /** diff --git a/src/main/java/org/olat/portfolio/EPMyStructuredMapsExtension.java b/src/main/java/org/olat/portfolio/EPMyStructuredMapsExtension.java index b15343be2d6..a706a5855b5 100644 --- a/src/main/java/org/olat/portfolio/EPMyStructuredMapsExtension.java +++ b/src/main/java/org/olat/portfolio/EPMyStructuredMapsExtension.java @@ -26,7 +26,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.ContextEntryControllerCreator; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; import org.olat.portfolio.model.structel.EPStructuredMap; /** diff --git a/src/main/java/org/olat/portfolio/EPOtherMapsExtension.java b/src/main/java/org/olat/portfolio/EPOtherMapsExtension.java index c86e711ae30..b0d50054b53 100644 --- a/src/main/java/org/olat/portfolio/EPOtherMapsExtension.java +++ b/src/main/java/org/olat/portfolio/EPOtherMapsExtension.java @@ -26,7 +26,7 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.ContextEntryControllerCreator; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; /** * Description:<br> diff --git a/src/main/java/org/olat/portfolio/EPUIFactory.java b/src/main/java/org/olat/portfolio/EPUIFactory.java index 56aef5745a8..b8a684cd889 100755 --- a/src/main/java/org/olat/portfolio/EPUIFactory.java +++ b/src/main/java/org/olat/portfolio/EPUIFactory.java @@ -65,8 +65,9 @@ public class EPUIFactory { * @return */ public static Controller createPortfolioPoolController(UserRequest ureq, WindowControl wControl) { - return new EPArtefactPoolRunController(ureq, wControl); + return new EPArtefactPoolRunController(ureq, wControl); } + /** * get a controller for admin-setup of e Portfolio * used directly over extension-config, therefore needs to be static diff --git a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml index a701a78f521..dd63dc3dd7e 100644 --- a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml +++ b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml @@ -65,15 +65,17 @@ <property name="factoryMethod" value="createPortfolioAdminController"/> </bean> </property> + <property name="navigationKey" value="portfolio" /> <property name="i18nActionKey" value="admin.menu.title"/> <property name="i18nDescriptionKey" value="admin.menu.title.alt"/> <property name="translationPackage" value="org.olat.portfolio.ui"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> <property name="extensionPoints"> <list> <value>org.olat.admin.SystemAdminMainController</value> </list> </property> - <property name="order" value="37" /> + <property name="order" value="775" /> </bean> <!-- Portfolio Main View/all my artefacts in users Home --> @@ -197,4 +199,104 @@ </bean> + <!-- hook into minimalHome menu-tree --> + <!-- the EP-MENU (parent) --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" name="home.menupoint.ep" init-method="initExtensionPoints"> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="nodeIdentifierIfParent" value="portfolioParent" /> + <property name="translationPackage" value="org.olat.portfolio.ui" /> + <property name="i18nActionKey" value="eportfolio.menu.title" /> + <property name="i18nDescriptionKey" value="eportfolio.menu.title.alt" /> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the "my artefacts" menu --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" name="home.menupoint.ep.pool" init-method="initExtensionPoints" > + <property name="order" value="301" /> + <property name="actionController"> + <bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.portfolio.EPUIFactory"/> + <property name="factoryMethod" value="createPortfolioPoolController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.portfolio.ui" /> + <property name="i18nActionKey" value="myartefacts.menu.title"/> + <property name="i18nDescriptionKey" value="myartefacts.menu.title.alt"/> + <property name="parentTreeNodeIdentifier" value="portfolioParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the "my maps" menu --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" name="home.menupoint.ep.maps" init-method="initExtensionPoints" > + <property name="order" value="302" /> + <property name="actionController"> + <bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.portfolio.EPUIFactory"/> + <property name="factoryMethod" value="createPortfolioMapsController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.portfolio.ui" /> + <property name="i18nActionKey" value="mymaps.menu.title"/> + <property name="i18nDescriptionKey" value="mymaps.menu.title.alt"/> + <property name="parentTreeNodeIdentifier" value="portfolioParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the "my portfolioaufgaben" menu --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" name="home.menupoint.ep.structuredmaps" init-method="initExtensionPoints" > + <property name="order" value="303" /> + <property name="actionController"> + <bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.portfolio.EPUIFactory"/> + <property name="factoryMethod" value="createPortfolioStructuredMapsController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.portfolio.ui" /> + <property name="i18nActionKey" value="mystructuredmaps.menu.title"/> + <property name="i18nDescriptionKey" value="mystructuredmaps.menu.title.alt"/> + <property name="parentTreeNodeIdentifier" value="portfolioParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + <!-- the "shared maps" menu --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" name="home.menupoint.ep.sharedmaps" init-method="initExtensionPoints" > + <property name="order" value="304" /> + <property name="actionController"> + <bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.portfolio.EPUIFactory"/> + <property name="factoryMethod" value="createPortfolioMapsFromOthersController"/> + </bean> + </property> + <property name="securityCallbackClassName" value="org.olat.core.extensions.security.UserOnlyExtensionSecurityCallback" /> + <property name="translationPackage" value="org.olat.portfolio.ui" /> + <property name="i18nActionKey" value="othermaps.menu.title"/> + <property name="i18nDescriptionKey" value="othermaps.menu.title.alt"/> + <property name="parentTreeNodeIdentifier" value="portfolioParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.home.HomeMainController</value> + </list> + </property> + </bean> + + </beans> diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPMultipleMapController.java b/src/main/java/org/olat/portfolio/ui/structel/EPMultipleMapController.java index c4616e755bc..236a1fa1767 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPMultipleMapController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPMultipleMapController.java @@ -47,7 +47,7 @@ import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; -import org.olat.home.site.HomeSite; +import org.olat.home.HomeSite; import org.olat.portfolio.EPLoggingAction; import org.olat.portfolio.EPSecurityCallback; import org.olat.portfolio.EPSecurityCallbackFactory; diff --git a/src/main/java/org/olat/repository/controllers/RepositoryDetailsController.java b/src/main/java/org/olat/repository/controllers/RepositoryDetailsController.java index 76d171ff3ab..4562c34099a 100644 --- a/src/main/java/org/olat/repository/controllers/RepositoryDetailsController.java +++ b/src/main/java/org/olat/repository/controllers/RepositoryDetailsController.java @@ -158,6 +158,8 @@ public class RepositoryDetailsController extends BasicController implements Gene //different instances for "copy" and "settings change", since it is important to know what triggered the CLOSE_MODAL_EVENT private CloseableModalController copyCloseableModalController; private CloseableModalController settingsCloseableModalController; + //fxdiff FXOLAT-128: back/resume function + public static final Event LAUNCHED_EVENT = new Event("lr-launched"); /** * Controller displaying details of a given repository entry. @@ -563,7 +565,8 @@ public class RepositoryDetailsController extends BasicController implements Gene DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, displayName); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, repositoryEntry, displayName); if (dt == null) return; // build up the context path @@ -583,7 +586,8 @@ public class RepositoryDetailsController extends BasicController implements Gene * close detail page after resource is closed * DONE_EVENT will be catched by RepositoryMainController */ - fireEvent(ureq, Event.DONE_EVENT); + //fxdiff FXOLAT-128: back/resume function + fireEvent(ureq, LAUNCHED_EVENT); } private boolean checkIsRepositoryEntryLaunchable(UserRequest ureq) { @@ -743,7 +747,8 @@ public class RepositoryDetailsController extends BasicController implements Gene DTab dt = dts.getDTab(ores); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(ores, repositoryEntry.getDisplayname()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(ores, repositoryEntry, repositoryEntry.getDisplayname()); if (dt == null){ //null means DTabs are full -> warning is shown return; diff --git a/src/main/java/org/olat/repository/controllers/RepositoryMainController.java b/src/main/java/org/olat/repository/controllers/RepositoryMainController.java index 24804dda494..c0af345be55 100644 --- a/src/main/java/org/olat/repository/controllers/RepositoryMainController.java +++ b/src/main/java/org/olat/repository/controllers/RepositoryMainController.java @@ -21,6 +21,8 @@ package org.olat.repository.controllers; +import java.util.List; + import org.olat.catalog.CatalogEntry; import org.olat.catalog.ui.CatalogController; import org.olat.core.CoreSpringFactory; @@ -41,16 +43,22 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.dtabs.Activateable; +import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.gui.control.generic.portal.PortletFactory; import org.olat.core.gui.control.generic.tool.ToolController; import org.olat.core.gui.control.generic.tool.ToolFactory; import org.olat.core.gui.control.generic.wizard.WizardController; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; +import org.olat.core.util.resource.OresHelper; import org.olat.core.util.tree.TreeHelper; import org.olat.course.CourseModule; import org.olat.fileresource.types.BlogFileResource; @@ -90,7 +98,7 @@ import de.bps.olat.repository.controllers.WizardAddOwnersController; * @date Initial Date: Oct 21, 2004 <br> * @author Felix Jost */ -public class RepositoryMainController extends MainLayoutBasicController implements Activateable { +public class RepositoryMainController extends MainLayoutBasicController implements Activateable, Activateable2 { OLog log = Tracing.createLoggerFor(this.getClass()); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(RepositoryManager.class); @@ -119,6 +127,8 @@ public class RepositoryMainController extends MainLayoutBasicController implemen private String myEntriesNodeId; private RepositoryAddController addController; + //fxdiff BAKS-7 Resume function + private WindowControl searchWindowControl; private RepositorySearchController searchController; private RepositoryDetailsController detailsController; private DialogBoxController launchEditorDialog; @@ -430,6 +440,9 @@ public class RepositoryMainController extends MainLayoutBasicController implemen // encode sub view identifyer into state, attach separated by ":" lastUserObject = userObject.toString(); removeAsListenerAndDispose(deleteTabPaneCtr); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(lastUserObject, 0l); + searchWindowControl = addToHistory(ureq, ores, null); } private void activateCatalogController(UserRequest ureq, String nodeId) { @@ -438,7 +451,10 @@ public class RepositoryMainController extends MainLayoutBasicController implemen // catalog link in the menu if (catalogCntrllr == null || lastUserObject.equals("search.catalog")) { removeAsListenerAndDispose(catalogCntrllr); - catalogCntrllr = new CatalogController(ureq, getWindowControl(), nodeId); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance("search.catalog", 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); + catalogCntrllr = new CatalogController(ureq, bwControl, nodeId); listenTo(catalogCntrllr); } else { // just activate the existing catalog @@ -552,20 +568,30 @@ public class RepositoryMainController extends MainLayoutBasicController implemen Component toolComp = (toolC == null ? null : toolC.getInitialComponent()); columnsLayoutCtr.setCol2(toolComp); mainPanel.setContent(detailsController.getInitialComponent()); + //fxdiff BAKS-7 Resume function + addToHistory(urequest, selectedEntry, null, searchWindowControl, true); } } else if (source == detailsController) { // back from details - if (event.equals(Event.DONE_EVENT)) { + //fxdiff FXOLAT-128: back/resume function + if (event.equals(Event.DONE_EVENT) || event.equals(RepositoryDetailsController.LAUNCHED_EVENT)) { if (backtocatalog) { backtocatalog = false; ToolController toolC = catalogCntrllr.createCatalogToolController(); Component toolComp = (toolC == null ? null : toolC.getInitialComponent()); columnsLayoutCtr.setCol2(toolComp); mainPanel.setContent(catalogCntrllr.getInitialComponent()); - + //fxdiff BAKS-7 Resume function + if(!event.equals(RepositoryDetailsController.LAUNCHED_EVENT)) { + catalogCntrllr.updateHistory(urequest); + } } else { Component toolComp = (mainToolC == null ? null : mainToolC.getInitialComponent()); columnsLayoutCtr.setCol2(toolComp); mainPanel.setContent(main); + //fxdiff BAKS-7 Resume function + if(!event.equals(RepositoryDetailsController.LAUNCHED_EVENT)) { + addToHistory(urequest, searchWindowControl); + } } } else if (event instanceof EntryChangedEvent) { Component toolComp = (mainToolC == null ? null : mainToolC.getInitialComponent()); @@ -763,6 +789,41 @@ public class RepositoryMainController extends MainLayoutBasicController implemen protected void doDispose() { // } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + ContextEntry entry = entries.remove(0); + String type = entry.getOLATResourceable().getResourceableTypeName(); + //activate the catalog + if(CatalogEntry.class.getSimpleName().equals(type)) { + TreeNode rootNode = menuTree.getTreeModel().getRootNode(); + TreeNode activatedNode = TreeHelper.findNodeByUserObject("search.catalog", rootNode); + if (activatedNode != null) { + menuTree.setSelectedNodeId(activatedNode.getIdent()); + String catId = entry.getOLATResourceable().getResourceableId().toString(); + activateContent(ureq, "search.catalog", catId); + } + } else { + TreeNode rootNode = menuTree.getTreeModel().getRootNode(); + TreeNode activatedNode = TreeHelper.findNodeByUserObject(type, rootNode); + if (activatedNode != null) { + menuTree.setSelectedNodeId(activatedNode.getIdent()); + long resId = entry.getOLATResourceable().getResourceableId(); + activateContent(ureq, type, resId != 0 ? Long.toString(resId) : null); + if(!entries.isEmpty()) { + String subType = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if(RepositoryEntry.class.getSimpleName().equals(subType)) { + searchController.activate(ureq, entries, entry.getTransientState()); + } else if(CatalogEntry.class.getSimpleName().equals(subType)) { + catalogCntrllr.activate(ureq, entries, entry.getTransientState()); + } + } + } + } + } /** * @see org.olat.core.gui.control.generic.dtabs.Activateable#activate(org.olat.core.gui.UserRequest, diff --git a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java index e0338eac321..78e64212a8c 100644 --- a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java +++ b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java @@ -39,11 +39,14 @@ import org.olat.core.gui.control.Controller; 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.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.id.UserConstants; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.util.Util; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; @@ -65,7 +68,7 @@ import org.olat.repository.SearchForm; * * @author Felix Jost */ -public class RepositorySearchController extends BasicController { +public class RepositorySearchController extends BasicController implements Activateable2 { private static final String PACKAGE = Util.getPackageName(RepositoryManager.class); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(RepositoryManager.class); @@ -159,6 +162,20 @@ public class RepositorySearchController extends BasicController { public void enableBackToSearchFormLink(boolean enableBack) { vc.contextPut("withBack", new Boolean(enableBack)); } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) return; + + String subType = entries.get(0).getOLATResourceable().getResourceableTypeName(); + if(RepositoryEntry.class.getSimpleName().equals(subType)) { + //activate details + Long resId = entries.get(0).getOLATResourceable().getResourceableId(); + selectedEntry = RepositoryManager.getInstance().lookupRepositoryEntry(resId); + fireEvent(ureq, new Event(RepositoryTableModel.TABLE_ACTION_SELECT_LINK)); + } + } /** * @param enable true: searches done by the search form will find all resources diff --git a/src/main/java/org/olat/repository/portlet/RepositoryPortletRunController.java b/src/main/java/org/olat/repository/portlet/RepositoryPortletRunController.java index 6b5d274b934..b8a1394f142 100644 --- a/src/main/java/org/olat/repository/portlet/RepositoryPortletRunController.java +++ b/src/main/java/org/olat/repository/portlet/RepositoryPortletRunController.java @@ -200,7 +200,8 @@ public class RepositoryPortletRunController extends AbstractPortletRunController DTab dt = dts.getDTab(repoEntry.getOlatResource()); if (dt == null) { // does not yet exist -> create and add - dt = dts.createDTab(repoEntry.getOlatResource(), repoEntry.getDisplayname()); + //fxdiff BAKS-7 Resume function + dt = dts.createDTab(repoEntry.getOlatResource(), repoEntry, repoEntry.getDisplayname()); // tabs full if (dt != null) { Controller runCtr = RepositoyUIFactory.createLaunchController(repoEntry, null, ureq, dt.getWindowControl()); diff --git a/src/main/java/org/olat/repository/site/RepositorySite.java b/src/main/java/org/olat/repository/site/RepositorySite.java index d9855a6c9ba..b529212cde0 100644 --- a/src/main/java/org/olat/repository/site/RepositorySite.java +++ b/src/main/java/org/olat/repository/site/RepositorySite.java @@ -34,6 +34,8 @@ import org.olat.core.gui.control.navigation.SiteInstance; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.id.context.StateSite; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; import org.olat.repository.controllers.RepositoryMainController; @@ -77,7 +79,10 @@ public class RepositorySite implements SiteInstance { */ public MainLayoutController createController(UserRequest ureq, WindowControl wControl) { // for existing controller which are part of the main olat -> use the controllerfactory - MainLayoutController c = ControllerFactory.createLaunchController(ORES_REPO, null, ureq, wControl, true); + //fxdiff BAKS-7 Resume function + OLATResourceable ores = OresHelper.createOLATResourceableInstance(RepositorySite.class, 0l); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); + MainLayoutController c = ControllerFactory.createLaunchController(ORES_REPO, null, ureq, bwControl, true); return c; } diff --git a/src/main/java/org/olat/user/ChangePrefsController.java b/src/main/java/org/olat/user/ChangePrefsController.java index 274933bc9c0..accc747aa62 100644 --- a/src/main/java/org/olat/user/ChangePrefsController.java +++ b/src/main/java/org/olat/user/ChangePrefsController.java @@ -22,11 +22,15 @@ package org.olat.user; +import java.util.Set; + +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.WindowManager; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +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.components.velocity.VelocityContainer; @@ -36,7 +40,10 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.id.Identity; import org.olat.core.util.UserSession; - +import org.olat.core.id.User; +import org.olat.core.id.context.HistoryManager; +import org.olat.core.id.context.HistoryModule; +import org.olat.core.util.StringHelper; import org.olat.core.util.prefs.Preferences; import org.olat.core.util.prefs.PreferencesFactory; @@ -131,8 +138,15 @@ class SpecialPrefsForm extends FormBasicController { private Identity tobeChangedIdentity; private Preferences prefs; private MultipleSelectionElement prefsElement; + //fxdiff BAKS-7 Resume function + private SingleSelection resumeElement; + private SingleSelection backElement; private String[] keys, values; private boolean useAjaxCheckbox = false; + private String[] resumeKeys, resumeValues; + /** The keys for yes/no back. */ + private String[] yesNoKeys; + private String[] yesNoValues; public SpecialPrefsForm(final UserRequest ureq, final WindowControl wControl, final Identity changeableIdentity) { super(ureq, wControl); @@ -158,7 +172,15 @@ class SpecialPrefsForm extends FormBasicController { translate("accessibility.web2aMode.label") }; } - + //fxdiff BAKS-7 Resume function + resumeKeys = new String[]{"none", "auto", "ondemand"}; + resumeValues = new String[] { + translate("resume.none"), + translate("resume.auto"), + translate("resume.ondemand"), + }; + yesNoKeys = new String[]{"yes", "no"}; + yesNoValues = new String[] { translate("back.on"), translate("back.off") }; initForm(ureq); } @@ -177,6 +199,13 @@ class SpecialPrefsForm extends FormBasicController { prefs.putAndSave(WindowManager.class, "ajax-beta-on", prefsElement.getSelectedKeys().contains("ajax")); } prefs.putAndSave(WindowManager.class, "web2a-beta-on", prefsElement.getSelectedKeys().contains("web2a")); + //fxdiff BAKS-7 Resume function + if(resumeElement != null) { + prefs.putAndSave(WindowManager.class, "resume-prefs", resumeElement.getSelectedKey()); + } + if(backElement != null) { + prefs.putAndSave(WindowManager.class, "back-enabled", backElement.isSelected(0)); + } if (ureq.getIdentity().equalsByPersistableKey(tobeChangedIdentity)) { showInfo("preferences.successful"); } @@ -194,8 +223,14 @@ class SpecialPrefsForm extends FormBasicController { setFormContextHelp(this.getClass().getPackage().getName(), "home-prefs-special.html", "help.hover.home.prefs.special"); prefsElement = uifactory.addCheckboxesVertical("prefs", "title.prefs.accessibility", formLayout, keys, values, null, 1); - - + //fxdiff BAKS-7 Resume function + HistoryModule historyModule = (HistoryModule)CoreSpringFactory.getBean("historyModule"); + if(historyModule.isResumeEnabled()) { + resumeElement = uifactory.addRadiosVertical("resume", "resume.label", formLayout, resumeKeys, resumeValues); + } + if(historyModule.isBackEnabled()) { + backElement = uifactory.addRadiosVertical("back-enabling", "back.label", formLayout, yesNoKeys, yesNoValues); + } update(); final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator()); @@ -211,6 +246,34 @@ class SpecialPrefsForm extends FormBasicController { prefsElement.select("ajax", ajax == null ? true: ajax.booleanValue()); } prefsElement.select("web2a", web2a == null ? false: web2a.booleanValue()); + //fxdiff BAKS-7 Resume function + if(resumeElement != null) { + String resumePrefs = (String)prefs.get(WindowManager.class, "resume-prefs"); + if(StringHelper.containsNonWhitespace(resumePrefs)) { + resumeElement.select(resumePrefs, true); + } else { + HistoryModule historyModule = (HistoryModule)CoreSpringFactory.getBean("historyModule"); + String defaultSetting = historyModule.getResumeDefaultSetting(); + try { + resumeElement.select(defaultSetting, true); + } catch (Exception e) { + logError("Unavailable setting for resume function: " + defaultSetting, e); + } + } + } + if(backElement != null) { + Boolean be = (Boolean)prefs.get(WindowManager.class, "back-enabled"); + String selected; + if (be != null) { + selected = (be.booleanValue() ? "yes" : "no"); + } + else { + HistoryModule historyModule = (HistoryModule)CoreSpringFactory.getBean("historyModule"); + selected = (historyModule.isBackDefaultSetting() ? "yes" : "no"); + } + + backElement.select(selected, true); + } } @Override diff --git a/src/main/java/org/olat/user/PersonalSettingsController.java b/src/main/java/org/olat/user/PersonalSettingsController.java index 28da08466bd..2cd238c1be6 100644 --- a/src/main/java/org/olat/user/PersonalSettingsController.java +++ b/src/main/java/org/olat/user/PersonalSettingsController.java @@ -21,6 +21,8 @@ package org.olat.user; +import java.util.List; + import org.olat.basesecurity.Authentication; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; @@ -29,11 +31,15 @@ import org.olat.core.commons.persistence.DBFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.tabbedpane.TabbedPane; +import org.olat.core.gui.components.tabbedpane.TabbedPaneChangedEvent; import org.olat.core.gui.control.Controller; 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.id.Identity; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATSecurityException; import org.olat.core.servlets.WebDAVManager; import org.olat.core.util.resource.OresHelper; @@ -50,7 +56,7 @@ import org.olat.registration.RegistrationModule; * @author Sabina Jeger * */ -public class PersonalSettingsController extends BasicController { +public class PersonalSettingsController extends BasicController implements Activateable2 { private TabbedPane userConfig; @@ -76,6 +82,8 @@ public class PersonalSettingsController extends BasicController { throw new OLATSecurityException("Insufficient permissions to access PersonalSettingsController"); userConfig = new TabbedPane("userConfig", ureq.getLocale()); + //fxdiff BAKS-7 Resume function + userConfig.addListener(this); hpec = new ProfileAndHomePageEditController(ureq, getWindowControl(), (Identity)DBFactory.getInstance().loadObject(ureq.getIdentity()), false); listenTo(hpec); @@ -128,8 +136,11 @@ public class PersonalSettingsController extends BasicController { * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event) */ @Override + //fxdiff BAKS-7 Resume function public void event(UserRequest ureq, Component source, Event event) { - // nothing to do here. + if (source == userConfig && event instanceof TabbedPaneChangedEvent) { + userConfig.addToHistory(ureq, getWindowControl()); + } } /** @@ -147,4 +158,10 @@ public class PersonalSettingsController extends BasicController { protected void doDispose() { // } + + @Override + //fxdiff BAKS-7 Resume function + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + userConfig.activate(ureq, entries, state); + } } \ No newline at end of file diff --git a/src/main/java/org/olat/user/ProfileAndHomePageEditController.java b/src/main/java/org/olat/user/ProfileAndHomePageEditController.java index dc1f45b1f15..b090d8ca174 100644 --- a/src/main/java/org/olat/user/ProfileAndHomePageEditController.java +++ b/src/main/java/org/olat/user/ProfileAndHomePageEditController.java @@ -217,9 +217,6 @@ public class ProfileAndHomePageEditController extends BasicController implements } }); if (emailChanged) { - if (dialogCtr != null) { - dialogCtr.dispose(); - } if (dialogCtr != null) { dialogCtr.dispose(); } diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties index 6cbe330324b..0461dfe54bd 100644 --- a/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/user/_i18n/LocalStrings_de.properties @@ -219,6 +219,13 @@ chelp.accessibility1=F chelp.accessibility0=Barrierefreiheit identity.not.existing=Der gewünschte Benutzer konnte nicht gefunden werden. +back.on=Ein (Experimental) +back.off=Aus +back.label=Unterstützung "Browser Zurück" +resume.label=Sitzung wiederherstellen +resume.none=Nein +resume.auto=Ja, automatisch +resume.ondemand=Ja, bei Bedarf diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties index 3706882a004..5ab26377a2c 100644 --- a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties @@ -6,6 +6,9 @@ accessibility.web2aMode.label=Web 2.a mode for braille readers action.choose=Select ajaxon.global.label=AJAX mode active on system level ajaxon.label=AJAX mode +back.label=Support for "browser back" +back.off=Off +back.on=On (experimental) change=Modify error.user.logged.in=This change can not be made as the user {0} is currently logged in. Please wait until the user has logged out and try it again. chelp.accessibility0=Accessibility @@ -178,6 +181,10 @@ pwdav.password.successful=Your new WebDAV password has been saved successfully. pwdav.title=WebDAV access pwdav.username=WebDav user name replayurl.active=Load performance URL active +resume.auto=Yes, automatically +resume.label=Resume last session +resume.none=No +resume.ondemand=Yes, on request runonce.changepw.intro=Please modify your password. runonce.profile.intro=Please check if your profile is up-to-date before clicking on "Save." success.change.email=This E-mail address has been altered successfully from {0} to {1}. diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index a6ca19504bf..4e54d112a2b 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -76,7 +76,17 @@ enabledLanguages=en,de,fr,it,es # determines the character set of files written to the filesystem # e.g.: US-ASCII, ISO-8859-1, UTF-8 -defaultcharset=ISO-8859-1 +defaultcharset=UTF-8 + + +# global on/off config for back and resume +history.back.enabled=true +history.resume.enabled=true +# default settings for the back function in case feature is available +history.back.enabled.default=true +# default settings for the resume function in case feature is available +history.resume.enabled.default=ondemand +history.resume.enabled.default.values=none,auto,ondemand ######################################################################## # SMTP (mail) settings @@ -246,6 +256,23 @@ portlet.infomessages.enabled=true # whether or not the gui demo site should be enabled=shown guidemo.enabled=true +######################################################################## +# OALT sites / tabs +######################################################################## +# enable / disable homeSite +site.minimalhome.enabled=true + +#enable / disable GAE for HomeMainController (frentixContext.xml) +#note: orders, mail and EP are disabled via module-config +minimalhome.ext.efficiencystatement=true +minimalhome.ext.otherusers=true +minimalhome.ext.notelist=true +minimalhome.ext.userfolder=true +minimalhome.ext.bookmarks=true +minimalhome.ext.notifications=true +minimalhome.ext.calendar=true +minimalhome.ext.mysettings=true +minimalhome.ext.portal=true #webdav manager (show or don't webdav links in GIU) webdav.links.enabled=true diff --git a/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml b/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml index c77fd8f3051..9443d924ee3 100644 --- a/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml +++ b/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml @@ -15,31 +15,366 @@ <!-- classes implementing the Extension interface --> <!-- Locations that implement action extensions: SystemAdminMainController, HomeMainController, ArchiverMaincontroller --> + +<!-- SYSADMIN extension for admin site for OLAT setup --> + + <!-- the sysinfo menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="1" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.sysinfo.SysinfoController"/> + </bean> + </property> + <property name="navigationKey" value="sysinfo" /> + <property name="translationPackage" value="org.olat.admin"/> + <property name="i18nActionKey" value="menu.sysinfo"/> + <property name="i18nDescriptionKey" value="menu.sysinfo.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + + <!-- the "systemconfig" parent node --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="2" /> + <property name="navigationKey" value="sysconfig" /> + <property name="nodeIdentifierIfParent" value="sysconfigParent" /> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.config" /> + <property name="i18nDescriptionKey" value="menu.config.alt" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + <!-- the layout ("Darstellung") menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="771" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.layout.LayoutAdminController"/> + </bean> + </property> + <property name="navigationKey" value="layout" /> + <property name="translationPackage" value="org.olat.admin"/> + <property name="i18nActionKey" value="menu.layout"/> + <property name="i18nDescriptionKey" value="menu.layout.alt"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + <!-- the i18n ("sprachen") menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints" > + <property name="order" value="772" /> + <property name="navigationKey" value="i18n" /> + <property name="actionController"> + <bean class=" org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.core.util.i18n.ui.I18nUIFactory"/> + <property name="factoryMethod" value="createI18nConfigurationController" /> + </bean> + </property> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.i18n"/> + <property name="i18nDescriptionKey" value="menu.i18n.alt"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + <!-- the quota menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints" > + <property name="order" value="773" /> + <property name="navigationKey" value="quota" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.quota.QuotaController"/> + </bean> + </property> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.quota"/> + <property name="i18nDescriptionKey" value="menu.quota.alt"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + <!-- the version ("versionisierung") menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints" > + <property name="order" value="774" /> + <property name="navigationKey" value="versioning" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.version.VersionAdminController"/> + </bean> + </property> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.versions"/> + <property name="i18nDescriptionKey" value="menu.versions.alt"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + + <!-- the REST API menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="778" /> + <property name="navigationKey" value="restapi" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.restapi.RestapiAdminController"/> + </bean> + </property> + <property name="i18nActionKey" value="menu.restapi"/> + <property name="i18nDescriptionKey" value="menu.restapi.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + </bean> + <!-- the spring-extensions ("Software Module") menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.extensions.ExtensionsAdminController"/> + </bean> + </property> + <property name="navigationKey" value="extensions" /> + <property name="i18nActionKey" value="menu.extensions"/> + <property name="i18nDescriptionKey" value="menu.extensions.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="order" value="779" /> + </bean> + + <!-- the ("einrichten") menu-entry --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="3" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.core.configuration.SetupPropertiesController"/> + </bean> + </property> + <property name="navigationKey" value="properties" /> + <property name="i18nActionKey" value="main.menu.title"/> + <property name="i18nDescriptionKey" value="main.menu.title.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + + + + + - <!-- extension for admin site for OLAT setup --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="actionController"> <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> - <property name="className" value="org.olat.core.configuration.SetupPropertiesController"/> + <property name="className" value="org.olat.admin.properties.AdvancedPropertiesController"/> </bean> </property> - <property name="i18nActionKey" value="main.menu.title"/> - <property name="i18nDescriptionKey" value="main.menu.title.alt"/> + <property name="navigationKey" value="advancedproperties" /> + <property name="i18nActionKey" value="menu.advancedproperties"/> + <property name="i18nDescriptionKey" value="menu.advancedproperties.alt"/> + <property name="translationPackage" value="org.olat.admin"/> <property name="extensionPoints"> <list> <value>org.olat.admin.SystemAdminMainController</value> </list> </property> - <property name="order" value="1" /> + <property name="order" value="5" /> + </bean> + + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.instantMessaging.InstantMessagingAdminController"/> + </bean> + </property> + <property name="navigationKey" value="im" /> + <property name="i18nActionKey" value="menu.imadmin"/> + <property name="i18nDescriptionKey" value="menu.imadmin.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="6" /> + <property name="enabled" value="${instantMessaging.enable}"/> + </bean> + + + <!-- SYSADMIN customizing parent node --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <!-- <property name="actionController" value=""> + + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.instantMessaging.InstantMessagingAdminController"/> + </bean> + </property> --> + <property name="navigationKey" value="customizing" /> + <property name="nodeIdentifierIfParent" value="sysAdminMenueNodeCustomizing" /> + <property name="i18nActionKey" value="menu.parent.customizing"/> + <property name="i18nDescriptionKey" value="menu.parent.customizing.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="5" /> + </bean> + + <!-- "Sprachanpassungswerkzeug" --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> + <property name="factoryName" value="org.olat.core.util.i18n.ui.I18nUIFactory"/> + <property name="factoryMethod" value="createTranslationToolLauncherController"/> + </bean> + </property> + <property name="navigationKey" value="translation" /> + <property name="translationPackage" value="org.olat.core.util.i18n.ui" /> + <property name="i18nActionKey" value="start.customize.title"/> + <property name="i18nDescriptionKey" value="launch.title"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeCustomizing" /> + <property name="order" value="51" /> </bean> - <!-- extension for admin site for olatPasswordAuthentication --> + + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.registration.SystemRegistrationAdminController"/> + </bean> + </property> + <property name="navigationKey" value="registration" /> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.registration"/> + <property name="i18nDescriptionKey" value="menu.registration.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeCustomizing" /> + <property name="order" value="52" /> + </bean> + + + +<!-- SYSADMIN maintenance parent node --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="nodeIdentifierIfParent" value="sysAdminMenueNodeMaintenance" /> + <property name="navigationKey" value="sysadmin" /> + <property name="i18nActionKey" value="menu.parent.maintenance"/> + <property name="i18nDescriptionKey" value="menu.parent.maintenance.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="4" /> + </bean> + + <!-- statistics --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.statistics.StatisticsAdminController"/> + </bean> + </property> + <property name="navigationKey" value="statistics" /> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeMaintenance" /> + <property name="i18nActionKey" value="menu.statistics"/> + <property name="i18nDescriptionKey" value="menu.statistics.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="41" /> + </bean> + <!-- search admin ("volltextsuche") --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.search.SearchAdminController"/> + </bean> + </property> + <property name="navigationKey" value="search" /> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeMaintenance" /> + <property name="i18nActionKey" value="menu.search"/> + <property name="i18nDescriptionKey" value="menu.search.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="42" /> + </bean> + + <!-- ("benachrichtigungen") --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.notifications.NotificationsEmailAdminController"/> + </bean> + </property> + <property name="navigationKey" value="notifications" /> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeMaintenance" /> + <property name="i18nActionKey" value="menu.notifications"/> + <property name="i18nDescriptionKey" value="menu.notifications.alt"/> + <property name="translationPackage" value="org.olat.admin"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="order" value="43" /> + </bean> + + <!-- user bulk-pw change ("OLAT password") --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="actionController"> <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> <property name="className" value="org.olat.admin.user.bulkChange.UserBulkChangePasswordController"/> </bean> </property> + <property name="navigationKey" value="userbulkchangepw" /> <property name="i18nActionKey" value="main.menu.title"/> <property name="i18nDescriptionKey" value="main.menu.title.alt"/> <property name="extensionPoints"> @@ -47,9 +382,12 @@ <value>org.olat.admin.SystemAdminMainController</value> </list> </property> - <property name="order" value="2" /> - </bean> - + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeMaintenance" /> + <property name="order" value="46" /> + </bean> + + + <!-- Extensions in Statistic the first extension is text only and can be created with the most "generic" framework classes @@ -604,12 +942,18 @@ <property name="i18nActionKey" value="thisItem.title"/> <# optional, if none provided: <translationPackage>.menu.title.alt will be used #> <property name="i18nDescriptionKey" value="thisItem.title.alt"/> + + <property name="securityCallbackClassName" value="org.olat.core.extensions.action.ActionExtensionSecurityCallback"/> + <property name="extensionPoints"> <list> <value>org.olat.admin.SystemAdminMainController</value> <value>other Points where it should be</value> </list> </property> + # the parent actionExtension must have a lower order-value to be loaded before the children! + <property name="nodeIdentifierIfParent" value="someUniqueKey" /> + <property name="parentTreeNodeIdentifier" value="ifChild-point-to-someUniqueKey-from-parent" /> <property name="order" value="38" /> </bean> --> diff --git a/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml b/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml index fb297baad65..846c7edb4cd 100644 --- a/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml +++ b/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml @@ -25,8 +25,9 @@ </bean>--> <!-- Disable site by adding '<property name="enabled" value="false"/>' --> - <bean id="olatsites_home" class="org.olat.home.site.HomeSiteDef" scope="prototype" > + <bean id="olatsites_home" class="org.olat.home.HomeSiteDef" scope="prototype" > <property name="order" value="1" /> + <property name="enabled" value="${site.minimalhome.enabled}"/> </bean> <bean id="olatsites_groups" class="org.olat.group.site.GroupsSiteDef" scope="prototype" > <property name="order" value="2" /> diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index dd29de71c4a..f759388fefb 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -30,11 +30,12 @@ This is due to the fact that it can only control Loggers that have been created after it (ThreadLocalLogLevelManager) has been installed. --> classpath:/org/olat/core/util/threadlog/_spring/threadlogCorecontext.xml - classpath:/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml + classpath:/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml classpath:/org/olat/core/util/i18n/_spring/i18nCorecontext.xml classpath:/org/olat/core/util/_spring/utilCorecontext.xml classpath:/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml classpath:/org/olat/core/util/event/_spring/frameworkStartedEventCorecontext.xml + classpath:/org/olat/core/id/context/_spring/historyCorecontext.xml classpath:/org/olat/core/commons/persistence/_spring/databaseCorecontext.xml classpath:/org/olat/core/commons/taskExecutor/_spring/taskExecutorCorecontext.xml @@ -48,8 +49,8 @@ classpath:/org/olat/core/logging/activity/_spring/activityCorecontext.xml classpath:/org/olat/core/_spring/mainCorecontext.xml classpath:/org/olat/core/dispatcher/jumpin/_spring/jumpinCorecontext.xml - classpath:/org/olat/core/commons/services/tagging/_spring/taggingContext.xml - classpath:/org/olat/core/commons/services/_spring/servicesCorecontext.xml + classpath:/org/olat/core/commons/services/tagging/_spring/taggingContext.xml + classpath:/org/olat/core/commons/services/_spring/servicesCorecontext.xml classpath:/serviceconfig/org/olat/core/gui/components/form/flexible/impl/elements/richText/_spring/richTextCorecontext.xml classpath:/serviceconfig/org/olat/core/commons/scheduler/_spring/schedulerCorecontext.xml -- GitLab