/******************************************************************************* * Copyright (c) 2000, 2008 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 * Izzet Safer (isafer@ca.ibm.com) - patch (see Bugzilla #250505) *******************************************************************************/ package org.eclipse.ui.forms.widgets; import org.eclipse.core.runtime.ListenerList; import org.eclipse.swt.SWT; //import org.eclipse.swt.accessibility.ACC; //import org.eclipse.swt.events.PaintEvent; //import org.eclipse.swt.events.PaintListener; //import org.eclipse.swt.graphics.GC; //import org.eclipse.swt.graphics.Point; //import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.events.IHyperlinkListener; //import org.eclipse.ui.internal.forms.widgets.FormsResources; /** * This is the base class for custom hyperlink widget. It is responsible for * processing mouse and keyboard events, and converting them into unified * hyperlink events. Subclasses are responsible for rendering the hyperlink in * the client area. * <p> * <dl> * <dt><b>Styles:</b></dt> * <dd>None</dd> * </dl> * * @since 1.0 */ public abstract class AbstractHyperlink extends Canvas { private boolean hasFocus; boolean paintFocus=true; // RAP [rh] unnucessary code: was used by MouseUp/MouseDown listeners // /* // * Armed link is one that will activate on a mouse up event, i.e. // * it has received a mouse down and mouse still on top of it. // */ // private boolean armed; private ListenerList listeners; /** * Amount of the margin width around the hyperlink (default is 1). */ protected int marginWidth = 1; /** * Amount of the margin height around the hyperlink (default is 1). */ protected int marginHeight = 1; /** * Creates a new hyperlink in the provided parent. * * @param parent * the control parent * @param style * the widget style */ public AbstractHyperlink(Composite parent, int style) { super(parent, style); // RAP [rh] missing key, paint and traverse events // addListener(SWT.KeyDown, new Listener() { // public void handleEvent(Event e) { // if (e.character == '\r') { // handleActivate(e); // } // } // }); // addPaintListener(new PaintListener() { // public void paintControl(PaintEvent e) { // paint(e); // } // }); // addListener(SWT.Traverse, new Listener() { // public void handleEvent(Event e) { // switch (e.detail) { // case SWT.TRAVERSE_PAGE_NEXT: // case SWT.TRAVERSE_PAGE_PREVIOUS: // case SWT.TRAVERSE_ARROW_NEXT: // case SWT.TRAVERSE_ARROW_PREVIOUS: // case SWT.TRAVERSE_RETURN: // e.doit = false; // return; // } // e.doit = true; // } // }); Listener listener = new Listener() { public void handleEvent(Event e) { switch (e.type) { case SWT.FocusIn: hasFocus = true; handleEnter(e); break; case SWT.FocusOut: hasFocus = false; handleExit(e); break; case SWT.DefaultSelection: handleActivate(e); break; // RAP [rh] missing mouse events // case SWT.MouseEnter: // handleEnter(e); // break; // case SWT.MouseExit: // handleExit(e); // break; // RAP [rh] mouse-up- and -down unnecessary, see DefaultSelection // case SWT.MouseDown: // handleMouseDown(e); // break; // case SWT.MouseUp: // handleMouseUp(e); // break; // RAP [rh] missing mouse events // case SWT.MouseMove: // handleMouseMove(e); // break; } } }; // RAP [rh] missing mouse events // addListener(SWT.MouseEnter, listener); // addListener(SWT.MouseExit, listener); // addListener(SWT.MouseDown, listener); // addListener(SWT.MouseUp, listener); // addListener(SWT.MouseMove, listener); addListener(SWT.FocusIn, listener); addListener(SWT.FocusOut, listener); // RAP [rh] add defaultSelectionListener, sent by ToggleHyperlink.js to get // notified about clicks on toggle image addListener(SWT.DefaultSelection, listener); // RAP [if] Cursor is managed on the client side // setCursor(FormsResources.getHandCursor()); } /** * Adds the event listener to this hyperlink. * * @param listener * the event listener to add */ public void addHyperlinkListener(IHyperlinkListener listener) { if (listeners == null) listeners = new ListenerList(); listeners.add(listener); } /** * Removes the event listener from this hyperlink. * * @param listener * the event listener to remove */ public void removeHyperlinkListener(IHyperlinkListener listener) { if (listeners == null) return; listeners.remove(listener); } /** * Returns the selection state of the control. When focus is gained, the * state will be <samp>true </samp>; it will switch to <samp>false </samp> * when the control looses focus. * * @return <code>true</code> if the widget has focus, <code>false</code> * otherwise. */ public boolean getSelection() { return hasFocus; } /** * Called when hyperlink is entered. Subclasses that override this method * must call 'super'. */ protected void handleEnter(Event e) { redraw(); if (listeners == null) return; int size = listeners.size(); HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), e.stateMask); Object[] listenerList = listeners.getListeners(); for (int i = 0; i < size; i++) { IHyperlinkListener listener = (IHyperlinkListener) listenerList[i]; listener.linkEntered(he); } } /** * Called when hyperlink is exited. Subclasses that override this method * must call 'super'. */ protected void handleExit(Event e) { // disarm the link; won't activate on mouseup // RAP [rh] Unused code: was used by MouseUp/MouseDown listener code // armed = false; redraw(); if (listeners == null) return; int size = listeners.size(); HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), e.stateMask); Object[] listenerList = listeners.getListeners(); for (int i = 0; i < size; i++) { IHyperlinkListener listener = (IHyperlinkListener) listenerList[i]; listener.linkExited(he); } } /** * Called when hyperlink has been activated. Subclasses that override this * method must call 'super'. */ protected void handleActivate(Event e) { // disarm link, back to normal state // RAP [rh] Unused code: was used by MouseUp/MouseDown listener code // armed = false; if (listeners == null) return; int size = listeners.size(); // RAP [if] Cursor is managed on the client side // setCursor(FormsResources.getBusyCursor()); HyperlinkEvent he = new HyperlinkEvent(this, getHref(), getText(), e.stateMask); Object[] listenerList = listeners.getListeners(); for (int i = 0; i < size; i++) { IHyperlinkListener listener = (IHyperlinkListener) listenerList[i]; listener.linkActivated(he); } // RAP [if] Cursor is managed on the client side // if (!isDisposed()) // setCursor(FormsResources.getHandCursor()); // RAP [if] missing accessibility support // triggerAccessible(); } // RAP [if] missing accessibility support // void triggerAccessible() { // getAccessible().setFocus(ACC.CHILDID_SELF); // } /** * Sets the object associated with this hyperlink. Concrete implementation * of this class can use if to store text, URLs or model objects that need * to be processed on hyperlink events. * * @param href * the hyperlink object reference */ public void setHref(Object href) { setData("href", href); //$NON-NLS-1$ } /** * Returns the object associated with this hyperlink. * * @see #setHref * @return the hyperlink object reference */ public Object getHref() { return getData("href"); //$NON-NLS-1$ } /** * Returns the textual representation of this hyperlink suitable for showing * in tool tips or on the status line. * * @return the hyperlink text */ public String getText() { return getToolTipText(); } // RAP [rh] missing paint events // /** // * Paints the hyperlink as a reaction to the provided paint event. // * // * @param gc // * graphic context // */ // protected abstract void paintHyperlink(GC gc); // RAP [rh] missing paint events // /** // * Paints the control as a reaction to the provided paint event. // * // * @param e // * the paint event // */ // protected void paint(PaintEvent e) { // GC gc = e.gc; // Rectangle clientArea = getClientArea(); // if (clientArea.width == 0 || clientArea.height == 0) // return; // paintHyperlink(gc); // if (paintFocus && hasFocus) { // Rectangle carea = getClientArea(); // gc.setForeground(getForeground()); // gc.drawFocus(0, 0, carea.width, carea.height); // } // } // RAP [rh] Unused code: was used by MouseUp and MouseDown events // private void handleMouseDown(Event e) { // if (e.button != 1) // return; // // armed and ready to activate on mouseup // armed = true; // } // // private void handleMouseUp(Event e) { // if (!armed || e.button != 1) // return; // Point size = getSize(); // // Filter out mouse up events outside // // the link. This can happen when mouse is // // clicked, dragged outside the link, then // // released. // if (e.x < 0) // return; // if (e.y < 0) // return; // if (e.x >= size.x) // return; // if (e.y >= size.y) // return; // handleActivate(e); // } // RAP [rh] Unused code: was used by MouseMove listener // private void handleMouseMove(Event e) { // // disarm link if we move out of bounds // if (armed) { // Point size = getSize(); // armed = (e.x >= 0 && e.y >= 0 && e.x < size.x && e.y < size.y); // } // } /* * (non-Javadoc) * @see org.eclipse.swt.widgets.Control#setEnabled(boolean) */ public void setEnabled (boolean enabled) { boolean needsRedraw = enabled != getEnabled(); super.setEnabled(enabled); if (needsRedraw) redraw(); } }