/*
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.event.ActionEvent;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.swing.JColorChooser;
import javax.swing.JTextPane;
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.EkitCore;
import com.hexidec.ekit.component.SimpleInfoDialog;
import com.hexidec.ekit.component.UserInputAnchorDialog;
import com.hexidec.util.Translatrix;
/** Class for implementing custom HTML insertion actions
*/
public class CustomAction extends StyledEditorKit.StyledTextAction
{
protected EkitCore parentEkit;
private HTML.Tag htmlTag;
private Hashtable htmlAttribs;
public CustomAction(EkitCore ekit, String actionName, HTML.Tag inTag, Hashtable attribs)
{
super(actionName);
parentEkit = ekit;
htmlTag = inTag;
htmlAttribs = attribs;
}
public CustomAction(EkitCore ekit, String actionName, HTML.Tag inTag)
{
this(ekit, actionName, inTag, new Hashtable());
}
public void actionPerformed(ActionEvent ae)
{
if(this.isEnabled())
{
Hashtable<String, String> htmlAttribs2 = new Hashtable<String, String>();
JTextPane parentTextPane = parentEkit.getTextPane();
String selText = parentTextPane.getSelectedText();
int textLength = -1;
if(selText != null)
{
textLength = selText.length();
}
if(selText == null || textLength < 1)
{
SimpleInfoDialog sidWarn = new SimpleInfoDialog(parentEkit.getFrame(), Translatrix.getTranslationString("Error"), true, Translatrix.getTranslationString("ErrorNoTextSelected"), SimpleInfoDialog.ERROR);
}
else
{
int caretOffset = parentTextPane.getSelectionStart();
int internalTextLength = selText.length();
String currentAnchor = "";
// Somewhat ham-fisted code to obtain the first HREF in the selected text,
// which (if found) is passed to the URL HREF request dialog.
if(htmlTag.toString().equals(HTML.Tag.A.toString()))
{
SimpleAttributeSet sasText = null;
for(int i = caretOffset; i < caretOffset + internalTextLength; i++)
{
parentTextPane.select(i, i + 1);
sasText = new SimpleAttributeSet(parentTextPane.getCharacterAttributes());
Enumeration attribEntries1 = sasText.getAttributeNames();
while(attribEntries1.hasMoreElements() && currentAnchor.equals(""))
{
Object entryKey = attribEntries1.nextElement();
Object entryValue = sasText.getAttribute(entryKey);
if(entryKey.toString().equals(HTML.Tag.A.toString()))
{
if(entryValue instanceof SimpleAttributeSet)
{
Enumeration subAttributes = ((SimpleAttributeSet)entryValue).getAttributeNames();
while(subAttributes.hasMoreElements() && currentAnchor.equals(""))
{
Object subKey = subAttributes.nextElement();
if(subKey.toString().toLowerCase().equals("href"))
{
currentAnchor = ((SimpleAttributeSet)entryValue).getAttribute(subKey).toString();
break;
}
}
}
}
}
if(!currentAnchor.equals("")) { break; }
}
}
parentTextPane.select(caretOffset, caretOffset + internalTextLength);
SimpleAttributeSet sasTag = new SimpleAttributeSet();
SimpleAttributeSet sasAttr = new SimpleAttributeSet();
if(htmlTag.toString().equals(HTML.Tag.A.toString()))
{
if(!htmlAttribs.containsKey("href"))
{
UserInputAnchorDialog uidInput = new UserInputAnchorDialog(parentEkit, Translatrix.getTranslationString("AnchorDialogTitle"), true, currentAnchor);
String newAnchor = uidInput.getInputText();
uidInput.dispose();
if(newAnchor != null)
{
htmlAttribs2.put("href", newAnchor);
}
else
{
parentEkit.repaint();
return;
}
}
}
else if(htmlTag.toString().equals(HTML.Tag.FONT.toString()))
{
if(htmlAttribs.containsKey("color"))
{
Color color = new JColorChooser().showDialog(parentEkit.getFrame(), Translatrix.getTranslationString("CustomColorDialog"), Color.black);
if(color != null)
{
StyledEditorKit.ForegroundAction customColorAction = new StyledEditorKit.ForegroundAction("CustomColor", color);
customColorAction.actionPerformed(ae);
}
}
}
if(htmlAttribs2.size() > 0)
{
Enumeration attribEntries = htmlAttribs2.keys();
while(attribEntries.hasMoreElements())
{
Object entryKey = attribEntries.nextElement();
Object entryValue = htmlAttribs2.get(entryKey);
insertAttribute(sasAttr, entryKey, entryValue);
}
SimpleAttributeSet baseAttrs = new SimpleAttributeSet(parentEkit.getTextPane().getCharacterAttributes());
Enumeration attribEntriesOriginal = baseAttrs.getAttributeNames();
while(attribEntriesOriginal.hasMoreElements())
{
Object entryKey = attribEntriesOriginal.nextElement();
Object entryValue = baseAttrs.getAttribute(entryKey);
insertAttribute(sasAttr, entryKey, entryValue);
}
sasTag.addAttribute(htmlTag, sasAttr);
parentTextPane.setCharacterAttributes(sasTag, false);
parentEkit.refreshOnUpdate();
}
parentTextPane.select(caretOffset, caretOffset + internalTextLength);
parentTextPane.requestFocus();
}
}
}
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);
}
// map CSS font-family declarations to FONT tag face declarations
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);
}
}
// map CSS font-size declarations to FONT tag size declarations
/*
if(key.toString().toLowerCase().equals("font-size"))
{
if(attrs.isDefined("size"))
{
insertAttr(attrs, "size", attrs.getAttribute("size"));
insertAttr(attrs, "font-size", attrs.getAttribute("size"));
}
else
{
insertAttr(attrs, "size", value);
}
}
*/
}
private void insertAttr(SimpleAttributeSet attrs, Object key, Object value)
{
while(attrs.isDefined(key))
{
attrs.removeAttribute(key);
}
attrs.addAttribute(key, value);
}
}