package nota.oxygen.dtbook; import java.awt.Dimension; import java.io.File; import java.io.FilenameFilter; import java.net.MalformedURLException; import java.net.URL; import javax.swing.text.BadLocationException; import nota.oxygen.common.BaseAuthorOperation; import nota.oxygen.common.Utils; 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.AttrValue; import ro.sync.ecss.extensions.api.node.AuthorElement; import ro.sync.ecss.extensions.api.node.AuthorNode; /** * @author OHA * */ public class InsertImageGroupOperation extends BaseAuthorOperation { private static String ARG_IMGGROUP_FRAGMENT = "imggroup fragment"; private String imggroupFragment; private static String ARG_DO_FIXUP = "fixup mode"; private static String[] YES_NO = new String[]{"yes", "no"}; private boolean doFixup; @Override public ArgumentDescriptor[] getArguments() { return new ArgumentDescriptor[] { new ArgumentDescriptor(ARG_IMGGROUP_FRAGMENT, ArgumentDescriptor.TYPE_FRAGMENT, "Imagegroup fragment - $image is placeholder for the image file URL, $height and $width for image height and width respectively"), new ArgumentDescriptor(ARG_DO_FIXUP, ArgumentDescriptor.TYPE_CONSTANT_LIST, "Choose if the imageref attribute should be updated on the inserted caption element", YES_NO, YES_NO[1]) }; } @Override public String getDescription() { return "Insert an image group"; } private void insertImageGroup(String relImageURL) throws AuthorOperationException { URL imageURL; try { imageURL = new URL(getAuthorAccess().getDocumentController().getAuthorDocumentNode().getXMLBaseURL(), relImageURL); } catch (MalformedURLException e1) { return; } if (relImageURL.contains("*")||relImageURL.contains("?")) { } String height = ""; String width = ""; Dimension imageDim = Utils.getImageDimension(imageURL); if (imageDim!=null) { height = String.format("%1$d", imageDim.height); width = String.format("%1$d", imageDim.width); } if (imggroupFragment==null) throw new AuthorOperationException(ARG_IMGGROUP_FRAGMENT+" argument is null"); String imggroupXml = imggroupFragment.replace("$image", relImageURL).replace("$height", height).replace("$width", width); int offset = getAuthorAccess().getEditorAccess().getCaretOffset(); getAuthorAccess().getDocumentController().insertXMLFragment(imggroupXml, offset); if (doFixup) { try { AuthorNode aNode = getAuthorAccess().getDocumentController().getNodeAtOffset(offset+1); if (aNode instanceof AuthorElement) { AuthorElement imggroup = getSelfOrAncestorElementByLocalName((AuthorElement)aNode, "imggroup"); if (imggroup!=null) { AuthorElement[] captions = imggroup.getElementsByLocalName("caption"); if (captions.length==1) { AuthorElement[] imgs = imggroup.getElementsByLocalName("img"); String imgrefAttrValue = ""; for (int i=0; i<imgs.length; i++) { String val = imgs[i].getAttribute("id").getValue(); if (val!=null) imgrefAttrValue += val+" "; } if (!imgrefAttrValue.trim().equals("")) { getAuthorAccess().getDocumentController().setAttribute("imgref", new AttrValue(imgrefAttrValue), captions[0]); } } else { showMessage("Cannot set caption idref, when the image group contains multiple captions"); } } } } catch (BadLocationException e) { //Ignore } } try { AuthorNode aNode = getAuthorAccess().getDocumentController().getNodeAtOffset(offset+1); if (aNode instanceof AuthorElement) { getAuthorAccess().getEditorAccess().setCaretPosition(aNode.getEndOffset()+1); } } catch (BadLocationException e) { //Ignore } } private String[] getURLsFromPattern(String relPattern) throws AuthorOperationException { URL patternURL; try { patternURL = new URL(getAuthorAccess().getDocumentController().getAuthorDocumentNode().getXMLBaseURL(), relPattern); } catch (MalformedURLException e1) { throw new AuthorOperationException("Could not construct URL from "+relPattern, e1); } String patternPath = patternURL.getPath(); if (patternPath=="") throw new AuthorOperationException("Patterns are only supported for file URLs"); File relF = new File(patternPath); final String regEx = relF.getName().replace(".", "\\.").replace("*", ".*").replace("?", "."); File d = relF.getParentFile(); if (!d.isDirectory()) throw new AuthorOperationException("Parent is unexpectedly not a directory"); if (!d.exists()) throw new AuthorOperationException("Parent directory does not exist"); FilenameFilter ff = new FilenameFilter() { public boolean accept(File f, String n) { return n.matches(regEx); } }; return d.list(ff); } @Override protected void doOperation() throws AuthorOperationException { URL imageURL = getAuthorAccess().getWorkspaceAccess().chooseURL("Select image file (use */? for wildcards)", new String[] {"jpg", "png"}, "JPEG|PNG"); if (imageURL==null) return; String relImageURL = getAuthorAccess().getUtilAccess().makeRelative( getAuthorAccess().getDocumentController().getAuthorDocumentNode().getXMLBaseURL(), imageURL); //String relImageURL = ro.sync.ecss.extensions.commons.ImageFileChooser.chooseImageFile(getAuthorAccess()); if (relImageURL==null) return; if (relImageURL.contains("*")||relImageURL.contains("?")) { String[] relImageURLs = getURLsFromPattern(relImageURL); if (relImageURLs.length==0) { showMessage("No images matches pattern "+relImageURL); return; } int res = getAuthorAccess().getWorkspaceAccess().showConfirmDialog( getDescription(), "Do you wish to insert "+relImageURLs.length+" images matching "+relImageURL, new String[] {"Yes", "No"}, new int[] {1, 0}); if (res==0) return; for (int i=0; i<relImageURLs.length; i++) { insertImageGroup(relImageURLs[i]); } } else { insertImageGroup(relImageURL); } } private AuthorElement getSelfOrAncestorElementByLocalName(AuthorElement elem, String localName) { if (elem.getLocalName().equals(localName)) return elem; if (elem.getParent() instanceof AuthorElement) { return getSelfOrAncestorElementByLocalName((AuthorElement)elem.getParent(), localName); } return null; } @Override protected void parseArguments(ArgumentsMap args) throws IllegalArgumentException { imggroupFragment = (String)args.getArgumentValue(ARG_IMGGROUP_FRAGMENT); String fixupMode = (String)args.getArgumentValue(ARG_DO_FIXUP); doFixup = YES_NO[0].equals(fixupMode); } }