Use released Argeo Maven plugin
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / docbook / ui / AbstractDbkViewer.java
index 6b0692f6f80c52735b30c1a6647ded04ea0ce876..e9000936128b2f94f850475471b28161399911dc 100644 (file)
@@ -19,9 +19,6 @@ import javax.jcr.Session;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.text.Paragraph;
-import org.argeo.cms.text.TextInterpreter;
-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.AbstractPageViewer;
@@ -51,6 +48,7 @@ import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseListener;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
@@ -71,6 +69,11 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
 
        private final boolean flat;
 
+       private boolean showMainTitle = true;
+
+       private Integer maxMediaWidth = null;
+       private String defaultSectionStyle;
+
        protected AbstractDbkViewer(Section parent, int style, CmsEditable cmsEditable) {
                super(parent, style, cmsEditable);
 //             CmsView cmsView = CmsView.getCmsView(parent);
@@ -96,35 +99,62 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
        protected void refresh(Control control) throws RepositoryException {
                if (!(control instanceof Section))
                        return;
+               long begin = System.currentTimeMillis();
                Section section = (Section) control;
                if (section instanceof TextSection) {
                        CmsUiUtils.clear(section);
                        Node node = section.getNode();
                        TextSection textSection = (TextSection) section;
+                       String style = node.hasProperty(DbkAttr.role.name()) ? node.getProperty(DbkAttr.role.name()).getString()
+                                       : getDefaultSectionStyle();
+                       if (style != null)
+                               CmsUiUtils.style(textSection, style);
+
+                       // Title
+                       Node titleNode = null;
+                       // We give priority to ./title vs ./info/title, like the DocBook XSL
                        if (node.hasNode(DbkType.title.get())) {
-                               if (section.getHeader() == null)
-                                       section.createHeader();
-                               Node titleNode = node.getNode(DbkType.title.get());
-                               DocBookSectionTitle title = newSectionTitle(textSection, titleNode);
-                               title.setLayoutData(CmsUiUtils.fillWidth());
-                               updateContent(title);
+                               titleNode = node.getNode(DbkType.title.get());
+                       } else if (node.hasNode(DbkType.info.get() + '/' + DbkType.title.get())) {
+                               titleNode = node.getNode(DbkType.info.get() + '/' + DbkType.title.get());
+                       }
+
+                       if (titleNode != null) {
+                               boolean showTitle = getMainSection() == section ? showMainTitle : true;
+                               if (showTitle) {
+                                       if (section.getHeader() == null)
+                                               section.createHeader();
+                                       DbkSectionTitle title = newSectionTitle(textSection, titleNode);
+                                       title.setLayoutData(CmsUiUtils.fillWidth());
+                                       updateContent(title);
+                               }
                        }
 
+                       // content
                        for (NodeIterator ni = node.getNodes(); ni.hasNext();) {
                                Node child = ni.nextNode();
                                SectionPart sectionPart = null;
                                if (isDbk(child, DbkType.mediaobject)) {
                                        if (child.hasNode(DbkType.imageobject.get())) {
-                                               Node imageDataNode = child.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get());
-                                               sectionPart = newImg(textSection, imageDataNode);
+                                               sectionPart = newImg(textSection, child);
+                                       } else if (child.hasNode(DbkType.videoobject.get())) {
+                                               sectionPart = newVideo(textSection, child);
+                                       } else {
+                                               throw new IllegalArgumentException("Unsupported media object " + child);
                                        }
+                               } else if (isDbk(child, DbkType.info)) {
+                                       // TODO enrich UI based on info
+                               } else if (isDbk(child, DbkType.title)) {
+                                       // already managed
                                } else if (isDbk(child, para)) {
                                        sectionPart = newParagraph(textSection, child);
-                               } else {
+                               } else if (isDbk(child, DbkType.section)) {
                                        sectionPart = newSectionPart(textSection, child);
 //                                     if (sectionPart == null)
 //                                             throw new IllegalArgumentException("Unsupported node " + child);
                                        // TODO list node types in exception
+                               } else {
+                                       throw new IllegalArgumentException("Unsupported node type for " + child);
                                }
                                if (sectionPart != null && sectionPart instanceof Control)
                                        ((Control) sectionPart).setLayoutData(CmsUiUtils.fillWidth());
@@ -134,7 +164,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                        for (NodeIterator ni = section.getNode().getNodes(DbkType.section.get()); ni.hasNext();) {
                                Node child = ni.nextNode();
                                if (isDbk(child, DbkType.section)) {
-                                       TextSection newSection = new TextSection(section, SWT.NONE, child);
+                                       TextSection newSection = newTextSection(section, child);
                                        newSection.setLayoutData(CmsUiUtils.fillWidth());
                                        refresh(newSection);
                                }
@@ -144,6 +174,13 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                refresh(s);
                }
                // section.layout(true, true);
+               long duration = System.currentTimeMillis() - begin;
+//             System.out.println(duration + " ms - " + DbkUtils.getTitle(section.getNode()));
+       }
+
+       /** To be overridden in order to provide additional SectionPart types */
+       protected TextSection newTextSection(Section section, Node node) {
+               return new TextSection(section, SWT.NONE, node);
        }
 
        /** To be overridden in order to provide additional SectionPart types */
@@ -157,29 +194,62 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                updateContent(paragraph);
                paragraph.setLayoutData(fillWidth());
                paragraph.setMouseListener(getMouseListener());
+               paragraph.setFocusListener(getFocusListener());
                return paragraph;
        }
 
        protected DbkImg newImg(TextSection parent, Node node) {
                try {
                        DbkImg img = new DbkImg(parent, parent.getStyle(), node, imageManager);
-                       img.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
+                       GridData imgGd;
+                       if (maxMediaWidth != null) {
+                               imgGd = new GridData(SWT.CENTER, SWT.FILL, false, false);
+                               imgGd.widthHint = maxMediaWidth;
+                               img.setPreferredSize(new Point(maxMediaWidth, 0));
+                       } else {
+                               imgGd = CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT);
+                       }
+                       img.setLayoutData(imgGd);
                        updateContent(img);
                        img.setMouseListener(getMouseListener());
+                       img.setFocusListener(getFocusListener());
                        return img;
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot add new image " + node, e);
                }
        }
 
-       protected DocBookSectionTitle newSectionTitle(TextSection parent, Node titleNode) throws RepositoryException {
+       protected DbkVideo newVideo(TextSection parent, Node node) {
+               try {
+                       DbkVideo video = new DbkVideo(parent, getCmsEditable().canEdit() ? SWT.NONE : SWT.READ_ONLY, node);
+                       GridData gd;
+                       if (maxMediaWidth != null) {
+                               gd = new GridData(SWT.CENTER, SWT.FILL, false, false);
+                               // TODO, manage size
+//                             gd.widthHint = maxMediaWidth;
+//                             gd.heightHint = (int) (gd.heightHint * 0.5625);
+                       } else {
+                               gd = new GridData(SWT.CENTER, SWT.FILL, false, false);
+//                             gd.widthHint = video.getWidth();
+//                             gd.heightHint = video.getHeight();
+                       }
+                       video.setLayoutData(gd);
+                       updateContent(video);
+                       return video;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot add new image " + node, e);
+               }
+       }
+
+       protected DbkSectionTitle newSectionTitle(TextSection parent, Node titleNode) throws RepositoryException {
                int style = parent.getStyle();
                Composite titleParent = newSectionHeader(parent);
                if (parent.isTitleReadOnly())
                        style = style | SWT.READ_ONLY;
-               DocBookSectionTitle title = new DocBookSectionTitle(titleParent, style, titleNode);
+               DbkSectionTitle title = new DbkSectionTitle(titleParent, style, titleNode);
                updateContent(title);
                title.setMouseListener(getMouseListener());
+               title.setFocusListener(getFocusListener());
                return title;
        }
 
@@ -187,20 +257,20 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
         * To be overridden in order to provide additional processing at the section
         * level.
         * 
-        * @return the parent to use for the {@link DocBookSectionTitle}, by default
+        * @return the parent to use for the {@link DbkSectionTitle}, by default
         *         {@link Section#getHeader()}
         */
        protected Composite newSectionHeader(TextSection section) {
                return section.getHeader();
        }
 
-       protected DocBookSectionTitle prepareSectionTitle(Section newSection, String titleText) throws RepositoryException {
+       protected DbkSectionTitle prepareSectionTitle(Section newSection, String titleText) throws RepositoryException {
                Node sectionNode = newSection.getNode();
                Node titleNode = DbkUtils.getOrAddDbk(sectionNode, DbkType.title);
                getTextInterpreter().write(titleNode, titleText);
                if (newSection.getHeader() == null)
                        newSection.createHeader();
-               DocBookSectionTitle sectionTitle = newSectionTitle((TextSection) newSection, sectionNode);
+               DbkSectionTitle sectionTitle = newSectionTitle((TextSection) newSection, sectionNode);
                return sectionTitle;
        }
 
@@ -229,16 +299,20 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                        paragraph.setText(textInterpreter.readSimpleHtml(partNode));
                        } else if (part instanceof DbkImg) {
                                DbkImg editableImage = (DbkImg) part;
-                               imageManager.load(partNode, part.getControl(), editableImage.getPreferredImageSize());
+                               // imageManager.load(partNode, part.getControl(),
+                               // editableImage.getPreferredImageSize());
+                       } else if (part instanceof DbkVideo) {
+                               DbkVideo video = (DbkVideo) part;
+                               video.load(part.getControl());
                        }
-               } else if (part instanceof DocBookSectionTitle) {
-                       DocBookSectionTitle title = (DocBookSectionTitle) part;
+               } else if (part instanceof DbkSectionTitle) {
+                       DbkSectionTitle title = (DbkSectionTitle) part;
                        title.setStyle(title.getSection().getTitleStyle());
                        // use control AFTER setting style
                        if (title == getEdited())
                                title.setText(textInterpreter.read(title.getNode()));
                        else
-                               title.setText(textInterpreter.raw(title.getNode()));
+                               title.setText(textInterpreter.readSimpleHtml(title.getNode()));
                }
        }
 
