Support for docbook image object.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 20 Jan 2021 10:01:56 +0000 (11:01 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 20 Jan 2021 10:01:56 +0000 (11:01 +0100)
15 files changed:
publishing/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties [new file with mode: 0644]
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/AbstractTextViewer.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/CustomTextEditor.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/Paragraph.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/SectionTitle.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/StandardTextEditor.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/TextContextMenu.java
publishing/org.argeo.publishing.ui/src/org/argeo/cms/text/TextSection.java
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java [new file with mode: 0644]
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java [new file with mode: 0644]
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/AbstractDbkViewer.java
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkContextMenu.java
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java [new file with mode: 0644]
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkUtils.java [deleted file]
publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DocBookSectionTitle.java

diff --git a/publishing/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties b/publishing/org.argeo.publishing.ui/OSGI-INF/l10n/bundle.properties
new file mode 100644 (file)
index 0000000..77c5423
--- /dev/null
@@ -0,0 +1,10 @@
+paragraph=paragraph
+section=section
+media=media
+style=style
+
+deleteParagraph=delete paragraph
+deleteSection=delete section
+
+insertMedia=insert media
+deleteMedia=delete media
\ No newline at end of file
index c0a35d8817bff2d4b65e74c23c36ce4e278f1d95..74a9c81e523ed4b63976af7f232f1c3aa486eb8d 100644 (file)
@@ -50,6 +50,7 @@ import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Text;
 
 /** Base class for text viewers and editors. */
+@Deprecated
 public abstract class AbstractTextViewer extends AbstractPageViewer implements
                CmsNames, KeyListener, Observer {
        private static final long serialVersionUID = -2401274679492339668L;
index 2dd5b890f8217265738ba52afd19fe3546276c9c..c7690c71e68636c0f64a391099d6c4f416e0e255 100644 (file)
@@ -13,6 +13,7 @@ import org.eclipse.swt.widgets.Composite;
  * Manages hardcoded sections as an arbitrary hierarchy under the main section,
  * which contains no text and no title.
  */
+@Deprecated
 public class CustomTextEditor extends AbstractTextViewer {
        private static final long serialVersionUID = 5277789504209413500L;
 
index 6ff42815f261c71d16ac171c5b09a2f4a832e1c3..cfd02728a9872f58a068c6ee503994ccf5d94afd 100644 (file)
@@ -4,25 +4,23 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
 import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.viewers.Section;
 import org.argeo.cms.ui.viewers.SectionPart;
 import org.argeo.cms.ui.widgets.EditableText;
 import org.argeo.cms.ui.widgets.TextStyles;
 
-/** An editable paragraph.*/
+/** An editable paragraph. */
 public class Paragraph extends EditableText implements SectionPart {
        private static final long serialVersionUID = 3746457776229542887L;
 
        private final TextSection section;
 
-       public Paragraph(TextSection section, int style, Node node)
-                       throws RepositoryException {
+       public Paragraph(TextSection section, int style, Node node) throws RepositoryException {
                super(section, style, node);
                this.section = section;
                CmsUiUtils.style(this, TextStyles.TEXT_PARAGRAPH);
        }
 
-       public Section getSection() {
+       public TextSection getSection() {
                return section;
        }
 
index 8bd68c4a1434121f79cb45ec7ee0eac82f383183..1a67c11c58660a8cd7090d49ba47e4317182034a 100644 (file)
@@ -9,6 +9,7 @@ import org.argeo.cms.ui.widgets.EditableText;
 import org.eclipse.swt.widgets.Composite;
 
 /** The title of a section. */
+@Deprecated
 public class SectionTitle extends EditableText implements EditablePart,
                PropertyPart {
        private static final long serialVersionUID = -1787983154946583171L;
index f0f5042c89dd61f33e49a2e2ed863edb7728a5e4..3c3d16b0fab123fc43ca938bf8be3b32648c74ee 100644 (file)
@@ -12,6 +12,7 @@ import org.argeo.cms.ui.viewers.Section;
 import org.eclipse.swt.widgets.Composite;
 
 /** Text editor where sections and subsections can be managed by the user. */
+@Deprecated
 public class StandardTextEditor extends AbstractTextViewer {
        private static final long serialVersionUID = 6049661610883342325L;
 
index 8230bb3c69389c8eedbb1ff9d2ac1e16a815621c..f9cdbb53382a16045572c86759020bc1f54bdfbd 100644 (file)
@@ -20,6 +20,7 @@ import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Shell;
 
 /** Dialog to edit a text part. */
+@Deprecated
 class TextContextMenu extends Shell implements CmsNames, TextStyles {
        private final static String[] DEFAULT_TEXT_STYLES = {
                        TextStyles.TEXT_DEFAULT, TextStyles.TEXT_PRE, TextStyles.TEXT_QUOTE };
index 4f514bf763c4ad380262e9eb40c0863409c5ef28..894a2cf240d073c384f9d70f64789bca6bdf59da 100644 (file)
@@ -3,12 +3,15 @@ package org.argeo.cms.text;
 import javax.jcr.Node;
 
 import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.viewers.EditablePart;
 import org.argeo.cms.ui.viewers.Section;
 import org.argeo.cms.ui.widgets.TextStyles;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 
-public class TextSection extends Section implements CmsNames {
+/** An editable section. */
+public class TextSection extends Section {
        private static final long serialVersionUID = -8625209546243220689L;
        private String defaultTextStyle = TextStyles.TEXT_DEFAULT;
        private String titleStyle;
@@ -28,7 +31,7 @@ public class TextSection extends Section implements CmsNames {
        private TextSection(Composite parent, Section parentSection, int style, Node node) {
                super(parent, parentSection, style, node);
                flat = SWT.FLAT == (style & SWT.FLAT);
-               //CmsUiUtils.style(this, TextStyles.TEXT_SECTION);
+               // CmsUiUtils.style(this, TextStyles.TEXT_SECTION);
        }
 
        public String getDefaultTextStyle() {
@@ -61,6 +64,5 @@ public class TextSection extends Section implements CmsNames {
 
        public void setTitleReadOnly(boolean titleReadOnly) {
                this.titleReadOnly = titleReadOnly;
-       }
-
+       }       
 }
diff --git a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkMsg.java
new file mode 100644 (file)
index 0000000..6dc1c51
--- /dev/null
@@ -0,0 +1,14 @@
+package org.argeo.docbook;
+
+import org.argeo.cms.Localized;
+
+/** DocBook related messages. */
+public enum DbkMsg implements Localized {
+       paragraph, deleteParagraph,
+       //
+       section, deleteSection,
+       //
+       media, deleteMedia, insertMedia,
+       //
+       ;
+}
diff --git a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java
new file mode 100644 (file)
index 0000000..6a8da8e
--- /dev/null
@@ -0,0 +1,96 @@
+package org.argeo.docbook;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+import org.argeo.docbook.ui.DocBookNames;
+import org.argeo.docbook.ui.DocBookTypes;
+import org.argeo.entity.EntityNames;
+import org.argeo.entity.EntityType;
+import org.argeo.jcr.Jcr;
+import org.argeo.jcr.JcrException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.JcrxApi;
+
+/** Utilities around DocBook. */
+public class DbkUtils {
+       public static String getTitle(Node node) {
+               return JcrxApi.getXmlValue(node, DocBookTypes.TITLE);
+       }
+
+       public static void setTitle(Node node, String txt) {
+               try {
+                       Node titleNode = JcrUtils.getOrAdd(node, DocBookTypes.TITLE, DocBookTypes.TITLE);
+                       JcrxApi.setXmlValue(node, titleNode, txt);
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot add empty paragraph to " + node, e);
+               }
+       }
+
+       public static Node getMetadata(Node infoContainer) {
+               try {
+                       if (!infoContainer.hasNode(DocBookTypes.INFO))
+                               return null;
+                       Node info = infoContainer.getNode(DocBookTypes.INFO);
+                       if (!info.hasNode(EntityType.local.get()))
+                               return null;
+                       return info.getNode(EntityType.local.get());
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot retrieve metadata from " + infoContainer, e);
+               }
+       }
+
+       public static Node getChildByRole(Node parent, String role) {
+               try {
+                       NodeIterator baseSections = parent.getNodes();
+                       while (baseSections.hasNext()) {
+                               Node n = baseSections.nextNode();
+                               String r = Jcr.get(n, DocBookNames.DBK_ROLE);
+                               if (r != null && r.equals(role))
+                                       return n;
+                       }
+                       return null;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot get child from " + parent + " with role " + role, e);
+               }
+       }
+
+       public static Node addParagraph(Node node, String txt) {
+               try {
+                       Node para = node.addNode(DocBookTypes.PARA, DocBookTypes.PARA);
+                       JcrxApi.setXmlValue(node, para, txt);
+                       return para;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot add empty paragraph to " + node, e);
+               }
+       }
+
+       public static Node insertImageAfter(Node sibling) {
+               try {
+                       Node parent = sibling.getParent();
+                       Node mediaNode = parent.addNode(DocBookTypes.MEDIAOBJECT, DocBookTypes.MEDIAOBJECT);
+                       // TODO optimise?
+                       parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]",
+                                       sibling.getName() + "[" + sibling.getIndex() + "]");
+                       parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]",
+                                       mediaNode.getName() + "[" + mediaNode.getIndex() + "]");
+
+                       Node imageNode = mediaNode.addNode(DocBookTypes.IMAGEOBJECT, DocBookTypes.IMAGEOBJECT);
+                       Node infoNode = imageNode.addNode(DocBookTypes.INFO, DocBookTypes.INFO);
+                       Node imageDataNode = JcrUtils.copyBytesAsFile(infoNode, EntityType.box.get(), new byte[0]);
+                       imageDataNode.addMixin(EntityType.box.get());
+                       imageDataNode.setProperty(EntityNames.SVG_WIDTH, 0);
+                       imageDataNode.setProperty(EntityNames.SVG_LENGTH, 0);
+                       imageDataNode.addMixin(NodeType.MIX_MIMETYPE);
+                       return imageDataNode;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot insert empty image after " + sibling, e);
+               }
+       }
+
+       /** Singleton. */
+       private DbkUtils() {
+       }
+}
index 1b8a237cfcadc14c1642d84cb6661a4e132c5f72..b21f502eb43c2efe3f76bf8fa9ad3a3aaa0f1429 100644 (file)
@@ -18,7 +18,6 @@ import javax.jcr.nodetype.NodeType;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.text.Paragraph;
-import org.argeo.cms.text.SectionTitle;
 import org.argeo.cms.text.TextInterpreter;
 import org.argeo.cms.text.TextSection;
 import org.argeo.cms.ui.CmsEditable;
@@ -35,6 +34,7 @@ import org.argeo.cms.ui.widgets.EditableImage;
 import org.argeo.cms.ui.widgets.EditableText;
 import org.argeo.cms.ui.widgets.Img;
 import org.argeo.cms.ui.widgets.StyledControl;
+import org.argeo.entity.EntityType;
 import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.rap.fileupload.FileDetails;
@@ -71,7 +71,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
        protected AbstractDbkViewer(Section parent, int style, CmsEditable cmsEditable) {
                super(parent, style, cmsEditable);
                CmsView cmsView = CmsView.getCmsView(parent);
-               imageManager = cmsView.getImageManager();
+//             imageManager = cmsView.getImageManager();
+               imageManager = new DbkImageManager();
                flat = SWT.FLAT == (style & SWT.FLAT);
 
                if (getCmsEditable().canEdit()) {
@@ -105,21 +106,24 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                updateContent(title);
                        }
 
-                       for (NodeIterator ni = node.getNodes(DocBookNames.DBK_PARA); ni.hasNext();) {
+                       for (NodeIterator ni = node.getNodes(); ni.hasNext();) {
                                Node child = ni.nextNode();
-                               final SectionPart sectionPart;
-                               if (child.isNodeType(DocBookTypes.IMAGEDATA) || child.isNodeType(NodeType.NT_FILE)) {
-                                       // FIXME adapt to DocBook
-                                       sectionPart = newImg(textSection, child);
+                               SectionPart sectionPart = null;
+                               if (child.isNodeType(DocBookTypes.MEDIAOBJECT)) {
+                                       if (child.hasNode(DocBookTypes.IMAGEOBJECT)) {
+                                               Node imageNode = child.getNode(DocBookTypes.IMAGEOBJECT).getNode(DocBookTypes.INFO)
+                                                               .getNode(EntityType.box.get());
+                                               sectionPart = newImg(textSection, imageNode);
+                                       }
                                } else if (child.isNodeType(DocBookTypes.PARA)) {
                                        sectionPart = newParagraph(textSection, child);
                                } else {
                                        sectionPart = newSectionPart(textSection, child);
-                                       if (sectionPart == null)
-                                               throw new IllegalArgumentException("Unsupported node " + child);
+//                                     if (sectionPart == null)
+//                                             throw new IllegalArgumentException("Unsupported node " + child);
                                        // TODO list node types in exception
                                }
-                               if (sectionPart instanceof Control)
+                               if (sectionPart != null && sectionPart instanceof Control)
                                        ((Control) sectionPart).setLayoutData(CmsUiUtils.fillWidth());
                        }
 
@@ -153,24 +157,28 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                return paragraph;
        }
 
-       protected Img newImg(TextSection parent, Node node) throws RepositoryException {
-               Img img = new Img(parent, parent.getStyle(), node) {
-                       private static final long serialVersionUID = 1297900641952417540L;
+       protected Img newImg(TextSection parent, Node node) {
+               try {
+                       Img img = new Img(parent, parent.getStyle(), node, imageManager) {
+                               private static final long serialVersionUID = 1297900641952417540L;
 
-                       @Override
-                       protected void setContainerLayoutData(Composite composite) {
-                               composite.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-                       }
+                               @Override
+                               protected void setContainerLayoutData(Composite composite) {
+                                       composite.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+                               }
 
-                       @Override
-                       protected void setControlLayoutData(Control control) {
-                               control.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-                       }
-               };
-               img.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-               updateContent(img);
-               img.setMouseListener(getMouseListener());
-               return img;
+                               @Override
+                               protected void setControlLayoutData(Control control) {
+                                       control.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+                               }
+                       };
+                       img.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+                       updateContent(img);
+                       img.setMouseListener(getMouseListener());
+                       return img;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot add new image " + node, e);
+               }
        }
 
        protected DocBookSectionTitle newSectionTitle(TextSection parent, Node titleNode) throws RepositoryException {
@@ -347,18 +355,43 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                }
        }
 
-       void deletePart(SectionPart paragraph) {
+       void insertPart(Section section, Node node) {
                try {
-                       Node paragraphNode = paragraph.getNode();
-                       Section section = paragraph.getSection();
-                       Session session = paragraphNode.getSession();
-                       paragraphNode.remove();
+                       refresh(section);
+                       layoutPage();
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot insert part " + node + " in section " + section.getNode(), e);
+               }
+       }
+
+       void deletePart(SectionPart sectionPart) {
+               try {
+                       Node node = sectionPart.getNode();
+                       Session session = node.getSession();
+                       if (sectionPart instanceof Img) {
+                               // FIXME make it more robust
+                               node = node.getParent().getParent().getParent();
+                       }
+                       node.remove();
                        session.save();
-                       if (paragraph instanceof Control)
-                               ((Control) paragraph).dispose();
-                       layout(section);
+                       if (sectionPart instanceof Control)
+                               ((Control) sectionPart).dispose();
+                       layoutPage();
                } catch (RepositoryException e1) {
-                       throw new JcrException("Cannot delete " + paragraph, e1);
+                       throw new JcrException("Cannot delete " + sectionPart, e1);
+               }
+       }
+
+       void deleteSection(Section section) {
+               try {
+                       Node node = section.getNode();
+                       Session session = node.getSession();
+                       node.remove();
+                       session.save();
+                       section.dispose();
+                       layoutPage();
+               } catch (RepositoryException e1) {
+                       throw new JcrException("Cannot delete " + section, e1);
                }
        }
 
@@ -511,7 +544,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                        if (getEdited() == part)
                                                return;
                                        edit(part, null);
-                                       layout(part.getControl());
+                                       layoutPage();
                                }
                        }
                } catch (RepositoryException e) {
@@ -601,8 +634,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                try {
                        if (getEdited() instanceof Paragraph) {
                                upload(getEdited());
-                       } else if (getEdited() instanceof SectionTitle) {
-                               SectionTitle sectionTitle = (SectionTitle) getEdited();
+                       } else if (getEdited() instanceof DocBookSectionTitle) {
+                               DocBookSectionTitle sectionTitle = (DocBookSectionTitle) getEdited();
                                Section section = sectionTitle.getSection();
                                Node sectionNode = section.getNode();
                                Section parentSection = section.getParentSection();
@@ -741,9 +774,13 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                try {
                        // Common
                        if (ke.keyCode == SWT.ESC) {
-                               cancelEdit();
+//                             cancelEdit();
+                               saveEdit();
                        } else if (ke.character == '\r') {
                                splitEdit();
+                       } else if (ke.character == 'z') {
+                               if (ctrlPressed)
+                                       cancelEdit();
                        } else if (ke.character == 'S') {
                                if (ctrlPressed)
                                        saveEdit();
@@ -800,29 +837,28 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                public void mouseDoubleClick(MouseEvent e) {
                        if (e.button == 1) {
                                Control source = (Control) e.getSource();
-                               if (getCmsEditable().canEdit()) {
-                                       if (getCmsEditable().isEditing() && !(getEdited() instanceof Img)) {
-                                               if (source == mainSection)
-                                                       return;
-                                               EditablePart part = findDataParent(source);
-                                               upload(part);
-                                       } else {
-                                               getCmsEditable().startEditing();
+                               EditablePart composite = findDataParent(source);
+                               Point point = new Point(e.x, e.y);
+                               if (composite instanceof Img) {
+                                       if (getCmsEditable().canEdit()) {
+                                               if (getCmsEditable().isEditing() && !(getEdited() instanceof Img)) {
+                                                       if (source == mainSection)
+                                                               return;
+                                                       EditablePart part = findDataParent(source);
+                                                       upload(part);
+                                               } else {
+                                                       getCmsEditable().startEditing();
+                                               }
                                        }
-                               }
+                               } else
+                                       edit(composite, source.toDisplay(point));
                        }
                }
 
                @Override
                public void mouseDown(MouseEvent e) {
                        if (getCmsEditable().isEditing()) {
-                               if (e.button == 1) {
-                                       Control source = (Control) e.getSource();
-                                       EditablePart composite = findDataParent(source);
-                                       Point point = new Point(e.x, e.y);
-                                       if (!(composite instanceof Img))
-                                               edit(composite, source.toDisplay(point));
-                               } else if (e.button == 3) {
+                               if (e.button == 3) {
                                        EditablePart composite = findDataParent((Control) e.getSource());
                                        if (styledTools != null) {
                                                List<String> styles = getAvailableStyles(composite);
index bccdbb8986c02246a57a574bdc8fa20a9fc36e99..24a759c60ff06c963f2511da6e3fcd1f09ef99a6 100644 (file)
@@ -3,11 +3,23 @@ package org.argeo.docbook.ui;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.jcr.Node;
+
 import org.argeo.cms.text.Paragraph;
+import org.argeo.cms.text.TextSection;
+import org.argeo.cms.ui.CmsEditable;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.viewers.NodePart;
+import org.argeo.cms.ui.viewers.Section;
+import org.argeo.cms.ui.viewers.SectionPart;
 import org.argeo.cms.ui.widgets.EditableText;
+import org.argeo.cms.ui.widgets.Img;
 import org.argeo.cms.ui.widgets.TextStyles;
+import org.argeo.docbook.DbkMsg;
+import org.argeo.docbook.DbkUtils;
+import org.argeo.eclipse.ui.MouseDown;
+import org.argeo.jcr.Jcr;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseAdapter;
@@ -22,20 +34,11 @@ import org.eclipse.swt.widgets.Shell;
 
 /** Dialog to edit a text part. */
 class DbkContextMenu implements TextStyles {
-//     private final static String[] DEFAULT_TEXT_STYLES = { TextStyles.TEXT_DEFAULT, TextStyles.TEXT_PRE,
-//                     TextStyles.TEXT_QUOTE };
-
        private final AbstractDbkViewer textViewer;
 
-//     private List<StyleButton> styleButtons = new ArrayList<DbkContextMenu.StyleButton>();
-//
-//     private Label deleteButton, publishButton, editButton;
-
-       private EditablePart currentTextPart;
-
        private Shell shell;
 
-       public DbkContextMenu(AbstractDbkViewer textViewer, Shell parentShell) {
+       DbkContextMenu(AbstractDbkViewer textViewer, Shell parentShell) {
 //             shell = new Shell(display, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
                shell = new Shell(parentShell, SWT.BORDER);
 //             super(display, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
@@ -46,68 +49,110 @@ class DbkContextMenu implements TextStyles {
                shell.addShellListener(new ToolsShellListener());
        }
 
-       public void show(EditablePart source, Point location, List<String> availableStyles) {
+       void show(EditablePart editablePart, Point location, List<String> availableStyles) {
                if (shell.isVisible())
                        shell.setVisible(false);
                CmsUiUtils.clear(shell);
+               Composite parent = shell;
+               CmsEditable cmsEditable = textViewer.getCmsEditable();
+//             if (availableStyles.isEmpty())
+//                     return;
+
+               if (editablePart instanceof Paragraph) {
+                       Paragraph paragraph = (Paragraph) editablePart;
+                       deletePartB(parent, DbkMsg.deleteParagraph.lead(), paragraph);
+                       insertMediaB(parent, DbkMsg.insertMedia.lead(), paragraph);
+
+               } else if (editablePart instanceof Img) {
+                       Img img = (Img) editablePart;
+                       deletePartB(parent, DbkMsg.deleteMedia.lead(), img);
+                       insertMediaB(parent, DbkMsg.insertMedia.lead(), img);
+
+               } else if (editablePart instanceof DocBookSectionTitle) {
+                       DocBookSectionTitle sectionTitle = (DocBookSectionTitle) editablePart;
+                       TextSection section = sectionTitle.getSection();
+                       if (!section.isTitleReadOnly()) {
+                               Label deleteB = new Label(shell, SWT.NONE);
+                               deleteB.setText(DbkMsg.deleteSection.lead());
+                               deleteB.addMouseListener((MouseDown) (e) -> {
+                                       textViewer.deleteSection(section);
+                                       hide();
+                               });
+                       }
+                       insertMediaB(parent, DbkMsg.insertMedia.lead(), sectionTitle.getSection(), sectionTitle);
+               }
 
-               if (availableStyles.isEmpty())
-                       return;
-
-               StyledToolMouseListener stml = new StyledToolMouseListener();
+               StyledToolMouseListener stml = new StyledToolMouseListener(editablePart);
                List<StyleButton> styleButtons = new ArrayList<DbkContextMenu.StyleButton>();
-               if (textViewer.getCmsEditable().isEditing()) {
+               if (cmsEditable.isEditing()) {
                        for (String style : availableStyles) {
                                StyleButton styleButton = new StyleButton(shell, SWT.WRAP);
                                if (!"".equals(style))
                                        styleButton.setStyle(style);
                                else
                                        styleButton.setStyle(null);
-//                             if (!"".equals(style))
-//                                     styleButton.getLabel().setData(RWT.CUSTOM_VARIANT, style);
-//                             styleButton.getLabel().setData(RWT.MARKUP_ENABLED, true);
                                styleButton.setMouseListener(stml);
                                styleButtons.add(styleButton);
                        }
-
-//                     // Delete
-//                     deleteButton = new Label(shell, SWT.NONE);
-//                     deleteButton.setText("Delete");
-//                     deleteButton.addMouseListener(stml);
-//
-//                     // Publish
-//                     publishButton = new Label(shell, SWT.NONE);
-//                     publishButton.setText("Publish");
-//                     publishButton.addMouseListener(stml);
-               } else if (textViewer.getCmsEditable().canEdit()) {
+               } else if (cmsEditable.canEdit()) {
                        // Edit
-                       Label editButton = new Label(shell, SWT.NONE);
-                       editButton.setText("Edit");
-                       editButton.addMouseListener(stml);
+//                     Label editButton = new Label(shell, SWT.NONE);
+//                     editButton.setText("Edit");
+//                     editButton.addMouseListener(stml);
                }
 
-               this.currentTextPart = source;
-
-               if (currentTextPart instanceof Paragraph) {
+               if (editablePart instanceof Paragraph) {
                        final int size = 32;
-                       String text = textViewer.getRawParagraphText((Paragraph) currentTextPart);
+                       String text = textViewer.getRawParagraphText((Paragraph) editablePart);
                        String textToShow = text.length() > size ? text.substring(0, size - 3) + "..." : text;
                        for (StyleButton styleButton : styleButtons) {
                                styleButton.setText((styleButton.style == null ? "default" : styleButton.style) + " : " + textToShow);
                        }
                }
+
                shell.pack();
                shell.layout();
-               if (source instanceof Control) {
+               if (editablePart instanceof Control) {
                        int height = shell.getSize().y;
                        int parentShellHeight = shell.getShell().getSize().y;
                        if ((location.y + height) < parentShellHeight) {
-                               shell.setLocation(((Control) source).toDisplay(location.x, location.y));
+                               shell.setLocation(((Control) editablePart).toDisplay(location.x, location.y));
                        } else {
-                               shell.setLocation(((Control) source).toDisplay(location.x, location.y - parentShellHeight));
+                               shell.setLocation(((Control) editablePart).toDisplay(location.x, location.y - parentShellHeight));
                        }
                }
-               shell.open();
+
+               if (shell.getChildren().length != 0)
+                       shell.open();
+       }
+
+       void hide() {
+               shell.setVisible(false);
+       }
+
+       protected void insertMediaB(Composite parent, String msg, SectionPart sectionPart) {
+               insertMediaB(parent, msg, sectionPart.getSection(), sectionPart);
+       }
+
+       protected void insertMediaB(Composite parent, String msg, Section section, NodePart nodePart) {
+               Label insertMediaB = new Label(parent, SWT.NONE);
+               insertMediaB.setText(DbkMsg.insertMedia.lead());
+               insertMediaB.addMouseListener((MouseDown) (e) -> {
+                       Node newNode = DbkUtils.insertImageAfter(nodePart.getNode());
+                       Jcr.save(newNode);
+                       textViewer.insertPart(section, newNode);
+                       hide();
+               });
+
+       }
+
+       protected void deletePartB(Composite parent, String msg, SectionPart sectionPart) {
+               Label deleteB = new Label(shell, SWT.NONE);
+               deleteB.setText(msg);
+               deleteB.addMouseListener((MouseDown) (e) -> {
+                       textViewer.deletePart(sectionPart);
+                       hide();
+               });
        }
 
        class StyleButton extends EditableText {
@@ -141,23 +186,20 @@ class DbkContextMenu implements TextStyles {
 
        class StyledToolMouseListener extends MouseAdapter {
                private static final long serialVersionUID = 8516297091549329043L;
+               private EditablePart editablePart;
+
+               public StyledToolMouseListener(EditablePart editablePart) {
+                       super();
+                       this.editablePart = editablePart;
+               }
 
                @Override
                public void mouseDown(MouseEvent e) {
-//                     Object eventSource = e.getSource();
-////                   if (eventSource instanceof StyleButton) {
                        // TODO make it more robust.
                        Label sb = (Label) e.getSource();
                        Object style = sb.getData(RWT.CUSTOM_VARIANT);
-                       textViewer.setParagraphStyle((Paragraph) currentTextPart, style == null ? null : style.toString());
-//                     }
-//                     } else if (eventSource == deleteButton) {
-//                             textViewer.deletePart((SectionPart) currentTextPart);
-//                     } else if (eventSource == editButton) {
-//                             textViewer.getCmsEditable().startEditing();
-//                     } else if (eventSource == publishButton) {
-//                             textViewer.getCmsEditable().stopEditing();
-                       shell.setVisible(false);
+                       textViewer.setParagraphStyle((Paragraph) editablePart, style == null ? null : style.toString());
+                       hide();
                }
        }
 
@@ -166,7 +208,7 @@ class DbkContextMenu implements TextStyles {
 
                @Override
                public void shellDeactivated(ShellEvent e) {
-                       shell.setVisible(false);
+                       hide();
                }
 
        }
diff --git a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkImageManager.java
new file mode 100644 (file)
index 0000000..2e72a3e
--- /dev/null
@@ -0,0 +1,37 @@
+package org.argeo.docbook.ui;
+
+import java.io.IOException;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.cms.ui.util.DefaultImageManager;
+import org.argeo.entity.EntityNames;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+
+/** Add DocBook images support to {@link CmsImageManager}. */
+public class DbkImageManager extends DefaultImageManager {
+       @Override
+       public Binary getImageBinary(Node node) throws RepositoryException {
+               Binary binary = super.getImageBinary(node);
+               return binary;
+       }
+
+       public Point getImageSize(Node node) throws RepositoryException {
+               int width = node.hasProperty(EntityNames.SVG_WIDTH) ? (int) node.getProperty(EntityNames.SVG_WIDTH).getLong()
+                               : 0;
+               int height = node.hasProperty(EntityNames.SVG_HEIGHT) ? (int) node.getProperty(EntityNames.SVG_HEIGHT).getLong()
+                               : 0;
+               return new Point(width, height);
+       }
+
+       @Override
+       protected void processNewImageFile(Node fileNode, ImageData id) throws RepositoryException, IOException {
+               fileNode.setProperty(EntityNames.SVG_WIDTH, id.width);
+               fileNode.setProperty(EntityNames.SVG_HEIGHT, id.height);
+       }
+
+}
diff --git a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkUtils.java b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/ui/DbkUtils.java
deleted file mode 100644 (file)
index 35a7132..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.argeo.docbook.ui;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.argeo.entity.EntityType;
-import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrException;
-import org.argeo.jcr.JcrUtils;
-import org.argeo.jcr.JcrxApi;
-
-/** Utilities around DocBook. */
-public class DbkUtils {
-       public static String getTitle(Node node) {
-               return JcrxApi.getXmlValue(node, DocBookTypes.TITLE);
-       }
-
-       public static void setTitle(Node node, String txt) {
-               try {
-                       Node titleNode = JcrUtils.getOrAdd(node, DocBookTypes.TITLE, DocBookTypes.TITLE);
-                       JcrxApi.setXmlValue(node, titleNode, txt);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add empty paragraph to " + node, e);
-               }
-       }
-
-       public static Node getMetadata(Node infoContainer) {
-               try {
-                       if (!infoContainer.hasNode(DocBookTypes.INFO))
-                               return null;
-                       Node info = infoContainer.getNode(DocBookTypes.INFO);
-                       if (!info.hasNode(EntityType.local.get()))
-                               return null;
-                       return info.getNode(EntityType.local.get());
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot retrieve metadata from " + infoContainer, e);
-               }
-       }
-
-       public static Node getChildByRole(Node parent, String role) {
-               try {
-                       NodeIterator baseSections = parent.getNodes();
-                       while (baseSections.hasNext()) {
-                               Node n = baseSections.nextNode();
-                               String r = Jcr.get(n, DocBookNames.DBK_ROLE);
-                               if (r != null && r.equals(role))
-                                       return n;
-                       }
-                       return null;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot get child from " + parent + " with role " + role, e);
-               }
-       }
-
-       public static Node addParagraph(Node node, String txt) {
-               try {
-                       Node para = node.addNode(DocBookTypes.PARA, DocBookTypes.PARA);
-                       JcrxApi.setXmlValue(node, para, txt);
-                       return para;
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot add empty paragraph to " + node, e);
-               }
-       }
-
-       /** Singleton. */
-       private DbkUtils() {
-       }
-}
index 587bc852adfb07041fcf67e5f9be06ce53ff299b..61a91641e4550aba2bcae83a388004be6e551823 100644 (file)
@@ -20,6 +20,7 @@ public class DocBookSectionTitle extends EditableText implements EditablePart, N
                section = (TextSection) TextSection.findSection(this);
        }
 
+//     @Override
        public TextSection getSection() {
                return section;
        }
@@ -29,6 +30,11 @@ public class DocBookSectionTitle extends EditableText implements EditablePart, N
                return getNode();
        }
 
+//     @Override
+//     public String getPartId() {
+//             return getNodeId();
+//     }
+
 //     @Override
 //     protected void setControlLayoutData(Control control) {
 //             super.setControlLayoutData(control);