/* GNU Lesser General Public License CustomAction Copyright (C) 2000 Howard Kistler This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.hexidec.ekit.action; import java.awt.Color; import java.awt.dnd.DnDConstants; import java.awt.event.ActionEvent; import java.util.Enumeration; import java.util.Hashtable; import javax.swing.text.AttributeSet; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyledEditorKit; import javax.swing.text.html.HTML; import com.hexidec.ekit.action.bridges.EkitCoreService; import com.hexidec.ekit.action.bridges.MutatorService; import com.hexidec.ekit.action.bridges.TextPaneService; import com.hexidec.ekit.action.bridges.UserInputService; import com.hexidec.ekit.component.SimpleInfoDialog; import com.hexidec.util.Translatrix; /** Class for implementing custom HTML insertion actions */ public class CustomAction extends StyledEditorKit.StyledTextAction { private static final long serialVersionUID = 7752928122828347312L; protected EkitCoreService parentEkit; private HTML.Tag htmlTag; private Hashtable<?, ?> htmlAttribs; private MutatorService mutator; public CustomAction(EkitCoreService ekit, String actionName, HTML.Tag inTag, Hashtable<?, ?> attribs) { super(actionName); parentEkit = ekit; htmlTag = inTag; htmlAttribs = attribs; } public CustomAction(EkitCoreService ekit, String actionName, HTML.Tag inTag) { this(ekit, actionName, inTag, new Hashtable<Object, Object>()); } public void actionPerformed(ActionEvent ae) { mutator = parentEkit.getMutator(); if (!this.isEnabled()) return; TextPaneService parentTextPane = parentEkit.getTextPane(); String selText = parentTextPane.getSelectedText(); if (selText == null || selText.length() < 1) { parentEkit.showInfoDialog( Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorNoTextSelected"), SimpleInfoDialog.ERROR); return; } addHyperlink(ae, parentTextPane, selText); } public void addHyperlink(ActionEvent ae, TextPaneService parentTextPane, String selText) { if (htmlTag.toString().equals(HTML.Tag.FONT.toString())) { handleFontTag(ae); } if (!htmlAttribs.containsKey("href")) { SimpleAttributeSet sasAttr = new SimpleAttributeSet(); if (htmlTag.toString().equals(HTML.Tag.A.toString())) { String anchor = getAnchor(findCurrentAnchor(parentTextPane, selText)); if (anchor == null) return; insertAttribute(sasAttr, "href", anchor); } mergeAttributesFromTextPane(sasAttr); SimpleAttributeSet sasTag = new SimpleAttributeSet(); sasTag.addAttribute(htmlTag, sasAttr); parentTextPane.setCharacterAttributes(sasTag, false); parentEkit.refreshOnUpdate(); } parentTextPane.requestFocus(); } public void mergeAttributesFromTextPane(SimpleAttributeSet sasAttr) { SimpleAttributeSet baseAttrs = parentEkit.getTextPane().newSimpleAttributeSet(); mutator.mutate(baseAttrs); Enumeration<?> attribEntriesOriginal = baseAttrs.getAttributeNames(); while (attribEntriesOriginal.hasMoreElements()) { Object entryKey = attribEntriesOriginal.nextElement(); Object entryValue = baseAttrs.getAttribute(entryKey); insertAttribute(sasAttr, entryKey, entryValue); } } public void handleFontTag(ActionEvent ae) { if (htmlAttribs.containsKey("color")) { Color color = parentEkit.chooseColor(Translatrix .getTranslationString("CustomColorDialog"), Color.black); if (color != null) { parentEkit.setForegroundColor(color, ae); } } } public String getAnchor(String currentAnchor) { String newAnchor = getAnchorFromUser(currentAnchor); if (newAnchor == null) { parentEkit.repaint(); } return newAnchor; } public String getAnchorFromUser(String currentAnchor) { UserInputService uidInput = parentEkit .newUserInputAnchorDialog(parentEkit, Translatrix .getTranslationString("AnchorDialogTitle"), true, currentAnchor); String newAnchor = uidInput.getInputText(); uidInput.dispose(); return newAnchor; } public String findCurrentAnchor(TextPaneService parentTextPane, String selectedText) { SimpleAttributeSet sasText = null; for (int i = 0; i < selectedText.length(); i++) { sasText = parentTextPane.newSimpleAttributeSet(); Object entryValue = getValueOf(HTML.Tag.A.toString(), sasText); if (entryValue instanceof SimpleAttributeSet) { String currentAnchor = (String) getValueOf("href", (SimpleAttributeSet) entryValue); if (currentAnchor != null) { return currentAnchor; } } } return ""; } public boolean isATag(Object entryKey) { return entryKey.toString().equals(HTML.Tag.A.toString()); } private Object getValueOf(String key, SimpleAttributeSet set) { Enumeration<?> attributes = set.getAttributeNames(); while (attributes.hasMoreElements()) { Object entryKey = attributes.nextElement(); if (key.equalsIgnoreCase(entryKey.toString())) { return set.getAttribute(entryKey); } } return null; } private void insertAttribute(SimpleAttributeSet attrs, Object key, Object value) { if (value instanceof AttributeSet) { AttributeSet subSet = (AttributeSet) value; Enumeration<?> attribEntriesSub = subSet.getAttributeNames(); while (attribEntriesSub.hasMoreElements()) { Object subKey = attribEntriesSub.nextElement(); Object subValue = subSet.getAttribute(subKey); insertAttr(attrs, subKey, subValue); } } else { insertAttr(attrs, key, value); } if (key.toString().toLowerCase().equals("font-family")) { if (attrs.isDefined("face")) { insertAttr(attrs, "face", attrs.getAttribute("face")); insertAttr(attrs, "font-family", attrs.getAttribute("face")); } else { insertAttr(attrs, "face", value); } } } private void insertAttr(SimpleAttributeSet attrs, Object key, Object value) { while (attrs.isDefined(key)) { attrs.removeAttribute(key); break; } attrs.addAttribute(key, value); } }