Filter pasted content in Text page?

Oxygen general issues.
craig_sandvik
Posts: 5
Joined: Thu Dec 08, 2011 10:41 pm

Filter pasted content in Text page?

Post by craig_sandvik »

Hi,
Is there any way to hook into the paste action in the Text page? Into drag-and-drop handling on the Text page?

We need an attribute removed from pasted content. With much help from forum searches, I was able to hook filters into the Paste and Paste As XML actions on the Author page (and they majically filter drag-and-drop content as well). I can't find any thing in the API docs or forum searches that suggests how to do the same for the Text page.

thanks,
- craig
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Filter pasted content in Text page?

Post by Radu »

Hi Craig,

This might be possible if you are implementing a WorkspaceAccess plugin type.
You can get access to the selected WSEditor and if the current page is a WSTextEditorPage, use this method:

Code: Select all

ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage.getTextComponent()
to gain access to the used internal swing JTextArea.
A swing JComponent has an action map inside it and one approach would be to take from the action map the action corresponding to the "paste" key and wrap it in your own action.

For example if you wrap the default swing "paste" action in your own action, you could first look in the clipboard and if it contains simple text which has a certain attribute there, remove the attribute from the string and set it back in the clipboard, then run the default action.
Something like:

Code: Select all

            if(editorAccess != null && editorAccess.getCurrentPage() instanceof WSTextEditorPage) {
WSTextEditorPage tp = (WSTextEditorPage) editorAccess.getCurrentPage();
JTextArea textComponent = (JTextArea) tp.getTextComponent();
final Action defaultPasteAction = textComponent.getActionMap().get("paste");
textComponent.getActionMap().put("paste", new AbstractAction(
(String)defaultPasteAction.getValue(AbstractAction.NAME)) {
@Override
public void actionPerformed(ActionEvent e) {
Transferable contents = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if(contents != null) {
if(contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
String stringContents;
try {
stringContents = (String) contents.getTransferData(DataFlavor.stringFlavor);
if(stringContents.contains("to_be_removed")) {
//Pre-process it and set back to clipboard
stringContents = "MODIFIED";
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(stringContents), null);
}
} catch (UnsupportedFlavorException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
//Perform default behavior
defaultPasteAction.actionPerformed(e);
}
});
}
The drag and drop is trickier.
You can set a document filter on the document from the text page which can decide to sometimes modify the inserted string like:

Code: Select all

            if(editorAccess != null && editorAccess.getCurrentPage() instanceof WSTextEditorPage) {
WSTextEditorPage tp = (WSTextEditorPage) editorAccess.getCurrentPage();
((AbstractDocument)tp.getDocument()).setDocumentFilter(new DocumentFilter() {
/**
* @see javax.swing.text.DocumentFilter#replace(javax.swing.text.DocumentFilter.FilterBypass, int, int, java.lang.String, javax.swing.text.AttributeSet)
*/
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
if(text != null && text.contains("to_be_removed")) {
//You can either decide to remote the offending data here no matter of the
//source from where it came from.
//or if you want to remove it only for dropped text you can use this hack
boolean isDnD = false;
StackTraceElement[] stackTrace = new Exception().getStackTrace();
for (int i = 0; i < stackTrace.length; i++) {
if("java.awt.dnd.DropTarget".equals(stackTrace[i].getClassName())) {
isDnD = true;
break;
}
}
if(isDnD) {
text = "MODIFIED";
}
}
super.replace(fb, offset, length, text, attrs);
}
});
}
Of course this second approach could also be used for the first use case.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
craig_sandvik
Posts: 5
Joined: Thu Dec 08, 2011 10:41 pm

Re: Filter pasted content in Text page?

Post by craig_sandvik »

Thanks for the quick response. I've been working on other parts of our customization and just got back to this.

We are running the Eclipse version, and our code runs in a customized DITA framework. Does your javax.swing.text.DocumentFilter example below work the same in the Eclipse version?

A bigger question is how to reliably get our custom code associated with the WSTextEditor instance. The framework extension bundle does not activate until the Author page is displayed. When a new editor opens with Text as the initial page, the extension bundle does not activate and none of the custom code runs.

It looks like maybe we can run code in a separate Eclipse plug-in that uses a workspace part listener to watch for any instance of Oxygen. Are there other options?

thanks,
- craig
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Filter pasted content in Text page?

Post by Radu »

Hi Craig,

So my explanation above was mostly for the standalone Oxygen distribution.

What most integrators do for Eclipse is to provide along with our plugin for Eclipse a custom plugin which indeed uses a Workbench part listener to see when a part was opened with Oxygen. Such an opened part should be an instance of ro.sync.exml.workspace.api.editor.WSEditor.

So you can use the same API to see if a WSTextEditorPage is currently selected in the opened editor and get access to the ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage.getTextComponent().

In the case of Eclipse, the text component is actually a org.eclipse.swt.custom.StyledText.

Maybe you can add a verify listener to it org.eclipse.swt.custom.StyledText.addVerifyListener(VerifyListener) and somehow modify the text in the event before propagating it to the other listeners, but this needs to be tested of course.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply