package nota.oxygen.epub.headings;
import javax.swing.text.BadLocationException;
import nota.oxygen.common.BaseAuthorOperation;
import ro.sync.ecss.extensions.api.ArgumentDescriptor;
import ro.sync.ecss.extensions.api.ArgumentsMap;
import ro.sync.ecss.extensions.api.AuthorOperationException;
import ro.sync.ecss.extensions.api.node.AuthorDocumentFragment;
import ro.sync.ecss.extensions.api.node.AuthorElement;
public class RemoveHeadingOperation extends BaseAuthorOperation {
private static String ARG_HEADER_REPLACEMENT_FRAGMENT = "header replacement fragment";
private String headerReplacementFragment;
private static String ARG_PARENT_SECTION_LOCALNAME = "parent section localname";
private String parentSectionLocalName;
@Override
public ArgumentDescriptor[] getArguments() {
return new ArgumentDescriptor[]{
new ArgumentDescriptor(ARG_HEADER_REPLACEMENT_FRAGMENT, ArgumentDescriptor.TYPE_FRAGMENT, "Header replacement fragment"),
new ArgumentDescriptor(ARG_PARENT_SECTION_LOCALNAME, ArgumentDescriptor.TYPE_STRING, "Parent section localname")
};
}
@Override
protected void parseArguments(ArgumentsMap args)
throws IllegalArgumentException {
headerReplacementFragment = (String)args.getArgumentValue(ARG_HEADER_REPLACEMENT_FRAGMENT);
parentSectionLocalName = (String)args.getArgumentValue(ARG_PARENT_SECTION_LOCALNAME);
}
@Override
public String getDescription() {
return "Remove heading (and parent section), with the side-effect of updating the ePub navigation documents";
}
@Override
protected void doOperation() throws AuthorOperationException {
try {
int selectionStartBefore = getAuthorAccess().getEditorAccess().getSelectionStart();
int selectionEndBefore = getAuthorAccess().getEditorAccess().getSelectionEnd();
int selectionOffset = 0;
AuthorElement heading;
try {
heading = getCurrentElement();
} catch (BadLocationException e) {
throw new AuthorOperationException("No element was selected");
}
AuthorElement section = (AuthorElement)heading.getParent();
if (section == null) {
throw new AuthorOperationException("The selected element is the document root");
}
if (section.getParent() == null) {
throw new AuthorOperationException("The containing section of the heading to delete is the root of the document");
}
if (!section.getLocalName().equals(parentSectionLocalName)) {
throw new AuthorOperationException(String.format(
"The selected heading is not the child of a %s element", parentSectionLocalName));
}
getAuthorAccess().getDocumentController().surroundInFragment(
headerReplacementFragment,
heading.getStartOffset()+1,
heading.getEndOffset()-1);
AuthorDocumentFragment headingReplacementFragment = getAuthorAccess().getDocumentController().createDocumentFragment(
heading.getStartOffset()+1,
heading.getEndOffset()-1);
int offset = heading.getStartOffset();
getAuthorAccess().getDocumentController().deleteNode(heading);
getAuthorAccess().getDocumentController().insertFragment(offset, headingReplacementFragment);
AuthorElement prevSiblingWhenSection = findElementByXPath(
String.format("(preceding-sibling::*[1])[local-name()='%s']", parentSectionLocalName));
if (prevSiblingWhenSection == null && section.getElementsByLocalName("section").length > 0) {
throw new AuthorOperationException(
"Removing the selected heading will lead to inconsistent heading heirachy, since the heading is the first of its parent and has child sections");
}
AuthorDocumentFragment sectionContentFragment = getAuthorAccess().getDocumentController().createDocumentFragment(
section.getStartOffset()+1,
section.getEndOffset()-1);
int sectionStartOffset = section.getStartOffset();
if (!getAuthorAccess().getDocumentController().deleteNode(section)) {
throw new AuthorOperationException("Could not delete old section");
}
if (prevSiblingWhenSection != null) {
//if the preceding element of section is also a section, merge section with this
getAuthorAccess().getDocumentController().insertFragment(prevSiblingWhenSection.getEndOffset(), sectionContentFragment);
selectionOffset = -2;
}
else {
//insert
getAuthorAccess().getDocumentController().insertFragment(sectionStartOffset, sectionContentFragment);
selectionOffset = -1;
}
getAuthorAccess().getEditorAccess().select(selectionStartBefore+selectionOffset, selectionEndBefore+selectionOffset);
}
catch (AuthorOperationException e) {
throw e;
}
catch (Exception e) {
throw new AuthorOperationException(
String.format("An unexpected %s occured: %s",
e.getClass().getName(),
e.getMessage()),
e);
}
}
}