From: Alexander S. <as...@us...> - 2006-07-24 11:53:34
|
Update of /cvsroot/jxtaim/jxtaim/src/vsis/im/view/util In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv21042/src/vsis/im/view/util Modified Files: BBStyledEditorKit.java Log Message: New autodetect and display URL and URI feature for rich BB editor kit. Hyperlink events are properly emitted if mouse click on such a link happens. Index: BBStyledEditorKit.java =================================================================== RCS file: /cvsroot/jxtaim/jxtaim/src/vsis/im/view/util/BBStyledEditorKit.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** BBStyledEditorKit.java 23 Jul 2006 17:23:27 -0000 1.2 --- BBStyledEditorKit.java 24 Jul 2006 11:53:28 -0000 1.3 *************** *** 26,37 **** --- 26,48 ---- package vsis.im.view.util; + import java.awt.Color; import java.awt.event.ActionEvent; + import java.awt.event.MouseAdapter; + import java.awt.event.MouseEvent; + import java.awt.event.MouseMotionAdapter; import java.io.IOException; import java.io.Reader; import java.io.Writer; + import java.net.MalformedURLException; + import java.net.URI; + import java.net.URISyntaxException; + import java.net.URL; import java.util.LinkedList; import java.util.ListIterator; import javax.swing.JEditorPane; + import javax.swing.event.CaretEvent; + import javax.swing.event.CaretListener; + import javax.swing.event.HyperlinkEvent; import javax.swing.text.AbstractDocument; import javax.swing.text.AttributeSet; *************** *** 39,49 **** --- 50,63 ---- import javax.swing.text.BoxView; import javax.swing.text.ComponentView; + import javax.swing.text.DefaultStyledDocument; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.IconView; import javax.swing.text.LabelView; + import javax.swing.text.MutableAttributeSet; import javax.swing.text.ParagraphView; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; + import javax.swing.text.StyledDocument; import javax.swing.text.StyledEditorKit; import javax.swing.text.View; *************** *** 137,140 **** --- 151,205 ---- } + // action classes + static public class BBUrlifyAction extends StyledEditorKit.StyledTextAction + { + public BBUrlifyAction() + { + super("URL"); + } + + public void actionPerformed(ActionEvent e) { + JEditorPane editor = getEditor(e); + BBStyledEditorKit editorKit = (BBStyledEditorKit) editor.getEditorKit(); + + String potentialUrl = editor.getSelectedText(); + URL parsedUrl = null; + try { + parsedUrl = new URL(potentialUrl); + } catch (MalformedURLException e1) { + } + + if(parsedUrl != null) + { + SimpleAttributeSet anAttributeSet = + new SimpleAttributeSet(editorKit.getCharacterAttributeRun().getAttributes()); + + Object oldValue = editorKit.getCharacterAttributeRun().getAttributes().getAttribute("URL"); + if(oldValue != null && "true".equals(oldValue)) + { + anAttributeSet.removeAttribute("URL"); + } else { + anAttributeSet.addAttribute("URL","true"); + } + + setCharacterAttributes(editor, anAttributeSet, true); + } else { + SimpleAttributeSet anAttributeSet = + new SimpleAttributeSet(editorKit.getCharacterAttributeRun().getAttributes()); + + Object oldValue = editorKit.getCharacterAttributeRun().getAttributes().getAttribute("URL"); + if(oldValue != null && "true".equals(oldValue)) + { + anAttributeSet.removeAttribute("URL"); + } + + setCharacterAttributes(editor, anAttributeSet, true); + } + } + } + + + private JEditorPane installedEditor; + public BBStyledEditorKit() { super(); *************** *** 179,182 **** --- 244,388 ---- } + public void install(final JEditorPane c) { + if(c.isEditable()) + c.setToolTipText("JUXIM BBCode Editor"); + else + c.setToolTipText("JUXIM BBCode Viewer"); + + c.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + + int caretPos = c.viewToModel(e.getPoint()); + if(caretPos > -1) + { + Element elem = ((DefaultStyledDocument) c.getDocument()).getCharacterElement(caretPos); + if(elem == null) + return; + + String urlString = null; + try { + urlString = c.getDocument().getText(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset()); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } + + if(urlString != null) + { + Object urlValue = ((MutableAttributeSet)elem.getAttributes()).getAttribute("URL"); + if( urlValue != null) + { + URL url = null; + try { + url = new URL(urlString); + } catch (MalformedURLException e2) { + } + + if(url != null) + { + HyperlinkEvent e1 = new HyperlinkEvent(c, HyperlinkEvent.EventType.ACTIVATED, url); + c.fireHyperlinkUpdate(e1); + } + } + } + } + } + }); + + c.addMouseMotionListener(new MouseMotionAdapter() + { + Element current = null; + AttributeSet oldSet = null; + URL currentRealUrl = null; + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + int caretPos = c.viewToModel(e.getPoint()); + if(caretPos > -1) + { + Element elem = ((DefaultStyledDocument) c.getDocument()).getCharacterElement(caretPos); + if(elem == null) + return; + + String urlString = null; + try { + urlString = c.getDocument().getText(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset()); + } catch (BadLocationException e1) { + e1.printStackTrace(); + } + //System.out.println("Elem : "+elem); + if(elem != current && current != null){ + MutableAttributeSet newSet = new SimpleAttributeSet(oldSet); + newSet.removeAttribute("URLOVER"); + + ((StyledDocument)c.getDocument()).setCharacterAttributes(current.getStartOffset(), + current.getEndOffset() - current.getStartOffset(), + newSet, + true); + current = null; + oldSet = null; + + if(c.isEditable()) + c.setToolTipText("JUXIM BBCode Editor"); + else + c.setToolTipText("JUXIM BBCode Viewer"); + + if(currentRealUrl != null) + { + HyperlinkEvent e1 = new HyperlinkEvent(c, HyperlinkEvent.EventType.EXITED, currentRealUrl); + c.fireHyperlinkUpdate(e1); + currentRealUrl = null; + } + } + + if(urlString != null) + { + Object urlValue = ((MutableAttributeSet)elem.getAttributes()).getAttribute("URL"); + if( urlValue != null) + { + try { + currentRealUrl = new URL(urlString); + } catch (MalformedURLException e2) { + + } + + if(currentRealUrl != null) + { + current = elem; + oldSet = new SimpleAttributeSet(elem.getAttributes().copyAttributes()); + MutableAttributeSet newSet = new SimpleAttributeSet(oldSet); + newSet.addAttribute("URLOVER", "true"); + newSet.addAttribute("URL", "true"); + + ((StyledDocument)c.getDocument()).setCharacterAttributes(current.getStartOffset(), + current.getEndOffset() - current.getStartOffset(), + newSet, + true); + + c.setToolTipText("URL: " + urlString); + + + HyperlinkEvent e1 = new HyperlinkEvent(c, HyperlinkEvent.EventType.ENTERED, currentRealUrl); + c.fireHyperlinkUpdate(e1); + } + } + } + + } + } + }); + c.addCaretListener(new CaretListener() + { + public void caretUpdate(CaretEvent e) { + + } + }); + super.install(c); + installedEditor = c; + } + protected AttributeSet mapAttributeSetForRendering(AttributeSet set) { SimpleAttributeSet renderAttributes = new SimpleAttributeSet(); *************** *** 196,200 **** StyleConstants.setUnderline(renderAttributes, true); } ! // TODO ... all other BB tags must be mapped too here return renderAttributes; --- 402,417 ---- StyleConstants.setUnderline(renderAttributes, true); } ! ! if("true".equals(set.getAttribute("URL"))) ! { ! StyleConstants.setUnderline(renderAttributes, true); ! StyleConstants.setForeground(renderAttributes, Color.BLUE); ! } ! ! if("true".equals(set.getAttribute("URLOVER"))) ! { ! StyleConstants.setForeground(renderAttributes, Color.RED); ! } ! // TODO ... all other BB tags must be mapped too here return renderAttributes; *************** *** 233,237 **** String curContent = ""; SimpleAttributeSet curSet = new SimpleAttributeSet(); - while(next > -1) { --- 450,453 ---- *************** *** 255,259 **** if(curContent.length() > 0) { ! doc.insertString(pos + offset, curContent, curSet.copyAttributes()); offset += curContent.length(); curContent = ""; --- 471,475 ---- if(curContent.length() > 0) { ! doc.insertString(pos + offset, curContent, new SimpleAttributeSet(curSet)); offset += curContent.length(); curContent = ""; *************** *** 285,290 **** { curContent += fullSource.substring(cur); ! doc.insertString(pos + offset, curContent, curSet.copyAttributes()); } } --- 501,571 ---- { curContent += fullSource.substring(cur); ! doc.insertString(pos + offset, curContent, new SimpleAttributeSet(curSet)); } + + // first, remove all URL attributes from all elements currently in this kit + StyledDocument sDoc = (StyledDocument) doc; + Element lastElement = null; + for(int j = 0; j < doc.getLength(); j++) + { + Element maybeNew = sDoc.getCharacterElement(j); + if(maybeNew != lastElement) + { + lastElement = maybeNew; + if (maybeNew.getAttributes().getAttribute("URL") != null) + { + SimpleAttributeSet newSet = new SimpleAttributeSet(maybeNew.getAttributes()); + newSet.removeAttribute("URL"); + newSet.removeAttribute("URLOVER"); + sDoc.setCharacterAttributes(maybeNew.getStartOffset(), maybeNew.getEndOffset() - maybeNew.getStartOffset(), newSet, true); + } + } + } + + // second, parse and mark url runs + String fullText = doc.getText(0, doc.getLength()); + String splits[] = fullText.split("[ \t\n]"); + int realOffs = 0; + for(int i = 0; i < splits.length; i++) + { + URL maybeUrl = null; + URI maybeUri = null; + // lets do it dirty: exception decides if this is a valid url + try { + maybeUrl = new URL(splits[i]); + } catch (MalformedURLException e) { + } + + if(maybeUrl == null) + { + try { + maybeUri = new URI(splits[i]); + + if(!uriHasHandler(maybeUri)) + maybeUri = null; + } catch (URISyntaxException e) { + } + } + + if(maybeUrl != null || maybeUri != null) + { + realOffs = fullText.indexOf(splits[i], realOffs); + // we have an url ... now mark the run (from offset to offset + maybeUrl.length() + MutableAttributeSet newSet = new SimpleAttributeSet(); + newSet.addAttribute("URL", "true"); + + if(maybeUrl != null) + ((StyledDocument) doc).setCharacterAttributes(realOffs, maybeUrl.toString().length(), newSet, false); + else + ((StyledDocument) doc).setCharacterAttributes(realOffs, maybeUri.toString().length(), newSet, false); + } + } + } + + private boolean uriHasHandler(URI maybeUri) { + + if(maybeUri.getScheme() != null) + return true; + return false; } *************** *** 306,310 **** private void writeElement(Writer out, Element element, int pos, int len) throws IOException, BadLocationException { ! AttributeSet copySet = element.getAttributes().copyAttributes(); LinkedList<String> surroundingTags = new LinkedList<String>(); --- 587,591 ---- private void writeElement(Writer out, Element element, int pos, int len) throws IOException, BadLocationException { ! AttributeSet copySet = element.getAttributes(); LinkedList<String> surroundingTags = new LinkedList<String>(); *************** *** 321,324 **** --- 602,609 ---- surroundingTags.addLast("U"); } + if(copySet.containsAttribute("URL", "true")) + { + surroundingTags.addLast("URL"); + } ListIterator i = surroundingTags.listIterator(); |