From 33a00f6bea2fe68a7b34ef3305af78b43178afb5 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Fri, 18 Jul 2014 17:24:16 +0200
Subject: [PATCH] OO-990: refined handling of changed and published event for
 course visitors

---
 .../java/org/olat/catalog/CatalogManager.java |   3 +-
 .../components/stack/TooledStackedPanel.java  |   2 +-
 .../stack/TooledStackedPanelRenderer.java     |   4 +-
 .../java/org/olat/course/CourseFactory.java   |   2 +-
 .../olat/course/config/CourseConfigEvent.java |  32 ++--
 .../config/ui/CourseCalendarConfigForm.java   |   6 +-
 .../ui/CourseEfficencyStatementForm.java      |   3 +-
 .../course/editor/EditorMainController.java   |   3 +-
 .../org/olat/course/editor/PublishEvent.java  |  45 ++---
 .../olat/course/editor/PublishProcess.java    |  10 +-
 .../olat/course/run/RunMainController.java    | 155 +++++++++++++-----
 .../controllers/EntryChangedEvent.java        |  52 +++---
 .../RepositorySearchController.java           |   5 +-
 .../ui/author/AuthorListController.java       |   3 +-
 .../author/AuthoringEditAccessController.java |   5 +-
 .../AuthoringEntryDetailsController.java      |   5 +-
 .../CreateRepositoryEntryController.java      |   3 +-
 17 files changed, 214 insertions(+), 124 deletions(-)

diff --git a/src/main/java/org/olat/catalog/CatalogManager.java b/src/main/java/org/olat/catalog/CatalogManager.java
index 35d7c319081..1e29e4bd57a 100644
--- a/src/main/java/org/olat/catalog/CatalogManager.java
+++ b/src/main/java/org/olat/catalog/CatalogManager.java
@@ -60,6 +60,7 @@ import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.user.UserDataDeletable;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -657,7 +658,7 @@ public class CatalogManager extends BasicManager implements UserDataDeletable, I
 	public void updateReferencedRepositoryEntry(RepositoryEntry re) {
 		RepositoryEntry reloaded = repositoryManager.setDescriptionAndName(re, re.getDisplayname(), re.getDescription());
 		// inform anybody interested about this change
-		MultiUserEvent modifiedEvent = new EntryChangedEvent(reloaded, EntryChangedEvent.MODIFIED_DESCRIPTION);
+		MultiUserEvent modifiedEvent = new EntryChangedEvent(reloaded, null, Change.modifiedDescription);
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, reloaded);
 	}
 	
diff --git a/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanel.java b/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanel.java
index c047b9e8db4..7b441e4a84d 100644
--- a/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanel.java
+++ b/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanel.java
@@ -72,7 +72,7 @@ public class TooledStackedPanel extends BreadcrumbedStackedPanel implements Stac
 	protected BreadCrumb createCrumb(Controller controller) {
 		return new TooledBreadCrumb(controller);
 	}
