/*******************************************************************************
* Copyright 2006, CHISEL Group, University of Victoria, Victoria, BC, Canada.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* The Chisel Group, University of Victoria
* IBM Corporation
*******************************************************************************/
package ca.uvic.cs.tagsea.ui.views;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IPerspectiveListener2;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.part.ViewPart;
import ca.uvic.cs.tagsea.TagSEAPlugin;
import ca.uvic.cs.tagsea.actions.SendTagsAction;
import ca.uvic.cs.tagsea.core.ITagCollectionListener;
import ca.uvic.cs.tagsea.preferences.TagSEAPreferences;
/**
* This is the overall view part for TagSEA. It shows the tags tree viewer,
* the waypoints table viewer, and the routes tree viewer. All three are inside
* of split panes.
*
* @author Chris Callendar, Chris Bennett, mdesmond
*/
public class TagsView extends ViewPart implements IPerspectiveListener, IPerspectiveListener2
{
public static final String ID = "ca.uvic.cs.tagsea.views.TagsView";
/** default help email address */
private static final String HELP_EMAIL = "chisel-support@cs.uvic.ca, tagsea-user-help@lists.sourceforge.net";
private TagsComposite tagsComposite;
private WaypointsComposite waypointsComposite;
private SashForm leftSash;
private SashForm rightSash;
private Action emailAction;
private Action sendTagsAction;
private IPartListener partListener;
private ITagCollectionListener tagListener;
private class ViewSelectionProvider implements ISelectionProvider {
private List<ISelectionChangedListener> listeners;
private ISelection selection;
/**
*
*/
public ViewSelectionProvider() {
this.listeners = new ArrayList<ISelectionChangedListener>();
this.selection = StructuredSelection.EMPTY;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
*/
public void addSelectionChangedListener(ISelectionChangedListener listener) {
if (!listeners.contains(listener)) listeners.add(listener);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
*/
public ISelection getSelection() {
return this.selection;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
*/
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
listeners.remove(listener);
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
*/
public void setSelection(ISelection selection) {
this.selection = selection;
fireSelectionChanged();
}
private void fireSelectionChanged() {
SelectionChangedEvent evt = new SelectionChangedEvent(this, getSelection());
for (ISelectionChangedListener listener : listeners) {
listener.selectionChanged(evt);
}
}
}
/**
* Should be called after the part control has been created.
*/
private void loadPreferences() {
// load the preferred sash weights
int[] leftWeights = TagSEAPreferences.getTagsSashWeights();
if (leftWeights == null) {
leftWeights = new int[] {10, 25}; // default weights
}
leftSash.setWeights(leftWeights);
int[] rightWeights = TagSEAPreferences.getWaypointsSashWeights();
if (rightWeights == null) {
rightWeights = new int[] {100}; // default weights
}
rightSash.setWeights(rightWeights);
tagsComposite.loadPreferences();
waypointsComposite.loadPreferences();
getSite().getWorkbenchWindow().addPerspectiveListener(this);
connectDnd();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener2#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, org.eclipse.ui.IWorkbenchPartReference, java.lang.String)
*/
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, IWorkbenchPartReference partRef, String changeId)
{
if (partRef instanceof IViewReference && changeId.equals(IWorkbenchPage.CHANGE_VIEW_HIDE))
{
String id = ((IViewReference) partRef).getId();
if (id.equals(getViewSite().getId()))
{
savePreferences();
saveViewerState();
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener#perspectiveActivated(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor)
*/
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective)
{
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPerspectiveListener#perspectiveChanged(org.eclipse.ui.IWorkbenchPage, org.eclipse.ui.IPerspectiveDescriptor, java.lang.String)
*/
public void perspectiveChanged(IWorkbenchPage page, IPerspectiveDescriptor perspective, String changeId)
{
}
/**
* Saves the TagSEA preferences.
*/
private void savePreferences()
{
try {
// boolean showRoutes = (rightSash.getMaximizedControl() == null);
// TagSEAPreferences.setShowRoutes(showRoutes);
int[] weights = leftSash.getWeights();
TagSEAPreferences.setTagsSashWeights(weights);
weights = rightSash.getWeights();
TagSEAPreferences.setWaypointsSashWeights(weights);
tagsComposite.savePreferences();
waypointsComposite.savePreferences();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* This is a callback that will allow us
* to create the viewer and initialize it.
*/
public void createPartControl(final Composite parent) {
//add the selection provider
getSite().setSelectionProvider(new ViewSelectionProvider());
leftSash = new SashForm(parent, SWT.HORIZONTAL);
tagsComposite = new TagsComposite(leftSash, SWT.NONE, this);
rightSash = new SashForm(leftSash, SWT.HORIZONTAL);
waypointsComposite = new WaypointsComposite(rightSash, SWT.NONE);
tagsComposite.getTagsTreeViewer().setInput(getViewSite());
tagsComposite.getTagsTreeViewer().addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
getSite().getSelectionProvider().setSelection(event.getSelection());
}
});
waypointsComposite.getWaypointsTableViewer().setInput(getViewSite());
waypointsComposite.getWaypointsTableViewer().addSelectionChangedListener(new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
getSite().getSelectionProvider().setSelection(event.getSelection());
}
});
// when a tag is selected, show all the waypoints
tagsComposite.getTagsTreeViewer().addSelectionChangedListener(waypointsComposite.getWaypointProvider());
makeActions();
hookContextMenus();
hookDoubleClickActions();
contributeToActionBars();
loadPreferences();
hookListeners();
}
private void hookListeners() {
partListener = new IPartListener()
{
public void partClosed(IWorkbenchPart part)
{
saveViewerState();
getSite().getWorkbenchWindow().getPartService().removePartListener(this);
}
public void partActivated(IWorkbenchPart part) {}
public void partBroughtToTop(IWorkbenchPart part) {}
public void partDeactivated(IWorkbenchPart part) {}
public void partOpened(IWorkbenchPart part)
{
// attempt to connect dnd to the tags view
connectDnd();
}
};
getSite().getWorkbenchWindow().getPartService().addPartListener(partListener);
tagListener = new ITagCollectionListener() {
public void tagsLoaded()
{
getTagsComposite().getTagsTreeViewer().refresh();
loadViewerState();
}
};
TagSEAPlugin.getDefault().getTagCollection().addTagCollectionListener(tagListener);
}
/* (non-Javadoc)
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
getSite().getWorkbenchWindow().getPartService().removePartListener(partListener);
TagSEAPlugin.getDefault().getTagCollection().removeTagCollectionListener(tagListener);
super.dispose();
}
@Override
public void saveState(IMemento memento)
{
savePreferences();
saveViewerState();
super.saveState(memento);
}
private void saveViewerState()
{
TagsViewStateManager.recordState(tagsComposite);
}
private void loadViewerState()
{
TagsViewStateManager.restoreState(tagsComposite);
}
private void hookContextMenus() {
MenuManager menuMgr = tagsComposite.createContextMenu();
getSite().registerContextMenu(menuMgr, tagsComposite.getTagsTreeViewer());
menuMgr = waypointsComposite.createContextMenu();
getSite().registerContextMenu(menuMgr, waypointsComposite.getWaypointsTableViewer());
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
TagsView.this.fillWaypointsContextMenu(manager);
}
});
// @tag TagsView(ContextMenu) : register additional context menus here
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillWaypointsContextMenu(IMenuManager manager)
{
// Route route = routesComposite.getSelectedRoute();
// final Waypoint[] selectedWaypoints = waypointsComposite.getSelectedWaypoints();
// boolean enabled = (route != null) && (selectedWaypoints.length > 0);
// addWaypointsToRouteAction.setEnabled(enabled);
// update the action text to show the route name
// boolean multiple = (selectedWaypoints.length >= 2);
// String text = (multiple ? ADD_WAYPOINTS_TEXT : ADD_WAYPOINT_TEXT);
// if (route != null) {
// text += " (" + route.getName() + ")";
// }
// addWaypointsToRouteAction.setText(text);
//manager.add(addWaypointsToRouteAction);
// manager.add(new Separator());
// Other plug-ins can contribute there actions here
// manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalPullDown(IMenuManager manager)
{
manager.add(emailAction);
manager.add(sendTagsAction);
manager.add(new Separator());
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(emailAction);
manager.add(sendTagsAction);
manager.add(new Separator());
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void makeActions()
{
emailAction = new Action() {
public void run() {
try {
String href = "mailto:" + HELP_EMAIL + "?subject=TagSEA Feedback";
IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
IWebBrowser browser = support.getExternalBrowser();
browser.openURL(new URL(href));
} catch (Throwable t) {
TagSEAPlugin.log("Failed to open email client.", t);
}
}
};
emailAction.setText("Send Feedback");
emailAction.setToolTipText("Email us with your feedback");
emailAction.setImageDescriptor(TagSEAPlugin.getImageDescriptor("/icons/email.gif"));
sendTagsAction = new SendTagsAction(getViewSite());
sendTagsAction.setText("Send Tags");
sendTagsAction.setToolTipText("Send us your tags");
sendTagsAction.setImageDescriptor(TagSEAPlugin.getImageDescriptor("/icons/send_tags.gif"));
// addWaypointsToRouteAction = new Action(ADD_WAYPOINT_TEXT) {
// public void run() {
// Route route = routesComposite.getSelectedRoute();
// if (route != null) {
// Waypoint[] wps = waypointsComposite.getSelectedWaypoints();
// if (wps.length > 0) {
// for (Waypoint wp : wps) {
// route.addWaypoint(wp);
// }
// routesComposite.refreshRoutesViewer(route);
// // expand the route and select the waypoints
// routesComposite.getRoutesTreeViewer().expandToLevel(route, 1);
// routesComposite.getRoutesTreeViewer().setSelection(new StructuredSelection(wps), true);
// }
// }
// }
// };
}
private void hookDoubleClickActions() {
IWorkbenchPage page = getSite().getPage();
waypointsComposite.hookDoubleClickAction(page);
// routesComposite.hookDoubleClickAction(page);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
tagsComposite.getTagsTreeViewer().getControl().setFocus();
}
/**
* Refreshes the tags tree viewer.
*/
public void refreshTagsViewer() {
tagsComposite.refreshTagsViewer(null);
}
public TagsComposite getTagsComposite() {
return tagsComposite;
}
public WaypointsComposite getWaypointsComposite() {
return waypointsComposite;
}
/**
* This is a hack to temporarily support the drag and drop support
*/
private void connectDnd()
{
RoutesView view = TagSEAPlugin.getDefault().getRoutesView();
try
{
if(view != null)
view.getRoutesComposite().getRoutesTreeItemWorker().addTableDragSource(waypointsComposite.getWaypointsTableViewer().getTable());
}
catch (SWTError e)
{
e.printStackTrace();
}
}
}