diff --git a/src/net/java/sip/communicator/plugin/desktoputil/ExtendedTransferHandler.java b/src/net/java/sip/communicator/plugin/desktoputil/ExtendedTransferHandler.java index 9a230179c..a65789db6 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/ExtendedTransferHandler.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/ExtendedTransferHandler.java @@ -16,6 +16,9 @@ import javax.swing.*; import javax.swing.text.*; +import javax.swing.text.html.*; + +import java.util.regex.*; /** * A TransferHandler that we use to handle copying, pasting and DnD operations. @@ -36,6 +39,17 @@ public class ExtendedTransferHandler */ private static final long serialVersionUID = 0L; + /** + * HTML Editor Kit used to load and parse the selected html string + */ + private HTMLEditorKit htmlKit = new HTMLEditorKit(); + + /** + * HTML Document for the htmlKit. + */ + private HTMLDocument htmlDoc + = (HTMLDocument) htmlKit.createDefaultDocument(); + /** * Returns the type of transfer actions supported by the source; * any bitwise-OR combination of COPY, MOVE @@ -115,6 +129,8 @@ protected Transferable createTransferable(JComponent component) * Handles transport (cut and copy) from the chat panel to * clipboard. This method will only transfer plain text and would * explicitly ignore any formatting. + * If the selected text is HTML the images will be replaced with the + * content of the alt attribute. *
* @param comp the component holding the data to be transferred;
* provided to enable sharing of TransferHandlers
@@ -138,13 +154,12 @@ public void exportToClipboard(JComponent comp,
JTextComponent textComponent = (JTextComponent)comp;
int startIndex = textComponent.getSelectionStart();
int endIndex = textComponent.getSelectionEnd();
- if (startIndex != endIndex)
+ try
{
- try
+ Document doc = textComponent.getDocument();
+ String srcData = getSelectedTextFromComponent(textComponent);
+ if(srcData != null)
{
- Document doc = textComponent.getDocument();
- String srcData = doc.getText(startIndex,
- endIndex - startIndex);
StringSelection contents = new StringSelection(srcData);
// this may throw an IllegalStateException,
@@ -157,12 +172,91 @@ public void exportToClipboard(JComponent comp,
doc.remove(startIndex, endIndex - startIndex);
}
}
- catch (BadLocationException ble)
+ }
+ catch (BadLocationException ble)
+ {
+ //we simply ignore
+ }
+ }
+ }
+
+ /**
+ * Gets the selected text and if the text is HTML replaces the images with
+ * the content in ALT attribute.
+ * @param textComponent the component which contains the selected data
+ * @return selected text
+ */
+ public String getSelectedTextFromComponent(JTextComponent textComponent)
+ {
+ String srcData = null;
+ int startIndex = textComponent.getSelectionStart();
+ int endIndex = textComponent.getSelectionEnd();
+
+ if (startIndex != endIndex)
+ {
+ Document doc = (Document)textComponent.getDocument();
+ int selectionLength = endIndex - startIndex;
+ try
+ {
+ if (textComponent instanceof JTextPane)
{
- //we simply ignore
+ JTextPane textPaneComponent = (JTextPane)textComponent;
+
+ StringWriter stringWriter = new StringWriter();
+ textPaneComponent.getEditorKit().write(stringWriter,
+ doc, startIndex, selectionLength);
+ String data = stringWriter.toString();
+
+ String smileyHtmlPattern = "<\\s*[iI][mM][gG](.*?)" +
+ "[aA][lL][tT]\\s*=\\s*[\\\"']([^\\\"]*)" +
+ "[\\\"'](.*?)>";
+
+ Pattern p
+ = Pattern.compile(smileyHtmlPattern,Pattern.DOTALL);
+ Matcher m = p.matcher(data);
+ if(m.find())
+ {
+ /*
+ * Remove the PLAINTEXT tags because they brake the
+ * HTML
+ */
+ data = data.replaceAll(
+ "<[/]*PLAINTEXT>.*<[/]*PLAINTEXT>", "");
+
+ /*
+ * The getText method ignores the BR tag,
+ * empty A tag is replaced with \n
+ */
+ data = data.replaceAll(
+ "<\\s*[bB][rR][^>]*>", "");
+ data = data.replaceAll(smileyHtmlPattern, "$2");
+ htmlDoc.remove(0, htmlDoc.getLength());
+ htmlKit.read(new StringReader(data), htmlDoc, 0);
+
+ srcData = htmlDoc.getText(0, htmlDoc.getLength());
+ }
}
+
+ if(srcData == null)
+ {
+ srcData = doc.getText(startIndex, selectionLength);
+ }
+ }
+ catch (BadLocationException ble)
+ {
+ /*
+ * we simply ignore
+ */
+ }
+ catch (IOException ioe)
+ {
+ /*
+ * we simply ignore
+ */
}
}
+
+ return srcData;
}
/**
@@ -219,8 +313,9 @@ public Object getTransferData(DataFlavor flavor)
{
throw new UnsupportedFlavorException(flavor);
}
-
- return textComponent.getSelectedText();
+
+ String data = getSelectedTextFromComponent(textComponent);
+ return ((data == null)? "" : data);
}
}