-	
+
 	/**
 	 * If the component is null, it will simply not be added,
 	 * @param toolComponent
diff --git a/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanelRenderer.java b/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanelRenderer.java
index 554470f0857..68b3666b8f9 100644
--- a/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanelRenderer.java
+++ b/src/main/java/org/olat/core/gui/components/stack/TooledStackedPanelRenderer.java
@@ -115,13 +115,13 @@ public class TooledStackedPanelRenderer extends DefaultComponentRenderer {
 		List<Tool> alignedTools = new ArrayList<>(tools.size());
 		if(alignement == null) {
 			for(Tool tool:tools) {
-				if(tool.getAlign() == null) {
+				if(tool.getAlign() == null && tool.getComponent().isVisible()) {
 					alignedTools.add(tool);
 				}
 			}
 		} else {
 			for(Tool tool:tools) {
-				if(alignement.equals(tool.getAlign())) {
+				if(alignement.equals(tool.getAlign()) && tool.getComponent().isVisible()) {
 					alignedTools.add(tool);
 				}
 			}
diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java
index 6a4d77ddebf..3fe66fd49d7 100644
--- a/src/main/java/org/olat/course/CourseFactory.java
+++ b/src/main/java/org/olat/course/CourseFactory.java
@@ -745,7 +745,7 @@ public class CourseFactory extends BasicManager {
 		 //RepositoryEntry.ACC_OWNERS_AUTHORS //only owners and authors can the see course
 		 //RepositoryEntry.ACC_USERS_GUESTS // users and guests can see the course
 		 //fxdiff VCRP-1,2: access control of resources
-		 publishProcess.changeGeneralAccess(newAccess, membersOnly);
+		 publishProcess.changeGeneralAccess(identity, newAccess, membersOnly);
 		 
 		 if (publishTreeModel.hasPublishableChanges()) {
 			 List<String>nodeToPublish = new ArrayList<String>();
diff --git a/src/main/java/org/olat/course/config/CourseConfigEvent.java b/src/main/java/org/olat/course/config/CourseConfigEvent.java
index fe83f40c4fe..d888adeb746 100644
--- a/src/main/java/org/olat/course/config/CourseConfigEvent.java
+++ b/src/main/java/org/olat/course/config/CourseConfigEvent.java
@@ -38,23 +38,27 @@ import org.olat.core.util.event.MultiUserEvent;
 public class CourseConfigEvent extends MultiUserEvent {
 
 	private static final long serialVersionUID = 7362131099407009869L;
-	public static final String EFFICIENCY_STATEMENT_TYPE = "efficiency";
-	public static final String CALENDAR_TYPE = "calendar";
-	public static final String LAYOUT_TYPE = "css";
-	
-	private final Long ResourceableId;
+
+	private final Long resourceableId;
+	private final CourseConfigType type;
 	
-	/**
-	 * The command should be one of the above defined: EFFICIENCY_STATEMENT_TYPE, CALENDAR_TYPE, LAYOUT_TYPE, etc.
-	 * @param command
-	 */
-	public CourseConfigEvent(String command, Long resourceableId) {
-		super(command);	
-		this.ResourceableId = resourceableId;
+	public CourseConfigEvent(CourseConfigType type, Long resourceableId) {
+		super(type.name());	
+		this.type = type;
+		this.resourceableId = resourceableId;
 	}
 
 	public Long getResourceableId() {
-		return ResourceableId;
+		return resourceableId;
+	}
+	
+	public CourseConfigType getType() {
+		return type;
+	}
+	
+	public static enum CourseConfigType {
+		efficiencyStatement,
+		calendar,
+		layout
 	}
-
 }
diff --git a/src/main/java/org/olat/course/config/ui/CourseCalendarConfigForm.java b/src/main/java/org/olat/course/config/ui/CourseCalendarConfigForm.java
index 302221ac7c1..61900c94cc6 100644
--- a/src/main/java/org/olat/course/config/ui/CourseCalendarConfigForm.java
+++ b/src/main/java/org/olat/course/config/ui/CourseCalendarConfigForm.java
@@ -37,6 +37,8 @@ import org.olat.core.util.resource.OresHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
 import org.olat.course.config.CourseConfig;
