blob: cacc7b60a4db7dfa8acaabd5a3b764cd92f309f0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.help.ui.internal.views;
import org.eclipse.help.*;
import org.eclipse.help.ui.internal.*;
import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.forms.AbstractFormPart;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
public abstract class HyperlinkTreePart extends AbstractFormPart implements
IHelpPart {
protected ReusableHelpPart parent;
private String id;
private Composite container;
protected TreeViewer treeViewer;
private TreeItem lastItem;
private Cursor handCursor;
/**
* @param parent
* @param toolkit
* @param style
*/
public HyperlinkTreePart(Composite parent, final FormToolkit toolkit,
IToolBarManager tbm) {
handCursor = new Cursor(parent.getDisplay(), SWT.CURSOR_HAND);
container = toolkit.createComposite(parent);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
container.setLayout(layout);
Composite sep = toolkit.createCompositeSeparator(container);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.heightHint = 1;
sep.setLayoutData(gd);
treeViewer = new TreeViewer(container, SWT.H_SCROLL | SWT.V_SCROLL);
treeViewer.getTree().setMenu(parent.getMenu());
treeViewer.getTree().setForeground(
toolkit.getHyperlinkGroup().getForeground());
configureTreeViewer();
treeViewer.setInput(this);
treeViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
treeViewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent event) {
doOpenSelection((IStructuredSelection) event.getSelection());
}
});
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
handleSelectionChanged((IStructuredSelection) event
.getSelection());
}
});
treeViewer.getTree().addMouseListener(new MouseAdapter() {
long lastTime;
public void mouseUp(MouseEvent e) {
long eventTime = e.time & 0xFFFFFFFFL;
if (eventTime - lastTime <= e.display.getDoubleClickTime())
return;
if (e.button != 1)
return;
lastTime = eventTime;
Point p = new Point(e.x, e.y);
TreeItem item = treeViewer.getTree().getItem(p);
if (item != null) {
Object obj = item.getData();
if (obj != null) {
doOpen(obj);
}
}
}
});
treeViewer.getTree().addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
validateLastItem();
if (lastItem == null)
return;
Rectangle bounds = lastItem.getBounds();
boolean selected = false;
TreeItem[] items = lastItem.getParent().getSelection();
for (int i = 0; i < items.length; i++) {
if (items[i].equals(lastItem)) {
selected = true;
break;
}
}
if (selected)
e.gc.setForeground(container.getDisplay().getSystemColor(
SWT.COLOR_LIST_SELECTION_TEXT));
else
e.gc.setForeground(toolkit.getHyperlinkGroup()
.getActiveForeground());
FontMetrics fm = e.gc.getFontMetrics();
int height = fm.getHeight();
int lineY = bounds.y + height;
e.gc.drawLine(bounds.x, lineY, bounds.x + bounds.width - 1,
lineY);
}
});
treeViewer.getTree().addMouseTrackListener(new MouseTrackAdapter() {
public void mouseExit(MouseEvent e) {
validateLastItem();
if (lastItem != null) {
TreeItem item = lastItem;
lastItem = null;
item.setForeground(null);
}
}
});
treeViewer.getTree().addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
Point p = new Point(e.x, e.y);
TreeItem item = treeViewer.getTree().getItem(p);
validateLastItem();
if (item != null) {
if (lastItem != null) {
if (!lastItem.equals(item)) {
lastItem.setForeground(null);
repaintItem(lastItem);
updateStatus(null);
lastItem = null;
} else
return;
}
Object obj = item.getData();
treeViewer.getTree().setCursor(handCursor);
IStructuredSelection ssel = (IStructuredSelection) treeViewer
.getSelection();
if (ssel.getFirstElement() == obj)
item.setForeground(container.getDisplay()
.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
else
item.setForeground(toolkit.getHyperlinkGroup()
.getActiveForeground());
lastItem = item;
repaintItem(lastItem);
if (obj instanceof IHelpResource)
updateStatus((IHelpResource) obj);
else
updateStatus(null);
return;
} else if (lastItem != null) {
lastItem.setForeground(null);
repaintItem(lastItem);
lastItem = null;
updateStatus(null);
}
treeViewer.getTree().setCursor(null);
}
});
contributeToToolBar(tbm);
}
public void dispose() {
handCursor.dispose();
super.dispose();
}
private void repaintItem(TreeItem item) {
Rectangle bounds = item.getBounds();
item.getParent().redraw(bounds.x, bounds.y, bounds.width,
bounds.height, false);
}
protected void contributeToToolBar(IToolBarManager tbm) {
Action collapseAllAction = new Action() {
public void run() {
BusyIndicator.showWhile(container.getDisplay(), new Runnable() {
public void run() {
doCollapseAll();
}
});
}
};
collapseAllAction.setImageDescriptor(HelpUIResources
.getImageDescriptor(IHelpUIConstants.IMAGE_COLLAPSE_ALL));
collapseAllAction
.setToolTipText(Messages.AllTopicsPart_collapseAll_tooltip);
tbm.insertBefore("back", collapseAllAction); //$NON-NLS-1$
tbm.insertBefore("back", new Separator()); //$NON-NLS-1$
}
private void doCollapseAll() {
Object[] expanded = treeViewer.getExpandedElements();
treeViewer.collapseAll();
treeViewer.update(expanded, null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.help.ui.internal.views.IHelpPart#getControl()
*/
public Control getControl() {
return container;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.help.ui.internal.views.IHelpPart#init(org.eclipse.help.ui.internal.views.NewReusableHelpPart)
*/
public void init(ReusableHelpPart parent, String id, IMemento memento) {
this.parent = parent;
this.id = id;
}
public String getId() {
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.help.ui.internal.views.IHelpPart#setVisible(boolean)
*/
public void setVisible(boolean visible) {
container.setVisible(visible);
if (visible)
treeViewer.refresh();
}
private void doOpenSelection(IStructuredSelection sel) {
Object obj = sel.getFirstElement();
if (obj != null) {
doOpen(obj);
}
}
protected void handleSelectionChanged(IStructuredSelection sel) {
Object obj = sel.getFirstElement();
if (lastItem != null) {
Object lastObj = lastItem.getData();
if (lastObj==obj)
lastItem.setForeground(container.getDisplay()
.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
else
lastItem.setForeground(parent.getForm().getToolkit().getHyperlinkGroup()
.getActiveForeground());
repaintItem(lastItem);
}
if (obj instanceof IHelpResource) {
IHelpResource res = (IHelpResource) obj;
updateStatus(res, false);
} else
updateStatus(null, false);
}
private void updateStatus(IHelpResource res) {
updateStatus(res, true);
}
private void updateStatus(IHelpResource res, boolean defaultToSelection) {
if (defaultToSelection && res == null) {
IStructuredSelection ssel = (IStructuredSelection) treeViewer
.getSelection();
Object obj = ssel.getFirstElement();
if (obj instanceof IHelpResource)
res = (IHelpResource) obj;
}
if (res != null) {
String label = res.getLabel();
String href = getHref(res);
HyperlinkTreePart.this.parent.handleLinkEntered(new HyperlinkEvent(
treeViewer.getTree(), href, label, SWT.NULL));
} else {
HyperlinkTreePart.this.parent.handleLinkExited(null);
}
}
protected String getHref(IHelpResource res) {
return res.getHref();
}
protected abstract void configureTreeViewer();
protected abstract void doOpen(Object obj);
protected void postUpdate(final Object obj) {
treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
public void run() {
treeViewer.update(obj, null);
}
});
}
/*
* (non-Javadoc)
*
* @see org.eclipse.help.ui.internal.views.IHelpPart#fillContextMenu(org.eclipse.jface.action.IMenuManager)
*/
public boolean fillContextMenu(IMenuManager manager) {
return parent.fillSelectionProviderMenu(treeViewer, manager,
canAddBookmarks());
}
protected abstract boolean canAddBookmarks();
/*
* (non-Javadoc)
*
* @see org.eclipse.help.ui.internal.views.IHelpPart#hasFocus()
*/
public boolean hasFocusControl(Control focusControl) {
return treeViewer.getControl().equals(focusControl);
}
public void setFocus() {
if (treeViewer != null)
treeViewer.getTree().setFocus();
}
public IAction getGlobalAction(String id) {
if (id.equals(ActionFactory.COPY.getId()))
return parent.getCopyAction();
return null;
}
public void stop() {
}
private void validateLastItem() {
if (lastItem != null && lastItem.isDisposed())
lastItem = null;
}
}