/* * Copyright (c) 2006-2017 DMDirc Developers * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS * OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * @author Stanislav Lapitsky * @version 1.0 * * Extended for Hyperlink events */ package com.dmdirc.addons.ui_swing.components.text; import com.dmdirc.events.LinkChannelClickedEvent; import com.dmdirc.events.LinkNicknameClickedEvent; import com.dmdirc.events.LinkUrlClickedEvent; import com.dmdirc.events.eventbus.EventBus; import com.dmdirc.interfaces.WindowModel; import com.dmdirc.ui.messages.IRCTextAttribute; import java.awt.Cursor; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.JEditorPane; import javax.swing.SwingUtilities; import javax.swing.text.Element; import javax.swing.text.StyledDocument; import javax.swing.text.StyledEditorKit; import javax.swing.text.ViewFactory; /** * @author Stanislav Lapitsky * @version 1.0 * * Extended for Hyperlink events */ public class WrapEditorKit extends StyledEditorKit implements MouseListener, MouseMotionListener { /** A version number for this class. */ private static final long serialVersionUID = 1; /** Wrap column factory. */ private final ViewFactory defaultFactory = new WrapColumnFactory(); /** Hand cursor. */ private static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR); /** Are we wrapping text? */ private final boolean wrap; /** Associated Component. */ private JEditorPane editorPane; /** Event bus to fire link click events on. */ private final EventBus eventBus; /** The window this editor kit is used in. */ private final WindowModel window; /** * Initialises a new wrapping editor kit. * * @param wrapping true iif the text needs to wrap * @param eventBus Event bus to raise hyperlink events on * @param window Window as source for hyperlink events */ public WrapEditorKit(final boolean wrapping, final EventBus eventBus, final WindowModel window) { this.window = window; this.eventBus = eventBus; wrap = wrapping; } @Override public void install(final JEditorPane c) { super.install(c); editorPane = c; c.addMouseListener(this); c.addMouseMotionListener(this); } @Override public void deinstall(final JEditorPane c) { c.removeMouseListener(this); c.removeMouseMotionListener(this); editorPane = null; super.deinstall(c); } @Override public ViewFactory getViewFactory() { if (wrap) { return super.getViewFactory(); } else { return defaultFactory; } } @Override public void mouseMoved(final MouseEvent e) { if (editorPane == null) { return; } if (!editorPane.isEditable() && (characterElementAt(e).getAttributes() .getAttribute(IRCTextAttribute.HYPERLINK) != null || characterElementAt(e).getAttributes().getAttribute( IRCTextAttribute.CHANNEL) != null || characterElementAt(e).getAttributes().getAttribute( IRCTextAttribute.NICKNAME) != null)) { editorPane.setCursor(HAND_CURSOR); return; } editorPane.setCursor(Cursor.getDefaultCursor()); } @Override public void mouseReleased(final MouseEvent e) { if (!SwingUtilities.isLeftMouseButton(e) || editorPane == null) { return; } if (!editorPane.isEditable()) { Object target = characterElementAt(e).getAttributes().getAttribute( IRCTextAttribute.HYPERLINK); if (target != null) { eventBus.publishAsync(new LinkUrlClickedEvent(window, (String) target)); } target = characterElementAt(e).getAttributes().getAttribute(IRCTextAttribute.CHANNEL); if (target != null) { eventBus.publishAsync(new LinkChannelClickedEvent(window, (String) target)); } target = characterElementAt(e).getAttributes().getAttribute(IRCTextAttribute.NICKNAME); if (target != null) { eventBus.publishAsync(new LinkNicknameClickedEvent(window, (String) target)); } } } @Override public void mouseClicked(final MouseEvent e) { //Ignore } @Override public void mousePressed(final MouseEvent e) { //Ignore } @Override public void mouseEntered(final MouseEvent e) { //Ignore } @Override public void mouseExited(final MouseEvent e) { //Ignore } @Override public void mouseDragged(final MouseEvent e) { //Ignore } /** * Returns the character element for the position of the mouse event. * * @param e Mouse event to get position from * * @return Character element at mouse event */ private Element characterElementAt(final MouseEvent e) { return ((StyledDocument) editorPane.getDocument()).getCharacterElement( editorPane.getUI().viewToModel(editorPane, e.getPoint())); } }