@@ -353,22 +427,47 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                }
        }
 
-       void insertPart(Section section, Node node) {
+       SectionPart insertPart(Section section, Node node) {
                try {
                        refresh(section);
                        layoutPage();
+                       for (Control control : section.getChildren()) {
+                               if (control instanceof SectionPart) {
+                                       SectionPart sectionPart = (SectionPart) control;
+                                       Node partNode = sectionPart.getNode();
+                                       if (partNode.getPath().equals(node.getPath()))
+                                               return sectionPart;
+                               }
+                       }
+                       throw new IllegalStateException("New section part " + node + "not found");
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot insert part " + node + " in section " + section.getNode(), e);
                }
        }
 
+       void addParagraph(SectionPart partBefore, String txt) {
+               Section section = partBefore.getSection();
+               SectionPart nextSectionPart = section.nextSectionPart(partBefore);
+               Node newNode = addDbk(section.getNode(), para);
+               textInterpreter.write(newNode, txt != null ? txt : "");
+               if (nextSectionPart != null) {
+                       try {
+                               Node nextNode = nextSectionPart.getNode();
+                               section.getNode().orderBefore(Jcr.getIndexedName(newNode), Jcr.getIndexedName(nextNode));
+                       } catch (RepositoryException e) {
+                               throw new JcrException("Cannot order " + newNode + " before " + nextSectionPart.getNode(), e);
+                       }
+               }
+               Jcr.save(newNode);
+               Paragraph paragraph = (Paragraph) insertPart(partBefore.getSection(), newNode);
+               edit(paragraph, 0);
+       }
+
        void deletePart(SectionPart sectionPart) {
                try {
                        Node node = sectionPart.getNode();
                        Session session = node.getSession();
                        if (sectionPart instanceof DbkImg) {
-                               // FIXME make it more robust
-                               node = node.getParent().getParent();
                                if (!isDbk(node, DbkType.mediaobject))
                                        throw new IllegalArgumentException("Node " + node + " is not a media object.");
                        }
@@ -440,8 +539,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
 
                                Paragraph secondParagraph = paragraphSplitted(paragraph, secondNode);
                                edit(secondParagraph, 0);
-                       } else if (getEdited() instanceof DocBookSectionTitle) {
-                               DocBookSectionTitle sectionTitle = (DocBookSectionTitle) getEdited();
+                       } else if (getEdited() instanceof DbkSectionTitle) {
+                               DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited();
                                Text text = (Text) sectionTitle.getControl();
                                String txt = text.getText();
                                int caretPosition = text.getCaretPosition();
@@ -567,7 +666,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                // main title
                                if (section == mainSection && section instanceof TextSection && paragraphNode.getIndex() == 1
                                                && !sectionNode.hasNode(DbkType.title.get())) {
-                                       DocBookSectionTitle sectionTitle = prepareSectionTitle(section, txt);
+                                       DbkSectionTitle sectionTitle = prepareSectionTitle(section, txt);
                                        edit(sectionTitle, 0);
                                        return;
                                }
@@ -603,8 +702,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                newSection.getParent().layout();
                                layout(newSection);
                                persistChanges(sectionNode);
-                       } else if (getEdited() instanceof DocBookSectionTitle) {
-                               DocBookSectionTitle sectionTitle = (DocBookSectionTitle) getEdited();
+                       } else if (getEdited() instanceof DbkSectionTitle) {
+                               DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited();
                                Section section = sectionTitle.getSection();
                                Section parentSection = section.getParentSection();
                                if (parentSection == null)
@@ -635,8 +734,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                try {
                        if (getEdited() instanceof Paragraph) {
                                upload(getEdited());
-                       } else if (getEdited() instanceof DocBookSectionTitle) {
-                               DocBookSectionTitle sectionTitle = (DocBookSectionTitle) getEdited();
+                       } else if (getEdited() instanceof DbkSectionTitle) {
+                               DbkSectionTitle sectionTitle = (DbkSectionTitle) getEdited();
                                Section section = sectionTitle.getSection();
                                Node sectionNode = section.getNode();
                                Section parentSection = section.getParentSection();
@@ -708,8 +807,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                return newParagraph;
        }
 
-       protected Paragraph sectionTitleSplitted(DocBookSectionTitle sectionTitle, Node newNode)
-                       throws RepositoryException {
+       protected Paragraph sectionTitleSplitted(DbkSectionTitle sectionTitle, Node newNode) throws RepositoryException {
                updateContent(sectionTitle);
                Paragraph newParagraph = newParagraph(sectionTitle.getSection(), newNode);
                // we assume beforeFirst is not null since there was a sectionTitle
@@ -859,8 +957,8 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                        float height = bounds.height;
                                        float textLength = lbl.getText().length();
                                        float area = width * height;
-                                       float charArea = area/textLength;
-                                       float lines = textLength/width;
+                                       float charArea = area / textLength;
+                                       float lines = textLength / width;
                                        float proportion = point.y * width + point.x;
                                        int pos = (int) (textLength * (proportion / area));
                                        // TODO refine it
@@ -893,6 +991,22 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                return new ArrayList<>();
        }
 
+       public void setMaxMediaWidth(Integer maxMediaWidth) {
+               this.maxMediaWidth = maxMediaWidth;
+       }
+
+       public void setShowMainTitle(boolean showMainTitle) {
+               this.showMainTitle = showMainTitle;
+       }
+
+       public String getDefaultSectionStyle() {
+               return defaultSectionStyle;
+       }
+
+       public void setDefaultSectionStyle(String defaultSectionStyle) {
+               this.defaultSectionStyle = defaultSectionStyle;
+       }
+
        // FILE UPLOAD LISTENER
        private class FUL implements FileUploadListener {
                public void uploadProgress(FileUploadEvent event) {