package org.xmind.cathy.internal;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Inject;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.EventTopic;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.model.application.ui.menu.MItem;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.actions.ActionFactory;
import org.osgi.service.event.Event;
public class CommandLabelUpdater implements IPropertyChangeListener {
private static final int TEXT = 1 << 1;
private static final int TOOLTIP = 1 << 2;
private static final String DATA_ORIGINAL_TEXT = "CommandLabelUpdater:OriginalText"; //$NON-NLS-1$
private static final String DATA_ORIGINAL_TOOLTIP = "CommandLabelUpdater:OriginalTooltip"; //$NON-NLS-1$
@Inject
private EModelService modelService;
private MWindow activeWindow = null;
private IActionBars activeActionBars = null;
private Set<IAction> trackedHandlers = null;
@Inject
@Optional
public void applicationStarted(
@EventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) {
}
@Inject
@Optional
public void activePartChanged(
@EventTopic(UIEvents.UILifeCycle.ACTIVATE) Event event) {
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (!(element instanceof MPart))
return;
MPart part = (MPart) element;
MWindow window = findWindowFor(part);
if (window == null)
return;
partActivated(part, window);
}
private void partActivated(MPart part, MWindow window) {
IWorkbenchWindow ww = window.getContext().get(IWorkbenchWindow.class);
IActionBars actionBars = findActionBars(ww);
this.activeWindow = window;
if (actionBars != this.activeActionBars) {
if (this.activeActionBars instanceof SubActionBars) {
((SubActionBars) this.activeActionBars)
.removePropertyChangeListener(this);
}
this.activeActionBars = actionBars;
if (this.activeActionBars instanceof SubActionBars) {
((SubActionBars) this.activeActionBars)
.addPropertyChangeListener(this);
}
updateAllItemLabels();
}
}
private void updateAllItemLabels() {
if (activeWindow == null)
return;
Set<IAction> oldTrackedHandlers = this.trackedHandlers;
Set<IAction> newTrackedHandlers = new HashSet<IAction>();
updateItemLabel(activeActionBars, activeWindow.getMainMenu(),
ICathyConstants.ID_MENU_ITEM_UNDO, ActionFactory.UNDO.getId(),
ActionFactory.UNDO.getCommandId(), TEXT, newTrackedHandlers);
updateItemLabel(activeActionBars, activeWindow.getMainMenu(),
ICathyConstants.ID_MENU_ITEM_REDO, ActionFactory.REDO.getId(),
ActionFactory.REDO.getCommandId(), TEXT, newTrackedHandlers);
updateItemLabel(activeActionBars, activeWindow,
ICathyConstants.ID_TOOL_ITEM_UNDO, ActionFactory.UNDO.getId(),
ActionFactory.UNDO.getCommandId(), TOOLTIP, newTrackedHandlers);
updateItemLabel(activeActionBars, activeWindow,
ICathyConstants.ID_TOOL_ITEM_REDO, ActionFactory.REDO.getId(),
ActionFactory.REDO.getCommandId(), TOOLTIP, newTrackedHandlers);
this.trackedHandlers = newTrackedHandlers;
if (oldTrackedHandlers != null) {
for (IAction handler : oldTrackedHandlers) {
if (!newTrackedHandlers.contains(handler)) {
handler.removePropertyChangeListener(this);
}
}
}
for (IAction handler : newTrackedHandlers) {
if (oldTrackedHandlers == null
|| !oldTrackedHandlers.contains(handler)) {
handler.addPropertyChangeListener(this);
}
}
}
private void updateItemLabel(IActionBars actionBars, MUIElement topElement,
String itemId, String actionId, String commandId, int attributes,
Set<IAction> handlers) {
if (modelService == null || topElement == null)
return;
MUIElement element = modelService.find(itemId, topElement);
if (!(element instanceof MItem))
return;
MItem item = (MItem) element;
IAction handler = actionBars == null ? null
: actionBars.getGlobalActionHandler(actionId);
if ((attributes & TEXT) != 0) {
String text = handler == null ? null : handler.getText();
if (text != null) {
if (!item.getTransientData().containsKey(DATA_ORIGINAL_TEXT)) {
item.getTransientData().put(DATA_ORIGINAL_TEXT,
item.getLabel());
}
item.setLabel(text);
} else {
Object originalText = item.getTransientData()
.get(DATA_ORIGINAL_TEXT);
if (originalText != null && originalText instanceof String) {
item.setLabel((String) originalText);
}
}
}
if ((attributes & TOOLTIP) != 0) {
String tooltip = handler == null ? null : handler.getToolTipText();
if (tooltip != null) {
if (!item.getTransientData()
.containsKey(DATA_ORIGINAL_TOOLTIP)) {
item.getTransientData().put(DATA_ORIGINAL_TOOLTIP,
item.getTooltip());
}
item.setTooltip(tooltip);
} else {
Object originalTooltip = item.getTransientData()
.get(DATA_ORIGINAL_TOOLTIP);
if (originalTooltip != null
&& originalTooltip instanceof String) {
item.setTooltip((String) originalTooltip);
}
}
}
}
private MWindow findWindowFor(MUIElement element) {
if (element == null)
return null;
if (element instanceof MWindow)
return (MWindow) element;
MPlaceholder placeholder = element.getCurSharedRef();
if (placeholder != null)
return findWindowFor(placeholder);
MUIElement parent = element.getParent();
if (parent != null)
return findWindowFor(parent);
return null;
}
private IActionBars findActionBars(IWorkbenchWindow window) {
if (window == null)
return null;
IWorkbenchPage page = window.getActivePage();
if (page == null)
return null;
IWorkbenchPart activePart = page.getActivePart();
if (activePart == null)
return null;
IWorkbenchPartSite site = activePart.getSite();
if (site instanceof IEditorSite)
return ((IEditorSite) site).getActionBars();
if (site instanceof IViewSite)
return ((IViewSite) site).getActionBars();
return null;
}
public void propertyChange(PropertyChangeEvent event) {
updateAllItemLabels();
}
}