Improve media management in DocBook.
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / docbook / ui / AbstractDbkViewer.java
index a4755c7114b1c1dc9aafe6757e89d1284cc011d1..44e6f547a4088f6ff59f642c30a7cf58df1e7102 100644 (file)
@@ -5,10 +5,6 @@ import static org.argeo.docbook.DbkType.para;
 import static org.argeo.docbook.DbkUtils.addDbk;
 import static org.argeo.docbook.DbkUtils.isDbk;
 
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -54,8 +50,10 @@ import org.eclipse.swt.events.MouseAdapter;
 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.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 
 /** Base class for text viewers and editors. */
@@ -116,10 +114,11 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                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);
+//                                     if (child.hasNode(DbkType.imageobject.get())) {
+//                                             Node imageDataNode = child.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get());
+//                                             sectionPart = newImg(textSection, imageDataNode);
+//                                     }
                                } else if (isDbk(child, para)) {
                                        sectionPart = newParagraph(textSection, child);
                                } else {
@@ -159,6 +158,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                updateContent(paragraph);
                paragraph.setLayoutData(fillWidth());
                paragraph.setMouseListener(getMouseListener());
+               paragraph.setFocusListener(getFocusListener());
                return paragraph;
        }
 
@@ -168,6 +168,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                        img.setLayoutData(CmsUiUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
                        updateContent(img);
                        img.setMouseListener(getMouseListener());
+                       img.setFocusListener(getFocusListener());
                        return img;
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot add new image " + node, e);
@@ -182,6 +183,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                DocBookSectionTitle title = new DocBookSectionTitle(titleParent, style, titleNode);
                updateContent(title);
                title.setMouseListener(getMouseListener());
+               title.setFocusListener(getFocusListener());
                return title;
        }
 
@@ -315,7 +317,18 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                if (caretPosition instanceof Integer)
                                        text.setSelection((Integer) caretPosition);
                                else if (caretPosition instanceof Point) {
-                                       // TODO find a way to position the caret at the right place
+//                                     layout(text);
+//                                     // TODO find a way to position the caret at the right place
+//                                     Point clickLocation = (Point) caretPosition;
+//                                     Point withinText = text.toControl(clickLocation);
+//                                     Rectangle bounds = text.getBounds();
+//                                     int width = bounds.width;
+//                                     int height = bounds.height;
+//                                     int textLength = text.getText().length();
+//                                     float area = width * height;
+//                                     float proportion = withinText.y * width + withinText.x;
+//                                     int pos = (int) (textLength * (proportion / area));
+//                                     text.setSelection(pos);
                                }
                        text.setData(RWT.ACTIVE_KEYS, new String[] { "BACKSPACE", "ESC", "TAB", "SHIFT+TAB", "ALT+ARROW_LEFT",
                                        "ALT+ARROW_RIGHT", "ALT+ARROW_UP", "ALT+ARROW_DOWN", "RETURN", "CTRL+RETURN", "ENTER", "DELETE" });
@@ -344,22 +357,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.");
                        }
@@ -843,8 +881,22 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                                        getCmsEditable().startEditing();
                                                }
                                        }
-                               } else
+                               } else if (source instanceof Label) {
+                                       Label lbl = (Label) source;
+                                       Rectangle bounds = lbl.getBounds();
+                                       float width = bounds.width;
+                                       float height = bounds.height;
+                                       float textLength = lbl.getText().length();
+                                       float area = width * height;
+                                       float charArea = area / textLength;
+                                       float lines = textLength / width;
+                                       float proportion = point.y * width + point.x;
+                                       int pos = (int) (textLength * (proportion / area));
+                                       // TODO refine it
+                                       edit(composite, (Integer) pos);
+                               } else {
                                        edit(composite, source.toDisplay(point));
+                               }
                        }
                }
 
@@ -870,29 +922,6 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                return new ArrayList<>();
        }
 
-       public void export(Path directory, String fileName) {
-               Path filePath = directory.resolve(fileName);
-               try {
-                       Files.createDirectories(directory);
-                       try (OutputStream out = Files.newOutputStream(filePath)) {
-                               exportXml(out);
-                       }
-                       if (log.isDebugEnabled())
-                               log.debug("DocBook " + getMainSection().getNode() + " exported to " + filePath.toAbsolutePath());
-               } catch (IOException e) {
-                       throw new RuntimeException(e);
-               }
-       }
-
-       public void exportXml(OutputStream out) throws IOException {
-               Node node = getMainSection().getNode();
-               try {
-                       node.getSession().exportDocumentView(node.getPath(), out, false, false);
-               } catch (RepositoryException e) {
-                       throw new JcrException("Cannot export " + node + " to XML", e);
-               }
-       }
-
        // FILE UPLOAD LISTENER
        private class FUL implements FileUploadListener {
                public void uploadProgress(FileUploadEvent event) {