Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/openon/OpenFileHyperlinkTracker.java')
-rw-r--r--core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/openon/OpenFileHyperlinkTracker.java660
1 files changed, 660 insertions, 0 deletions
diff --git a/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/openon/OpenFileHyperlinkTracker.java b/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/openon/OpenFileHyperlinkTracker.java
new file mode 100644
index 0000000000..372a62008c
--- /dev/null
+++ b/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/openon/OpenFileHyperlinkTracker.java
@@ -0,0 +1,660 @@
+/*******************************************************************************
+ * Copyright (c) 2001, 2006 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
+ * Jens Lukowski/Innoopract - initial renaming/restructuring
+ *
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.internal.openon;
+
+import com.ibm.icu.util.StringTokenizer;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.ITextViewerExtension5;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.wst.sse.ui.internal.Logger;
+import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
+
+
+/**
+ * @deprecated Use org.eclipse.jface.text.hyperlink.HyperlinkManager
+ */
+public class OpenFileHyperlinkTracker implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener {
+
+ /** The session is active. */
+ private boolean fActive;
+
+ /** The currently active style range. */
+ private IRegion fActiveRegion;
+ /** Preference key for browser-like links to be enabled */
+ private String fBrowserLikeLinksKeyModifierKey;
+
+ /** The link color. */
+ private Color fColor;
+ /** The hand cursor. */
+ private Cursor fCursor;
+ /** The key modifier mask. */
+ private int fKeyModifierMask;
+ /** Preference key for hyperlink underline color */
+ private String fLinkColorKey;
+ /** The preference store */
+ private IPreferenceStore fPreferenceStore;
+ /** The currently active style range as position. */
+ private Position fRememberedPosition;
+
+ /** The text viewer this hyperlink tracker is associated with */
+ private ITextViewer fTextViewer;
+
+ /**
+ *
+ */
+ public OpenFileHyperlinkTracker(ITextViewer textViewer) {
+ fTextViewer = textViewer;
+ }
+
+ private void activateCursor(ITextViewer viewer) {
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+ Display display = text.getDisplay();
+ if (fCursor == null)
+ fCursor = new Cursor(display, SWT.CURSOR_HAND);
+ text.setCursor(fCursor);
+ }
+
+ private int computeStateMask(String modifiers) {
+ if (modifiers == null)
+ return -1;
+
+ if (modifiers.length() == 0)
+ return SWT.NONE;
+
+ int stateMask = 0;
+ StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
+ while (modifierTokenizer.hasMoreTokens()) {
+ int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
+ if (modifier == 0 || (stateMask & modifier) == modifier)
+ return -1;
+ stateMask = stateMask | modifier;
+ }
+ return stateMask;
+ }
+
+ /**
+ * Creates a color from the information stored in the given preference
+ * store. Returns <code>null</code> if there is no such information
+ * available.
+ */
+ private Color createColor(IPreferenceStore store, String key, Display display) {
+
+ RGB rgb = null;
+
+ if (store.contains(key)) {
+
+ if (store.isDefault(key))
+ rgb = PreferenceConverter.getDefaultColor(store, key);
+ else
+ rgb = PreferenceConverter.getColor(store, key);
+ }
+
+ return EditorUtility.getColor(rgb);
+ }
+
+ public void deactivate() {
+ deactivate(false);
+ }
+
+ public void deactivate(boolean redrawAll) {
+ if (!fActive)
+ return;
+
+ repairRepresentation(redrawAll);
+ fActive = false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ if (fActive && fActiveRegion != null) {
+ fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
+ try {
+ event.getDocument().addPosition(fRememberedPosition);
+ } catch (BadLocationException x) {
+ fRememberedPosition = null;
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ */
+ public void documentChanged(DocumentEvent event) {
+ if (fRememberedPosition != null) {
+ if (!fRememberedPosition.isDeleted()) {
+
+ event.getDocument().removePosition(fRememberedPosition);
+ fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
+ fRememberedPosition = null;
+
+ ITextViewer viewer = getTextViewer();
+ if (viewer != null) {
+ StyledText widget = viewer.getTextWidget();
+ if (widget != null && !widget.isDisposed()) {
+ widget.getDisplay().asyncExec(new Runnable() {
+ public void run() {
+ deactivate();
+ }
+ });
+ }
+ }
+
+ } else {
+ fActiveRegion = null;
+ fRememberedPosition = null;
+ deactivate();
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusGained(FocusEvent e) {
+ }
+
+ /*
+ * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ */
+ public void focusLost(FocusEvent event) {
+ deactivate();
+ }
+
+ private int getCurrentTextOffset() {
+ try {
+ StyledText text = getTextViewer().getTextWidget();
+ if (text == null || text.isDisposed())
+ return -1;
+
+ Display display = text.getDisplay();
+ Point absolutePosition = display.getCursorLocation();
+ Point relativePosition = text.toControl(absolutePosition);
+
+ int widgetOffset = text.getOffsetAtLocation(relativePosition);
+ if (getTextViewer() instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) getTextViewer();
+ return extension.widgetOffset2ModelOffset(widgetOffset);
+ } else {
+ return widgetOffset + getTextViewer().getVisibleRegion().getOffset();
+ }
+
+ } catch (IllegalArgumentException e) {
+ return -1;
+ }
+ }
+
+ private Point getMaximumLocation(StyledText text, int offset, int length) {
+ Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
+
+ for (int i = 0; i <= length; i++) {
+ Point location = text.getLocationAtOffset(offset + i);
+
+ if (location.x > maxLocation.x)
+ maxLocation.x = location.x;
+ if (location.y > maxLocation.y)
+ maxLocation.y = location.y;
+ }
+
+ return maxLocation;
+ }
+
+ private Point getMinimumLocation(StyledText text, int offset, int length) {
+ Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ for (int i = 0; i <= length; i++) {
+ Point location = text.getLocationAtOffset(offset + i);
+
+ if (location.x < minLocation.x)
+ minLocation.x = location.x;
+ if (location.y < minLocation.y)
+ minLocation.y = location.y;
+ }
+
+ return minLocation;
+ }
+
+ private IPreferenceStore getNewPreferenceStore() {
+ return fPreferenceStore;
+ }
+
+ private ITextViewer getTextViewer() {
+ return fTextViewer;
+ }
+
+ private void highlightRegion(ITextViewer viewer, IRegion region) {
+
+ if (region.equals(fActiveRegion))
+ return;
+
+ repairRepresentation();
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+
+ // Underline
+ int offset = 0;
+ int length = 0;
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ IRegion widgetRange = extension.modelRange2WidgetRange(new Region(region.getOffset(), region.getLength()));
+ if (widgetRange == null)
+ return;
+
+ offset = widgetRange.getOffset();
+ length = widgetRange.getLength();
+
+ } else {
+ offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
+ length = region.getLength();
+ }
+ // need clearBackground to be true for paint event to be fired
+ text.redrawRange(offset, length, true);
+
+ fActiveRegion = region;
+ }
+
+ private boolean includes(IRegion region, IRegion position) {
+ return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+ if (oldInput == null)
+ return;
+ deactivate();
+ oldInput.removeDocumentListener(this);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
+ * org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (newInput == null)
+ return;
+ newInput.addDocumentListener(this);
+ }
+
+ public void install(IPreferenceStore store) {
+ fPreferenceStore = store;
+ ITextViewer textViewer = getTextViewer();
+ if (textViewer == null)
+ return;
+
+ StyledText text = textViewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ updateColor(textViewer);
+
+ textViewer.addTextInputListener(this);
+
+ IDocument document = textViewer.getDocument();
+ if (document != null)
+ document.addDocumentListener(this);
+
+ text.addKeyListener(this);
+ text.addMouseListener(this);
+ text.addMouseMoveListener(this);
+ text.addFocusListener(this);
+ text.addPaintListener(this);
+
+ updateKeyModifierMask();
+
+ fPreferenceStore.addPropertyChangeListener(this);
+ }
+
+ /*
+ * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyPressed(KeyEvent event) {
+
+ if (fActive) {
+ deactivate();
+ return;
+ }
+
+ if (event.keyCode != fKeyModifierMask) {
+ deactivate();
+ return;
+ }
+
+ fActive = true;
+
+ // removed for #25871
+ //
+ // ISourceViewer viewer= getSourceViewer();
+ // if (viewer == null)
+ // return;
+ //
+ // IRegion region= getCurrentTextRegion(viewer);
+ // if (region == null)
+ // return;
+ //
+ // highlightRegion(viewer, region);
+ // activateCursor(viewer);
+ }
+
+ /*
+ * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ public void keyReleased(KeyEvent event) {
+
+ if (!fActive)
+ return;
+
+ deactivate();
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseDown(MouseEvent event) {
+
+ if (!fActive)
+ return;
+
+ if (event.stateMask != fKeyModifierMask) {
+ deactivate();
+ return;
+ }
+
+ if (event.button != 1) {
+ deactivate();
+ return;
+ }
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseMove(MouseEvent event) {
+
+ if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
+ deactivate();
+ return;
+ }
+
+ if (!fActive) {
+ if (event.stateMask != fKeyModifierMask)
+ return;
+ // modifier was already pressed
+ fActive = true;
+ }
+
+ ITextViewer viewer = getTextViewer();
+ if (viewer == null) {
+ deactivate();
+ return;
+ }
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed()) {
+ deactivate();
+ return;
+ }
+
+ if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
+ deactivate();
+ return;
+ }
+
+ IRegion region = null;
+ int offset = getCurrentTextOffset();
+ IOpenOn openOn = OpenOnProvider.getInstance().getOpenOn(getTextViewer().getDocument(), offset);
+ if (openOn != null) {
+ region = openOn.getOpenOnRegion(getTextViewer().getDocument(), offset);
+ }
+ if (region == null || region.getLength() == 0) {
+ repairRepresentation();
+ return;
+ }
+
+ highlightRegion(viewer, region);
+ activateCursor(viewer);
+ }
+
+ /*
+ * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
+ */
+ public void mouseUp(MouseEvent e) {
+
+ if (!fActive)
+ return;
+
+ if (e.button != 1) {
+ deactivate();
+ return;
+ }
+
+ boolean wasActive = fCursor != null;
+ IRegion previousRegion = fActiveRegion;
+
+ deactivate();
+
+ if (wasActive) {
+ IOpenOn openOn = OpenOnProvider.getInstance().getOpenOn(getTextViewer().getDocument(), previousRegion.getOffset());
+ if (openOn != null) {
+ openOn.openOn(getTextViewer().getDocument(), previousRegion);
+ }
+ }
+ }
+
+ /*
+ * @see PaintListener#paintControl(PaintEvent)
+ */
+ public void paintControl(PaintEvent event) {
+ if (fActiveRegion == null)
+ return;
+
+ ITextViewer viewer = getTextViewer();
+ if (viewer == null)
+ return;
+
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+
+ int offset = 0;
+ int length = 0;
+
+ if (viewer instanceof ITextViewerExtension5) {
+
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ IRegion widgetRange = extension.modelRange2WidgetRange(fActiveRegion);
+ if (widgetRange == null)
+ return;
+
+ offset = widgetRange.getOffset();
+ length = widgetRange.getLength();
+
+ } else {
+
+ IRegion region = viewer.getVisibleRegion();
+ if (!includes(region, fActiveRegion))
+ return;
+
+ offset = fActiveRegion.getOffset() - region.getOffset();
+ length = fActiveRegion.getLength();
+ }
+
+ // support for bidi
+ Point minLocation = getMinimumLocation(text, offset, length);
+ Point maxLocation = getMaximumLocation(text, offset, length);
+
+ int x1 = minLocation.x;
+ int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
+ int y = minLocation.y + text.getLineHeight() - 1;
+
+ GC gc = event.gc;
+ if (fColor != null && !fColor.isDisposed())
+ gc.setForeground(fColor);
+ gc.drawLine(x1, y, x2, y);
+ }
+
+ /*
+ * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ if (event.getProperty().equals(fLinkColorKey)) {
+ ITextViewer viewer = getTextViewer();
+ if (viewer != null)
+ updateColor(viewer);
+ } else if (event.getProperty().equals(fBrowserLikeLinksKeyModifierKey)) {
+ updateKeyModifierMask();
+ }
+ }
+
+ private void repairRepresentation() {
+ repairRepresentation(false);
+ }
+
+ private void repairRepresentation(boolean redrawAll) {
+
+ if (fActiveRegion == null)
+ return;
+
+ int offset = fActiveRegion.getOffset();
+ int length = fActiveRegion.getLength();
+ fActiveRegion = null;
+
+ ITextViewer viewer = getTextViewer();
+ if (viewer != null) {
+
+ resetCursor(viewer);
+
+ // Remove underline
+ if (viewer instanceof ITextViewerExtension5) {
+ ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
+ offset = extension.modelOffset2WidgetOffset(offset);
+ } else {
+ offset -= viewer.getVisibleRegion().getOffset();
+ }
+ try {
+ StyledText text = viewer.getTextWidget();
+
+ // need clearBackground to be true for paint event to be fired
+ text.redrawRange(offset, length, true);
+ } catch (IllegalArgumentException x) {
+ Logger.logException(x);
+ }
+ }
+ }
+
+ private void resetCursor(ITextViewer viewer) {
+ StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed())
+ text.setCursor(null);
+
+ if (fCursor != null) {
+ fCursor.dispose();
+ fCursor = null;
+ }
+ }
+
+ public void setHyperlinkPreferenceKeys(String linkColorKey, String browserLikeLinksKeyModifierKey) {
+ fLinkColorKey = linkColorKey;
+ fBrowserLikeLinksKeyModifierKey = browserLikeLinksKeyModifierKey;
+ }
+
+ public void uninstall() {
+ if (fCursor != null) {
+ fCursor.dispose();
+ fCursor = null;
+ }
+
+ ITextViewer textViewer = getTextViewer();
+ if (textViewer == null)
+ return;
+
+ textViewer.removeTextInputListener(this);
+
+ IDocument document = textViewer.getDocument();
+ if (document != null)
+ document.removeDocumentListener(this);
+
+ IPreferenceStore preferenceStore = getNewPreferenceStore();
+ if (preferenceStore != null)
+ preferenceStore.removePropertyChangeListener(this);
+
+ StyledText text = textViewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ text.removeKeyListener(this);
+ text.removeMouseListener(this);
+ text.removeMouseMoveListener(this);
+ text.removeFocusListener(this);
+ text.removePaintListener(this);
+ }
+
+ private void updateColor(ITextViewer viewer) {
+ StyledText text = viewer.getTextWidget();
+ if (text == null || text.isDisposed())
+ return;
+
+ Display display = text.getDisplay();
+ fColor = createColor(getNewPreferenceStore(), fLinkColorKey, display);
+ }
+
+ private void updateKeyModifierMask() {
+ String modifiers = getNewPreferenceStore().getString(fBrowserLikeLinksKeyModifierKey);
+ fKeyModifierMask = computeStateMask(modifiers);
+ }
+}

Back to the top