Page 1 of 1

Folding a node via code in Author View

Posted: Wed Jan 21, 2015 5:33 pm
by DirkDubois
Hello,

I am developing an plugin for XML Author, specifically for the Author View. I want to be able to collapse (fold) all nodes of a particular name on a page. I am able to retrieve these nodes as AuthorNode's using AuthorDocumentController. However, I can't seem to figure out how to collapse/fold them. I am aware there is an isFolded() property associated with the Styles of the node, but I am not sure if this is the property that should be adjusted.

Thanks in advance for all your help.

Sincerely,
Dirk Dubois

Re: Folding a node via code in Author View

Posted: Thu Jan 22, 2015 10:49 am
by alex_jitianu
Hello Dirk,

Since you are developing a plugin I suggest to use a StylesFilter Plugin Extension. A plugin can have any number of extensions. From this extension you can set fold information like this:

Code: Select all

public Styles filter(Styles styles, AuthorNode authorNode) {
styles.setProperty(Styles.KEY_FOLDED, true);
styles.setProperty(Styles.KEY_FOLDABLE, true);
styles.setProperty(Styles.KEY_NON_FOLDABLE_CHILD_NAME, new String[] {"title"});
return styles;
}
I suppose that you have an action from which you decide to fold those elements? If that is true then from that code you need to call a refresh on the nodes from which the fold property has changed:

Code: Select all

AuthorNode[] findNodesByXPath = authorAccess.getDocumentController().findNodesByXPath("//toFold", true, true, true);
for (int i = 0; i < findNodesByXPath.length; i++) {
authorAccess.getEditorAccess().refresh(findNodesByXPath[i]);
}
You also have an issue recorded to add a more specific folding API so I will add your vote for it.

Best regards,
Alex

Re: Folding a node via code in Author View

Posted: Mon Mar 02, 2015 11:04 pm
by DirkDubois
Hello,

I recently tried implementing your solution, but I am having some trouble. I have an action that runs the collapseSelection method and using some prompts I was able to determine that there are nodes being selected in my document and that there styles are being changed. However, I do not see a visual difference in the Author view. I am calling the refresh function on the nodes that have been altered.

The following code shows my implementation. Any help would be greatly appreciated.

Code: Select all

private void collapseSelection(AuthorAccess authorAccess){
AuthorNode[] findNodesByXPath;
try {
findNodesByXPath = authorAccess.getDocumentController().findNodesByXPath("//note", true, true, true);
pluginWorkspaceAccess.showInformationMessage("Total found nodes: "+String.valueOf(findNodesByXPath.length));
for (int i = 0; i < findNodesByXPath.length; i++) {
AuthorNode currentNode = findNodesByXPath[i];
Styles styles = authorAccess.getEditorAccess().getStyles(currentNode);
filter(styles, currentNode);
authorAccess.getEditorAccess().refresh(currentNode);
}
} catch (AuthorOperationException e) {
// TODO Auto-generated catch block
pluginWorkspaceAccess.showErrorMessage(e.getMessage());
}

}

public Styles filter(Styles styles, AuthorNode authorNode) {

styles.setProperty(Styles.KEY_FOLDED, true);
styles.setProperty(Styles.KEY_FOLDABLE, true);
return styles;
}
Thanks,
Dirk

Re: Folding a node via code in Author View

Posted: Tue Mar 03, 2015 10:39 am
by alex_jitianu
Hello Dirk,

One thing that doesn't seem right is this call:

Code: Select all

Styles styles = authorAccess.getEditorAccess().getStyles(currentNode);
filter(styles, currentNode);
Oxygen will call filter() automatically on the nodes on which you called refresh(). I expect you are having two types of extensions:
1. a WorkspaceAccess which contributes actions. This is where the collapseSelection() method is invoked.
2. a StylesFilter to perform the Styles filtering.

Since Oxygen will create an instance for each extension you will have to communicate somehow between the two. Moreover, these two instances will be used for all open documents. WorkspaceAccess.collapseSelection() should add somewhere in a static/singleton the information that for this URL the elements with these local names must be collapsed. After that it invokes refresh() on the nodes. After this happens, GeneralStylesFilterExtension.filter() will be called automatically. At this point you should get the URL of the node, inspect that static/singleton for that URL and do the filtering:

Code: Select all

public class CustomStylesFilter extends GeneralStylesFilterExtension {
/**
* @see ro.sync.ecss.extensions.api.StylesFilter#filter(ro.sync.ecss.css.Styles, ro.sync.ecss.extensions.api.node.AuthorNode)
*/
@Override
public Styles filter(Styles styles, AuthorNode authorNode) {
String systemID = authorNode.getOwnerDocument().getSystemID();
List<String> localNames = FoldingStorage.getInstance().getFoldedElementNames(systemID);

if (localNames.contains(authorNode.getName())) {
styles.setProperty(Styles.KEY_FOLDED, true);
styles.setProperty(Styles.KEY_FOLDABLE, true);
}
return styles;
}
You might be interested to know that in the next version of Oxygen (17.0 is scheduled for May) we added API for folding.

Best regards,
Alex