+import org.olat.course.config.CourseConfigEvent;
+import org.olat.course.config.CourseConfigEvent.CourseConfigType;
 
 /**
  * 
@@ -102,7 +104,9 @@ public class CourseCalendarConfigForm extends FormBasicController {
 		ThreadLocalUserActivityLogger.log(loggingAction, getClass());
         CoordinatorManager.getInstance().getCoordinator().getEventBus()
         	.fireEventToListenersOf(new KalendarModifiedEvent(), OresHelper.lookupType(CalendarManager.class));
-				
+        CoordinatorManager.getInstance().getCoordinator().getEventBus()
+        	.fireEventToListenersOf(new CourseConfigEvent(CourseConfigType.calendar, course.getResourceableId()), course);
+		
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/config/ui/CourseEfficencyStatementForm.java b/src/main/java/org/olat/course/config/ui/CourseEfficencyStatementForm.java
index a11fe769995..b3e63c0b601 100644
--- a/src/main/java/org/olat/course/config/ui/CourseEfficencyStatementForm.java
+++ b/src/main/java/org/olat/course/config/ui/CourseEfficencyStatementForm.java
@@ -49,6 +49,7 @@ import org.olat.course.ICourse;
 import org.olat.course.assessment.EfficiencyStatementManager;
 import org.olat.course.config.CourseConfig;
 import org.olat.course.config.CourseConfigEvent;
+import org.olat.course.config.CourseConfigEvent.CourseConfigType;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 /**
@@ -150,7 +151,7 @@ public class CourseEfficencyStatementForm extends FormBasicController {
 		}
 		//inform everybody else		
 		EventBus eventBus = CoordinatorManager.getInstance().getCoordinator().getEventBus();
-		CourseConfigEvent courseConfigEvent = new CourseConfigEvent(CourseConfigEvent.EFFICIENCY_STATEMENT_TYPE, course.getResourceableId());
+		CourseConfigEvent courseConfigEvent = new CourseConfigEvent(CourseConfigType.efficiencyStatement, course.getResourceableId());
 		eventBus.fireEventToListenersOf(courseConfigEvent, course);
 		ThreadLocalUserActivityLogger.log(loggingAction, getClass());
 	}
diff --git a/src/main/java/org/olat/course/editor/EditorMainController.java b/src/main/java/org/olat/course/editor/EditorMainController.java
index e20f31c13b3..0408c508a72 100644
--- a/src/main/java/org/olat/course/editor/EditorMainController.java
+++ b/src/main/java/org/olat/course/editor/EditorMainController.java
@@ -233,7 +233,6 @@ public class EditorMainController extends MainLayoutBasicController implements G
 		} else {
 			ICourse course = CourseFactory.openCourseEditSession(ores.getResourceableId());
 			main = createVelocityContainer("index");
-			main.setDomReplacementWrapperRequired(false); // we provide our own DOM replacement ID
 			
 			OLATResourceable courseOres = OresHelper.createOLATResourceableInstance("CourseModule", ores.getResourceableId());
 			RepositoryEntry repo = RepositoryManager.getInstance().lookupRepositoryEntry(courseOres, false);
@@ -1074,7 +1073,7 @@ public class EditorMainController extends MainLayoutBasicController implements G
 					
 					// fires an EntryChangedEvent for repository entry notifying
 					// about modification.
-					publishManager.changeGeneralAccess(newAccess, membersOnly);
+					publishManager.changeGeneralAccess(getIdentity(), newAccess, membersOnly);
 					hasChanges = true;
 				}
 				
diff --git a/src/main/java/org/olat/course/editor/PublishEvent.java b/src/main/java/org/olat/course/editor/PublishEvent.java
index 78e17aefd30..214756e3ab2 100644
--- a/src/main/java/org/olat/course/editor/PublishEvent.java
+++ b/src/main/java/org/olat/course/editor/PublishEvent.java
@@ -27,6 +27,7 @@ package org.olat.course.editor;
 
 import java.util.Set;
 
+import org.olat.basesecurity.IdentityRef;
 import org.olat.core.util.event.MultiUserEvent;
 import org.olat.course.ICourse;
 
@@ -39,11 +40,10 @@ public class PublishEvent extends MultiUserEvent {
 	private static final long serialVersionUID = 7105017036750676773L;
 	public final static int PRE_PUBLISH =0;
 	public final static int PUBLISH = 1;
-	//TODO: LD: temporary introduced, for the purpose of identifying the source of the event (same VM or another cluster node)
+
 	public final static String EVENT_IDENTIFIER = "usedForInstanceComparison";
 
-	//FIXME:fj:c: make serializable / remove unneeded methods and info
-	long pubtimestamp;
+	private Long authorKey;
 	private Long publishedCourseResId;
 	
 	private Set<String> insertedCourseNodeIds;
@@ -58,24 +58,20 @@ public class PublishEvent extends MultiUserEvent {
 	 * @param publishedCourse
 	 * @param eventIdentifier is EVENT_IDENTIFIER
 	 */
