blob: 5260cc000e833e812fd7d57a713a9ffa2cd4ff53 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2014 Tasktop Technologies and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.tasks.ui;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Set;
import org.apache.commons.lang.reflect.MethodUtils;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.mylyn.commons.ui.SelectionProviderAdapter;
import org.eclipse.mylyn.internal.tasks.core.ITaskListChangeListener;
import org.eclipse.mylyn.internal.tasks.core.TaskContainerDelta;
import org.eclipse.mylyn.internal.tasks.ui.actions.RepositoryElementActionGroup;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskActivationListener;
import org.eclipse.mylyn.tasks.core.TaskActivationAdapter;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.internal.ObjectActionContributorManager;
import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
/**
* @author Mik Kersten
* @author Leo Dos Santos
*/
public class TaskTrimWidget extends WorkbenchWindowControlContribution {
public static String ID_CONTAINER = "org.eclipse.mylyn.tasks.ui.trim.container"; //$NON-NLS-1$
public static String ID_CONTROL = "org.eclipse.mylyn.tasks.ui.trim.control"; //$NON-NLS-1$
private Composite composite;
private ITask activeTask;
private MenuManager menuManager;
private Menu menu;
private TaskScalingHyperlink activeTaskLabel;
private final ITaskActivationListener taskActivationListener = new TaskActivationAdapter() {
@Override
public void taskActivated(ITask task) {
activeTask = task;
indicateActiveTask();
}
@Override
public void taskDeactivated(ITask task) {
activeTask = null;
indicateNoActiveTask();
}
};
private final ITaskListChangeListener taskListListener = new ITaskListChangeListener() {
public void containersChanged(Set<TaskContainerDelta> containers) {
// update label in case task changes
if (activeTask != null) {
for (TaskContainerDelta taskContainerDelta : containers) {
if (activeTask.equals(taskContainerDelta.getElement())) {
if (taskContainerDelta.getKind().equals(TaskContainerDelta.Kind.CONTENT)) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (activeTask != null && activeTask.isActive()) {
indicateActiveTask();
}
}
});
return;
}
}
}
}
}
};
private SelectionProviderAdapter activeTaskSelectionProvider;
private RepositoryElementActionGroup actionGroup;
public TaskTrimWidget() {
TasksUi.getTaskActivityManager().addActivationListener(taskActivationListener);
TasksUiPlugin.getTaskList().addChangeListener(taskListListener);
hookContextMenu();
}
@Override
public void dispose() {
if (composite != null && !composite.isDisposed()) {
composite.dispose();
}
composite = null;
if (menuManager != null) {
menuManager.removeAll();
menuManager.dispose();
}
menuManager = null;
if (menu != null && !menu.isDisposed()) {
menu.dispose();
}
menu = null;
actionGroup.setSelectionProvider(null);
TasksUi.getTaskActivityManager().removeActivationListener(taskActivationListener);
TasksUiPlugin.getTaskList().removeChangeListener(taskListListener);
}
@Override
protected Control createControl(Composite parent) {
composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.horizontalSpacing = 0;
layout.marginHeight = 0;
layout.marginLeft = 0;
layout.marginRight = 0;
composite.setLayout(layout);
//composite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true));
createStatusComposite(composite);
return composite;
}
private Composite createStatusComposite(final Composite container) {
GC gc = new GC(container);
Point p = gc.textExtent("WWWWWWWWWWWWWWW"); //$NON-NLS-1$
gc.dispose();
activeTaskLabel = new TaskScalingHyperlink(container, SWT.RIGHT);
// activeTaskLabel.setLayoutData(new GridData(p.x, SWT.DEFAULT));
GridData gridData = new GridData(SWT.LEFT, SWT.CENTER, false, true);
gridData.widthHint = p.x;
gridData.minimumWidth = p.x;
gridData.horizontalIndent = 0;
activeTaskLabel.setLayoutData(gridData);
activeTaskLabel.setText(Messages.TaskTrimWidget__no_task_active_);
activeTask = TasksUi.getTaskActivityManager().getActiveTask();
if (activeTask != null) {
indicateActiveTask();
}
activeTaskLabel.addMenuDetectListener(new MenuDetectListener() {
public void menuDetected(MenuDetectEvent e) {
if (menu != null) {
menu.dispose();
}
menu = menuManager.createContextMenu(container);
menu.setVisible(true);
}
});
activeTaskLabel.addHyperlinkListener(new HyperlinkAdapter() {
@Override
public void linkActivated(HyperlinkEvent e) {
TaskListView taskListView = TaskListView.getFromActivePerspective();
if (taskListView != null && taskListView.getDrilledIntoCategory() != null) {
taskListView.goUpToRoot();
}
TasksUiInternal.refreshAndOpenTaskListElement((TasksUi.getTaskActivityManager().getActiveTask()));
}
});
activeTaskLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
// only handle left clicks, context menu is handled by platform
if (e.button == 1) {
if (activeTask == null) {
return;
}
TaskListView taskListView = TaskListView.getFromActivePerspective();
if (taskListView != null && taskListView.getDrilledIntoCategory() != null) {
taskListView.goUpToRoot();
}
TasksUiInternal.refreshAndOpenTaskListElement(activeTask);
}
}
});
return activeTaskLabel;
}
private void hookContextMenu() {
activeTaskSelectionProvider = new SelectionProviderAdapter();
actionGroup = new RepositoryElementActionGroup();
actionGroup.setSelectionProvider(activeTaskSelectionProvider);
menuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuManager.setRemoveAllWhenShown(true);
menuManager.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
actionGroup.fillContextMenu(manager);
// trims do not have a workbench part so there is no simple way of registering the
// context menu
if (!contributeObjectActionsOld(manager)) {
contributeObjectActionsNew(manager);
}
}
});
}
public void indicateActiveTask() {
if (activeTaskLabel == null || activeTaskLabel.isDisposed()) {
return;
}
//activeTaskLabel.setText(shortenText(activeTask.getSummary()));
activeTaskLabel.setText(activeTask.getSummary());
activeTaskLabel.setUnderlined(true);
activeTaskLabel.setToolTipText(activeTask.getSummary());
activeTaskSelectionProvider.setSelection(new StructuredSelection(activeTask));
}
public void indicateNoActiveTask() {
if (activeTaskLabel == null || activeTaskLabel.isDisposed()) {
return;
}
activeTaskLabel.setText(Messages.TaskTrimWidget__no_active_task_);
activeTaskLabel.setUnderlined(false);
activeTaskLabel.setToolTipText(""); //$NON-NLS-1$
activeTaskSelectionProvider.setSelection(StructuredSelection.EMPTY);
}
private boolean contributeObjectActionsOld(IMenuManager manager) {
try {
MethodUtils.invokeExactMethod(ObjectActionContributorManager.getManager(), "contributeObjectActions", //$NON-NLS-1$
new Object[] { null, manager, activeTaskSelectionProvider }, new Class[] { IWorkbenchPart.class,
IMenuManager.class, ISelectionProvider.class });
} catch (NoSuchMethodException e) {
return false;
} catch (IllegalAccessException e) {
return false;
} catch (InvocationTargetException e) {
return false;
}
return true;
}
private boolean contributeObjectActionsNew(IMenuManager manager) {
try {
MethodUtils.invokeExactMethod(ObjectActionContributorManager.getManager(), "contributeObjectActions", //$NON-NLS-1$
new Object[] { null, manager, activeTaskSelectionProvider, Collections.EMPTY_SET }, new Class[] {
IWorkbenchPart.class, IMenuManager.class, ISelectionProvider.class, Set.class });
} catch (NoSuchMethodException e) {
return false;
} catch (IllegalAccessException e) {
return false;
} catch (InvocationTargetException e) {
return false;
}
return true;
}
// // From PerspectiveBarContributionItem
// private String shortenText(String taskLabel) {
// if (taskLabel == null || composite == null || composite.isDisposed()) {
// return null;
// }
//
// String returnText = taskLabel;
// GC gc = new GC(composite);
// int maxWidth = p.x;
//
// if (gc.textExtent(taskLabel).x > maxWidth) {
// for (int i = taskLabel.length(); i > 0; i--) {
// String test = taskLabel.substring(0, i);
// test = test + "...";
// if (gc.textExtent(test).x < maxWidth) {
// returnText = test;
// break;
// }
// }
// }
//
// gc.dispose();
// return returnText;
// }
}