-	public PublishEvent(long pubtimestamp, ICourse publishedCourse, String eventIdentifier) {
-		super(eventIdentifier);
-		this.pubtimestamp = pubtimestamp;
-		this.publishedCourseResId = publishedCourse.getResourceableId();
+	public PublishEvent(ICourse publishedCourse, IdentityRef author) {
+		super(EVENT_IDENTIFIER);
+		authorKey = author == null ? null : author.getKey();
+		publishedCourseResId = publishedCourse.getResourceableId();
 	}
 	
-	public int getState(){
-		return this.state;
+	public int getState() {
+		return state;
 	}
 	
 	public void setState(int publishState){
 		this.state = publishState;
 	}
 	
-	public long getLatestPublishTimestamp() {
-		return pubtimestamp;
-	}
-	
 	public Set<String> getInsertedCourseNodeIds() {
 		return insertedCourseNodeIds;
 	}
@@ -88,6 +84,10 @@ public class PublishEvent extends MultiUserEvent {
 		return modifiedCourseNodeIds;
 	}
 	
+	public Long getAuthorKey() {
+		return authorKey;
+	}
+
 	/**
 	 * @return Returns the key of the publishedCourse.
 	 */
@@ -95,16 +95,23 @@ public class PublishEvent extends MultiUserEvent {
 		return publishedCourseResId;
 	}
 	
-	void setInsertedCourseNodeIds(Set<String> nodeIds) { insertedCourseNodeIds = nodeIds; }
-	void setDeletedCourseNodeIds(Set<String> nodeIds) { deletedCourseNodeIds = nodeIds; }
-	void setModifiedCourseNodeIds(Set<String> nodeIds) { modifiedCourseNodeIds = nodeIds; }
+	void setInsertedCourseNodeIds(Set<String> nodeIds) { 
+		insertedCourseNodeIds = nodeIds;
+	}
+	
+	void setDeletedCourseNodeIds(Set<String> nodeIds) {
+		deletedCourseNodeIds = nodeIds;
+	}
+	
+	void setModifiedCourseNodeIds(Set<String> nodeIds) {
+		modifiedCourseNodeIds = nodeIds;
+	}
 	
 	/**
 	 * Use command as event identifier.
 	 * @return
 	 */
 	public String getEventIdentifier() {
-		return this.getCommand();
+		return getCommand();
 	}
-	
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/editor/PublishProcess.java b/src/main/java/org/olat/course/editor/PublishProcess.java
index 4ba4bd58f7a..b87be10e744 100644
--- a/src/main/java/org/olat/course/editor/PublishProcess.java
+++ b/src/main/java/org/olat/course/editor/PublishProcess.java
@@ -73,6 +73,7 @@ import org.olat.properties.Property;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.resource.references.ReferenceImpl;
 import org.olat.resource.references.ReferenceManager;
 import org.olat.user.UserManager;
@@ -406,7 +407,7 @@ public class PublishProcess {
 		/*
 		 * broadcast PRE PUBLISH event that a publish will take place
 		 */
-		PublishEvent beforePublish = new PublishEvent(editorTreeModel.getLatestPublishTimestamp(), course, PublishEvent.EVENT_IDENTIFIER);
+		PublishEvent beforePublish = new PublishEvent(course, identity);
 		beforePublish.setDeletedCourseNodeIds(deletedCourseNodeIds);
 		beforePublish.setInsertedCourseNodeIds(insertedCourseNodeIds);
 		beforePublish.setModifiedCourseNodeIds(modifiedCourseNodeIds);
@@ -493,7 +494,7 @@ public class PublishProcess {
 		/*
 		 * broadcast event
 		 */
-		PublishEvent publishEvent = new PublishEvent(pubtimestamp, course, PublishEvent.EVENT_IDENTIFIER);
+		PublishEvent publishEvent = new PublishEvent(course, identity);
 		publishEvent.setDeletedCourseNodeIds(deletedCourseNodeIds);
 		publishEvent.setInsertedCourseNodeIds(insertedCourseNodeIds);
 		publishEvent.setModifiedCourseNodeIds(modifiedCourseNodeIds);
@@ -504,7 +505,6 @@ public class PublishProcess {
 		/*
 		 * END NEW STYLE PUBLISH
 		 */
-
 	}
 	
 	public void applyUpdateSet(Identity identity, Locale locale) {
@@ -700,9 +700,9 @@ public class PublishProcess {
 		return publishTreeModel;
 	}
 
-	public void changeGeneralAccess(int access, boolean membersOnly){
+	public void changeGeneralAccess(Identity author, int access, boolean membersOnly){
 		RepositoryManager.getInstance().setAccess(repositoryEntry, access, membersOnly);
-		MultiUserEvent modifiedEvent = new EntryChangedEvent(repositoryEntry, EntryChangedEvent.MODIFIED_AT_PUBLISH);
+		MultiUserEvent modifiedEvent = new EntryChangedEvent(repositoryEntry, author, Change.modifiedAtPublish);
 		CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, repositoryEntry);
 	}
 	
diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java
index aa44612f93f..7be67c0541e 100644
--- a/src/main/java/org/olat/course/run/RunMainController.java
+++ b/src/main/java/org/olat/course/run/RunMainController.java
@@ -29,6 +29,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.olat.NewControllerFactory;
@@ -193,7 +194,8 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 
 	private CourseNode currentCourseNode;
 	private TreeModel treeModel;
-	private boolean needsRebuildAfterPublish;
+	private boolean needsRebuildAfter = false;
+	private boolean needsRebuildAfterPublish = false;
 	private boolean needsRebuildAfterRunDone = false;
 	
 	private String courseTitle;
@@ -409,6 +411,10 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 		courseRightsCache.put(CourseRights.RIGHT_STATISTICS, new Boolean(rights.contains(CourseRights.RIGHT_STATISTICS)));
 		courseRightsCache.put(CourseRights.RIGHT_DB, new Boolean(rights.contains(CourseRights.RIGHT_DB)));
 	}
+	
+	private void updateAfterChanges(UserRequest ureq, CourseNode currentCourseNode) {
+		
+	}
 
 	/**
 	 * side-effecty to content and luTree
@@ -455,7 +461,6 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 		currentNodeController = nclr.getRunController();
 		addToHistory(ureq, currentNodeController);
 		
-		//fxdiff BAKS-7 Resume function
 		if (currentNodeController instanceof TitledWrapperController) {
 			Controller contentcontroller = ((TitledWrapperController)currentNodeController).getContentController();
 			addToHistory(ureq, contentcontroller);
@@ -466,7 +471,6 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 			((Activateable2)currentNodeController).activate(ureq, entries, state);
 		}
 		contentP.setContent(currentNodeController.getInitialComponent());
-		// enableCustomCourseCSS(ureq);
 		
 		return true;
 	}
@@ -478,6 +482,11 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 	 */
 	@Override
 	public void event(UserRequest ureq, Component source, Event event) {
+		if(needsRebuildAfter) {
+			updateAfterChanges(ureq, currentCourseNode);
+			needsRebuildAfter = false;
+		}
+		
 		if(runLink == source) {
 			toolbarPanel.popUpToRootController(ureq);
 			currentToolCtr = null;
@@ -582,6 +591,10 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 	 */
 	@Override
 	public void event(UserRequest ureq, Controller source, Event event) {
+		if(needsRebuildAfter) {
+			updateAfterChanges(ureq, currentCourseNode);
+			needsRebuildAfter = false;
+		}
 		
 		// event from the current tool (editor, groupmanagement, archiver)		
 		if (source == currentToolCtr) {
@@ -980,24 +993,9 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 	@Override
 	public void event(Event event) {	
 		if (event instanceof PublishEvent) {
-			PublishEvent pe = (PublishEvent) event;
-			// so far not interested in PRE PUBLISH event, but one could add user
-			// and the currently active BB information. This in turn could be used 
-			// by the publish event issuer to decide whether or not to publish...
-			//check if it's the right course
-			if (pe.getState() != PublishEvent.PRE_PUBLISH
-					&& course.getResourceableId().equals(pe.getPublishedCourseResId())) {
-				// disable this controller and issue a information
-				if (isInEditor) {
-					needsRebuildAfterPublish = true;
-					// author went in editor and published the course -> raise a flag to
-					// later prepare the new
-					// course to present him/her a nice view when
-					// he/she closes the editor to return to the run main (this controller)
-				} else {
-					//TODO
-					//doDisposeAfterEvent();
-				}
+			PublishEvent pe = (PublishEvent)event;
+			if(course.getResourceableId().equals(pe.getPublishedCourseResId())) {
+				processPublishEvent(pe);
 			}
 		} else if (event instanceof OLATResourceableJustBeforeDeletedEvent) {
 			OLATResourceableJustBeforeDeletedEvent ojde = (OLATResourceableJustBeforeDeletedEvent) event;
@@ -1024,7 +1022,6 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 						UserEfficiencyStatement es = efficiencyStatementManager
 							.getUserEfficiencyStatementLight(courseRepositoryEntry.getKey(), identity);
 						efficiencyStatementsLink.setEnabled(es != null);
-						efficiencyStatementsLink.setPopup(true);//"750", "800"
 					}
 				}
 				// raise a flag to indicate refresh
@@ -1034,11 +1031,10 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 			processBusinessGroupModifiedEvent((BusinessGroupModifiedEvent)event);
 		} else if (event instanceof CourseConfigEvent) {				
 			processCourseConfigEvent((CourseConfigEvent)event);
-		} else if (event instanceof EntryChangedEvent && ((EntryChangedEvent)event).getChange()!=EntryChangedEvent.MODIFIED_AT_PUBLISH) {
-			//courseRepositoryEntry changed (e.g. fired at course access rule change)
-			EntryChangedEvent repoEvent = (EntryChangedEvent) event;			
-			if (courseRepositoryEntry.getKey().equals(repoEvent.getChangedEntryKey()) && repoEvent.getChange() == EntryChangedEvent.MODIFIED) {				
-				doDisposeAfterEvent();
+		} else if (event instanceof EntryChangedEvent ) {
+			EntryChangedEvent repoEvent = (EntryChangedEvent) event;
+			if (courseRepositoryEntry.getKey().equals(repoEvent.getChangedEntryKey())) {
+				processEntryChangedEvent(repoEvent);
 			}
 		//All events are MultiUserEvent, check with command at the end
 		} else if (event instanceof MultiUserEvent) {
@@ -1048,11 +1044,88 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 		} 
 	}
 	
+	private void processPublishEvent(PublishEvent pe) {
+		if (pe.getState() == PublishEvent.PRE_PUBLISH) {
+			// so far not interested in PRE PUBLISH event, but one could add user
+			// and the currently active BB information. This in turn could be used 
+			// by the publish event issuer to decide whether or not to publish...
+		} else if (pe.getState() == PublishEvent.PUBLISH) {
+			// disable this controller and issue a information
+			if (isInEditor) {
+				needsRebuildAfterPublish = true;
+				// author went in editor and published the course -> raise a flag to
+				// later prepare the new
+				// course to present him/her a nice view when
+				// he/she closes the editor to return to the run main (this controller)
+			} else if(getIdentity().getKey().equals(pe.getAuthorKey())) {
+				//do nothing
+			} else {
+				if(currentCourseNode == null) {
+					needsRebuildAfter = true;
+				} else {
+					try {
+						String currentNodeIdent = currentCourseNode.getIdent();
+						Set<String> deletedNodeIds = pe.getDeletedCourseNodeIds();
+						Set<String> modifiedNodeIds = pe.getModifiedCourseNodeIds();
+						
+						if(deletedNodeIds != null && deletedNodeIds.contains(currentNodeIdent)) {
+							doDisposeAfterEvent();
+						} else if(modifiedNodeIds != null && modifiedNodeIds.contains(currentNodeIdent)) {
+							doDisposeAfterEvent();
+						}
+					} catch (Exception e) {
+						logError("", e);
+						//beyond update, be paranoid
+						doDisposeAfterEvent();
+					}
+				}
+			}
+		}
+	}
+	
+	private void processEntryChangedEvent(EntryChangedEvent repoEvent) {
+		switch(repoEvent.getChange()) {
+			case modifiedAtPublish:
+			case modifiedAccess:
+				if(repoEvent.getAuthorKey() == null || !getIdentity().getKey().equals(repoEvent.getAuthorKey())) {
+					doDisposeAfterEvent();
+				} 
+				break;
+			case deleted:
+				doDisposeAfterEvent();
+				break;
+			default: {}
+		}
+	}
+	
 	private void processCourseConfigEvent(CourseConfigEvent event) {
-		String cmd = event.getCommand();
-		System.out.println(cmd);
-		
-		doDisposeAfterEvent();
+		switch(event.getType()) {
+			case calendar: {
+				if(calendarLink != null) {
+					CourseConfig cc = uce.getCourseEnvironment().getCourseConfig();
+					calendarLink.setVisible(cc.isCalendarEnabled());
+					toolbarPanel.setDirty(true);
+				}
+				break;
+			}
+			case efficiencyStatement: {
+				if(efficiencyStatementsLink != null) {
+					CourseConfig cc = uce.getCourseEnvironment().getCourseConfig();
+					efficiencyStatementsLink.setVisible(cc.isEfficencyStatementEnabled());
+					if(cc.isEfficencyStatementEnabled()) {
+						UserEfficiencyStatement es = efficiencyStatementManager
+								.getUserEfficiencyStatementLight(courseRepositoryEntry.getKey(), getIdentity());
+						efficiencyStatementsLink.setEnabled(es != null);
+					}
+					toolbarPanel.setDirty(true);
+				}
+				break;
+			}
+			case layout: {
+				//don't restart for that
+				break;
+			}
+		}
 	}
 	
 	private void processBusinessGroupModifiedEvent(BusinessGroupModifiedEvent bgme) {
@@ -1235,9 +1308,10 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 			detailsLink = LinkFactory.createToolLink("courseconfig",translate("command.courseconfig"), this, "o_icon_details");
 			toolbarPanel.addTool(detailsLink);
 		}		
-		if (cc.isCalendarEnabled() && !isGuest) {
+		if (!isGuest) {
 			calendarLink = LinkFactory.createToolLink("calendar",translate("command.calendar"), this, "o_icon_calendar");
 			calendarLink.setPopup(new LinkPopupSettings(950, 750, "cal"));
+			calendarLink.setVisible(cc.isCalendarEnabled());
 			toolbarPanel.addTool(calendarLink);
 		}
 		if (cc.hasGlossary()) {
@@ -1252,13 +1326,8 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 			toolbarPanel.addTool(chatLink);
 		}
 		
-		if (CourseModule.displayParticipantsCount() && !isGuest) {
-			//TODO toolbox
-			//addCurrentUserCount(myTool);
-		}
-		
 		// Personal tools on right side
-		if (cc.isEfficencyStatementEnabled() && course.hasAssessableNodes() && !isGuest) {
+		if (course.hasAssessableNodes() && !isGuest) {
 			// link to efficiency statements should
 			// - not appear when not configured in course configuration
 			// - not appear when configured in course configuration but no assessable
@@ -1269,12 +1338,12 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 			// data exists for user
 			efficiencyStatementsLink = LinkFactory.createToolLink("efficiencystatement",translate("command.efficiencystatement"), this, "o_icon_certificate");
 			efficiencyStatementsLink.setPopup(new LinkPopupSettings(750, 800, "eff"));
+			efficiencyStatementsLink.setVisible(cc.isEfficencyStatementEnabled());
 			toolbarPanel.addTool(efficiencyStatementsLink, Align.right);
-			
-			UserEfficiencyStatement es = efficiencyStatementManager
-					.getUserEfficiencyStatementLight(courseRepositoryEntry.getKey(), getIdentity());
-			if (es == null) {
-				efficiencyStatementsLink.setEnabled(false);
+			if(cc.isEfficencyStatementEnabled()) {
+				UserEfficiencyStatement es = efficiencyStatementManager
+						.getUserEfficiencyStatementLight(courseRepositoryEntry.getKey(), getIdentity());
+				efficiencyStatementsLink.setEnabled(es != null);
 			}
 		}
 		
diff --git a/src/main/java/org/olat/repository/controllers/EntryChangedEvent.java b/src/main/java/org/olat/repository/controllers/EntryChangedEvent.java
index 6ff27631455..c96f9c12002 100644
--- a/src/main/java/org/olat/repository/controllers/EntryChangedEvent.java
+++ b/src/main/java/org/olat/repository/controllers/EntryChangedEvent.java
@@ -25,6 +25,7 @@
 
 package org.olat.repository.controllers;
 
+import org.olat.basesecurity.IdentityRef;
 import org.olat.core.util.event.MultiUserEvent;
 import org.olat.repository.RepositoryEntry;
 
@@ -36,28 +37,9 @@ import org.olat.repository.RepositoryEntry;
 public class EntryChangedEvent extends MultiUserEvent {
 
 	private static final long serialVersionUID = 8339474599787388699L;
-	private int change;
+	private Change change;
 	private Long changedEntryKey;
-	
-	/**
-	 * Entry modified status.
-	 */
-	public static final int MODIFIED = 0;
-	/**
-	 * Entry added status.
-	 */
-	public static final int ADDED = 1;
-	/**
-	 * Entry deleted status.
-	 */
-	public static final int DELETED = 2;
-	
-	/**
-	 * Entry description modified status.
-	 */
-	public static final int MODIFIED_DESCRIPTION = 3;
-	
-	public static final int MODIFIED_AT_PUBLISH = 4;
+	private Long authorKey;
 	
 	/**
 	 * Event signaling the change of a repository entry. Use getChange to see the status of the change.
@@ -65,21 +47,41 @@ public class EntryChangedEvent extends MultiUserEvent {
 	 * @param changedEntry
 	 * @param change
 	 */
-	public EntryChangedEvent(RepositoryEntry changedEntry, int change) {
+	public EntryChangedEvent(RepositoryEntry changedEntry, IdentityRef identity, Change change) {
 		super("");
-		this.changedEntryKey = changedEntry.getKey();
+		changedEntryKey = changedEntry.getKey();
+		authorKey = identity == null ? null : identity.getKey();
 		this.change = change;
 	}
 	
 	/**
 	 * @return the key of the repository entry that has been changed.
 	 */
-	public Long getChangedEntryKey() { return changedEntryKey; }
+	public Long getChangedEntryKey() {
+		return changedEntryKey;
+	}
 	
+	/**
+	 * The author of the change
+	 * @return
+	 */
+	public Long getAuthorKey() {
+		return authorKey;
+	}
+
 	/**
 	 * Get the type of change.
 	 * @return type of change.
 	 */
-	public int getChange() { return change; }
+	public Change getChange() {
+		return change;
+	}
 	
+	public static enum Change {
+		added,
+		deleted,
+		modifiedAccess,
+		modifiedDescription,
+		modifiedAtPublish
+	}
 }
diff --git a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java
index 0b668fc3d0f..d3043a5437d 100644
--- a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java
+++ b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java
@@ -60,6 +60,7 @@ import org.olat.core.util.Util;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.repository.model.SearchRepositoryEntryParameters;
 import org.olat.repository.ui.RepositoryTableModel;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -589,7 +590,7 @@ public class RepositorySearchController extends BasicController implements Activ
 		} 
 		else if (event instanceof EntryChangedEvent) { // remove deleted entry
 			EntryChangedEvent ecv = (EntryChangedEvent)event;
-			if (ecv.getChange() == EntryChangedEvent.DELETED) {
+			if (ecv.getChange() == Change.deleted) {
 				List<RepositoryEntry> newEntries = new ArrayList<RepositoryEntry>();
 				for (int i = 0; i < repoTableModel.getRowCount(); i++) {
 					RepositoryEntry foo = repoTableModel.getObject(i);
@@ -598,7 +599,7 @@ public class RepositorySearchController extends BasicController implements Activ
 				}
 				repoTableModel.setObjects(newEntries);
 				tableCtr.modelChanged();
-			} else if (ecv.getChange() == EntryChangedEvent.ADDED) {
+			} else if (ecv.getChange() == Change.added) {
 				doSearchByOwner(urequest.getIdentity());
 			}
 		}	else if (source == searchForm) { // process search form events
diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
index f9ff1ff2fe2..7c11383245b 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java
@@ -80,6 +80,7 @@ import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.repository.handlers.RepositoryHandlerFactory;
 import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams;
@@ -345,7 +346,7 @@ public class AuthorListController extends FormBasicController implements Activat
 				dirtyRows.add(new Integer(-1));
 			} else if(event instanceof EntryChangedEvent) {
 				EntryChangedEvent ce = (EntryChangedEvent)event;
-				if(ce.getChange() == EntryChangedEvent.DELETED) {
+				if(ce.getChange().equals(Change.deleted)) {
 					stackPanel.popUpToRootController(ureq);
 					dirtyRows.add(new Integer(-1));
 					reloadDirtyRows();
diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
index f19d9941ea4..a544c402a43 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthoringEditAccessController.java
@@ -34,6 +34,7 @@ import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.RepositoryService;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.resource.accesscontrol.ui.AccessConfigurationController;
 
 /**
@@ -112,8 +113,8 @@ public class AuthoringEditAccessController extends BasicController {
 					editproptabpubVC.remove(acCtr.getInitialComponent());
 				}
 				
-				// inform anybody interrested about this change
-				MultiUserEvent modifiedEvent = new EntryChangedEvent(entry, EntryChangedEvent.MODIFIED);
+				// inform anybody interested about this change
+				MultiUserEvent modifiedEvent = new EntryChangedEvent(entry, getIdentity(), Change.modifiedAccess);
 				CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, entry);			
 				fireEvent(ureq, Event.CHANGED_EVENT);
 			}
diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java
index c90d3555d6c..d442e0d848f 100644
--- a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java
+++ b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDetailsController.java
@@ -73,6 +73,7 @@ import org.olat.repository.RepositoryEntryManagedFlag;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.repository.controllers.WizardCloseResourceController;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.repository.handlers.RepositoryHandlerFactory;
@@ -709,15 +710,13 @@ public class AuthoringEntryDetailsController extends RepositoryEntryDetailsContr
 		}
 	}
 	
-
-	
 	private void deleteRepositoryEntry(UserRequest ureq) {
 		Roles roles = ureq.getUserSession().getRoles();
 		ErrorList errors = repositoryService.delete(entry, getIdentity(), roles, getLocale());
 		if (errors.hasErrors()) {
 			showInfo("info.could.not.delete.entry");
 		} else {
-			fireEvent(ureq, new EntryChangedEvent(entry, EntryChangedEvent.DELETED));
+			fireEvent(ureq, new EntryChangedEvent(entry, getIdentity(), Change.deleted));
 			showInfo("info.entry.deleted");
 		}
 	}
diff --git a/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java
index 9ed62099c01..bc269723884 100644
--- a/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java
+++ b/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java
@@ -41,6 +41,7 @@ import org.olat.core.util.Util;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryManager;
 import org.olat.repository.controllers.EntryChangedEvent;
+import org.olat.repository.controllers.EntryChangedEvent.Change;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.olat.util.logging.activity.LoggingResourceable;
 
@@ -139,7 +140,7 @@ public class CreateRepositoryEntryController extends FormBasicController {
 	protected void formOK(UserRequest ureq) {
 		doCreate();
 		fireEvent(ureq, Event.DONE_EVENT);
-		fireEvent(ureq, new EntryChangedEvent(addedEntry, EntryChangedEvent.ADDED));
+		fireEvent(ureq, new EntryChangedEvent(addedEntry, getIdentity(), Change.added));
 	}
 
 	@Override
-- 
GitLab