Move CMS Text framework to Argeo Connect.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 19 Feb 2020 09:58:37 +0000 (10:58 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 19 Feb 2020 09:58:37 +0000 (10:58 +0100)
33 files changed:
org.argeo.cms.e4.rap/e4xmi/cms-demo-rap.e4xmi [deleted file]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsTextEditor.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/forms/FormPageViewer.java
org.argeo.cms.ui/src/org/argeo/cms/forms/MarkupValidatorCopy.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/maintenance/Browse.java
org.argeo.cms.ui/src/org/argeo/cms/text/AbstractTextViewer.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/IdentityTextInterpreter.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/Img.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/MarkupValidatorCopy.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/Paragraph.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/SectionTitle.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextContextMenu.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreter.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreterImpl.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextSection.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/TextStyles.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/ui/img/Dummy.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java [deleted file]
org.argeo.cms.ui/src/org/argeo/cms/util/DefaultImageManager.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/util/SimpleErgonomics.java
org.argeo.cms.ui/src/org/argeo/cms/util/SimpleImageManager.java
org.argeo.cms.ui/src/org/argeo/cms/widgets/Img.java [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/widgets/StyledControl.java
org.argeo.cms.ui/src/org/argeo/cms/widgets/TextStyles.java [new file with mode: 0644]
org.argeo.cms/bnd.bnd
org.argeo.cms/src/org/argeo/cms/CmsNames.java [deleted file]
org.argeo.cms/src/org/argeo/cms/CmsTypes.java [deleted file]
org.argeo.cms/src/org/argeo/cms/cms.cnd [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/http/LinkServlet.java

diff --git a/org.argeo.cms.e4.rap/e4xmi/cms-demo-rap.e4xmi b/org.argeo.cms.e4.rap/e4xmi/cms-demo-rap.e4xmi
deleted file mode 100644 (file)
index 0e2b994..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="ASCII"?>
-<application:Application xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:application="http://www.eclipse.org/ui/2010/UIModel/application" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/ui/basic" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmi:id="_PjHLwMb4EeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.application">
-  <children xsi:type="basic:TrimmedWindow" xmi:id="_QnyU0Mb4EeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.trimmedwindow.0">
-    <children xsi:type="basic:PartStack" xmi:id="_V9EXcMb4EeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.partstack.0">
-      <children xsi:type="basic:Part" xmi:id="_RVKlIMctEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.part.docbook" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.connect.e4.parts.CmsDocBookEditorokEditor" label="DocBook">
-        <toolbar xmi:id="_TANxsMctEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.toolbar.1">
-          <children xsi:type="menu:HandledToolItem" xmi:id="_alIUoMctEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.handledtoolitem.save" label="Save" command="_vsxg8McmEeiIG7Bq51Btuw"/>
-        </toolbar>
-      </children>
-      <children xsi:type="basic:Part" xmi:id="_fPCGgMcCEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.part.texteditor" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.parts.CmsTextEditor" label="Text Editor">
-        <toolbar xmi:id="_jlPucMcmEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.toolbar.0">
-          <children xsi:type="menu:HandledToolItem" xmi:id="_r3TEMMcmEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.handledtoolitem.0" command="_vsxg8McmEeiIG7Bq51Btuw"/>
-        </toolbar>
-      </children>
-      <children xsi:type="basic:Part" xmi:id="_cIlegMb4EeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.part.htmleditor" contributionURI="bundleclass://org.argeo.cms.e4.rap/org.argeo.cms.e4.rap.parts.HtmlEditor" label="HTML Editor"/>
-    </children>
-  </children>
-  <handlers xmi:id="_zqabMMcmEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.handler.0" contributionURI="bundleclass://org.argeo.cms.e4/org.argeo.cms.e4.handlers.SavePart" command="_vsxg8McmEeiIG7Bq51Btuw"/>
-  <commands xmi:id="_vsxg8McmEeiIG7Bq51Btuw" elementId="org.argeo.cms.e4.command.save" commandName="Save"/>
-  <addons xmi:id="_PjHLwcb4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
-  <addons xmi:id="_PjHLwsb4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
-  <addons xmi:id="_PjHLw8b4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
-  <addons xmi:id="_PjHLxMb4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.workbench.commands.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.CommandProcessingAddon"/>
-  <addons xmi:id="_PjHLxcb4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.workbench.contexts.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.ContextProcessingAddon"/>
-  <addons xmi:id="_PjHLxsb4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.workbench.bindings.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench.swt/org.eclipse.e4.ui.workbench.swt.util.BindingProcessingAddon"/>
-  <addons xmi:id="_PjHLx8b4EeiIG7Bq51Btuw" elementId="org.eclipse.e4.ui.workbench.handler.model" contributionURI="bundleclass://org.eclipse.e4.ui.workbench/org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon"/>
-</application:Application>
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsTextEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsTextEditor.java
deleted file mode 100644 (file)
index 4021ead..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.argeo.cms.e4.parts;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.inject.Inject;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.text.StandardTextEditor;
-import org.argeo.cms.viewers.JcrVersionCmsEditable;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.e4.ui.di.Persist;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-
-public class CmsTextEditor implements Observer {
-       @Inject
-       Repository repository;
-
-       @Inject
-       private MPart mpart;
-
-       Session session;
-       JcrVersionCmsEditable cmsEditable;
-
-       @PostConstruct
-       public void createUI(Composite parent) {
-               try {
-                       parent.setLayout(new GridLayout());
-                       session = repository.login();
-                       JcrUtils.loginOrCreateWorkspace(repository, "demo");
-                       Node textNode = JcrUtils.getOrAdd(session.getRootNode(), "text", CmsTypes.CMS_TEXT);
-                       cmsEditable = new JcrVersionCmsEditable(textNode);
-                       if (session.hasPendingChanges())
-                               session.save();
-                       cmsEditable.addObserver(this);
-                       StandardTextEditor textEditor = new StandardTextEditor(parent, SWT.NONE, textNode, cmsEditable);
-                       mpart.setDirty(cmsEditable.isEditing());
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot create text editor", e);
-               }
-       }
-
-       @PreDestroy
-       public void dispose() {
-               JcrUtils.logoutQuietly(session);
-       }
-
-       @Persist
-       public void save() {
-               cmsEditable.stopEditing();
-       }
-
-       @Override
-       public void update(Observable o, Object arg) {
-               // CmsEditable cmsEditable = (CmsEditable) o;
-               mpart.setDirty(isDirty());
-       }
-
-       boolean isDirty() {
-               return cmsEditable.isEditing();
-       }
-
-}
index d6de0464e6fdb5f07d86e873d7098af9a1f602a9..d2af709a811d309e4766ce40c5cfe880ab04e776 100644 (file)
@@ -17,8 +17,6 @@ import javax.jcr.ValueFormatException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
-import org.argeo.cms.text.Img;
-import org.argeo.cms.text.MarkupValidatorCopy;
 import org.argeo.cms.ui.CmsEditable;
 import org.argeo.cms.ui.CmsImageManager;
 import org.argeo.cms.util.CmsUtils;
@@ -27,6 +25,7 @@ import org.argeo.cms.viewers.EditablePart;
 import org.argeo.cms.viewers.Section;
 import org.argeo.cms.viewers.SectionPart;
 import org.argeo.cms.widgets.EditableImage;
+import org.argeo.cms.widgets.Img;
 import org.argeo.cms.widgets.StyledControl;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.jcr.JcrUtils;
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/forms/MarkupValidatorCopy.java b/org.argeo.cms.ui/src/org/argeo/cms/forms/MarkupValidatorCopy.java
new file mode 100644 (file)
index 0000000..f1a5a8c
--- /dev/null
@@ -0,0 +1,169 @@
+package org.argeo.cms.forms;
+
+import java.io.StringReader;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.rap.rwt.SingletonUtil;
+import org.eclipse.swt.widgets.Widget;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Copy of RAP v2.3 since it is in an internal package.
+ */
+class MarkupValidatorCopy {
+
+       // Used by Eclipse Scout project
+       public static final String MARKUP_VALIDATION_DISABLED = "org.eclipse.rap.rwt.markupValidationDisabled";
+
+       private static final String DTD = createDTD();
+       private static final Map<String, String[]> SUPPORTED_ELEMENTS = createSupportedElementsMap();
+       private final SAXParser saxParser;
+
+       public static MarkupValidatorCopy getInstance() {
+               return SingletonUtil.getSessionInstance(MarkupValidatorCopy.class);
+       }
+
+       public MarkupValidatorCopy() {
+               saxParser = createSAXParser();
+       }
+
+       public void validate(String text) {
+               StringBuilder markup = new StringBuilder();
+               markup.append(DTD);
+               markup.append("<html>");
+               markup.append(text);
+               markup.append("</html>");
+               InputSource inputSource = new InputSource(new StringReader(markup.toString()));
+               try {
+                       saxParser.parse(inputSource, new MarkupHandler());
+               } catch (RuntimeException exception) {
+                       throw exception;
+               } catch (Exception exception) {
+                       throw new IllegalArgumentException("Failed to parse markup text", exception);
+               }
+       }
+
+       public static boolean isValidationDisabledFor(Widget widget) {
+               return Boolean.TRUE.equals(widget.getData(MARKUP_VALIDATION_DISABLED));
+       }
+
+       private static SAXParser createSAXParser() {
+               SAXParser result = null;
+               SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+               try {
+                       result = parserFactory.newSAXParser();
+               } catch (Exception exception) {
+                       throw new RuntimeException("Failed to create SAX parser", exception);
+               }
+               return result;
+       }
+
+       private static String createDTD() {
+               StringBuilder result = new StringBuilder();
+               result.append("<!DOCTYPE html [");
+               result.append("<!ENTITY quot \"&#34;\">");
+               result.append("<!ENTITY amp \"&#38;\">");
+               result.append("<!ENTITY apos \"&#39;\">");
+               result.append("<!ENTITY lt \"&#60;\">");
+               result.append("<!ENTITY gt \"&#62;\">");
+               result.append("<!ENTITY nbsp \"&#160;\">");
+               result.append("<!ENTITY ensp \"&#8194;\">");
+               result.append("<!ENTITY emsp \"&#8195;\">");
+               result.append("<!ENTITY ndash \"&#8211;\">");
+               result.append("<!ENTITY mdash \"&#8212;\">");
+               result.append("]>");
+               return result.toString();
+       }
+
+       private static Map<String, String[]> createSupportedElementsMap() {
+               Map<String, String[]> result = new HashMap<String, String[]>();
+               result.put("html", new String[0]);
+               result.put("br", new String[0]);
+               result.put("b", new String[] { "style" });
+               result.put("strong", new String[] { "style" });
+               result.put("i", new String[] { "style" });
+               result.put("em", new String[] { "style" });
+               result.put("sub", new String[] { "style" });
+               result.put("sup", new String[] { "style" });
+               result.put("big", new String[] { "style" });
+               result.put("small", new String[] { "style" });
+               result.put("del", new String[] { "style" });
+               result.put("ins", new String[] { "style" });
+               result.put("code", new String[] { "style" });
+               result.put("samp", new String[] { "style" });
+               result.put("kbd", new String[] { "style" });
+               result.put("var", new String[] { "style" });
+               result.put("cite", new String[] { "style" });
+               result.put("dfn", new String[] { "style" });
+               result.put("q", new String[] { "style" });
+               result.put("abbr", new String[] { "style", "title" });
+               result.put("span", new String[] { "style" });
+               result.put("img", new String[] { "style", "src", "width", "height", "title", "alt" });
+               result.put("a", new String[] { "style", "href", "target", "title" });
+               return result;
+       }
+
+       private static class MarkupHandler extends DefaultHandler {
+
+               @Override
+               public void startElement(String uri, String localName, String name, Attributes attributes) {
+                       checkSupportedElements(name, attributes);
+                       checkSupportedAttributes(name, attributes);
+                       checkMandatoryAttributes(name, attributes);
+               }
+
+               private static void checkSupportedElements(String elementName, Attributes attributes) {
+                       if (!SUPPORTED_ELEMENTS.containsKey(elementName)) {
+                               throw new IllegalArgumentException("Unsupported element in markup text: " + elementName);
+                       }
+               }
+
+               private static void checkSupportedAttributes(String elementName, Attributes attributes) {
+                       if (attributes.getLength() > 0) {
+                               List<String> supportedAttributes = Arrays.asList(SUPPORTED_ELEMENTS.get(elementName));
+                               int index = 0;
+                               String attributeName = attributes.getQName(index);
+                               while (attributeName != null) {
+                                       if (!supportedAttributes.contains(attributeName)) {
+                                               String message = "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
+                                               message = MessageFormat.format(message, new Object[] { attributeName, elementName });
+                                               throw new IllegalArgumentException(message);
+                                       }
+                                       index++;
+                                       attributeName = attributes.getQName(index);
+                               }
+                       }
+               }
+
+               private static void checkMandatoryAttributes(String elementName, Attributes attributes) {
+                       checkIntAttribute(elementName, attributes, "img", "width");
+                       checkIntAttribute(elementName, attributes, "img", "height");
+               }
+
+               private static void checkIntAttribute(String elementName, Attributes attributes, String checkedElementName,
+                               String checkedAttributeName) {
+                       if (checkedElementName.equals(elementName)) {
+                               String attribute = attributes.getValue(checkedAttributeName);
+                               try {
+                                       Integer.parseInt(attribute);
+                               } catch (NumberFormatException exception) {
+                                       String message = "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
+                                       Object[] arguments = new Object[] { checkedAttributeName, checkedElementName };
+                                       message = MessageFormat.format(message, arguments);
+                                       throw new IllegalArgumentException(message);
+                               }
+                       }
+               }
+
+       }
+
+}
index 0389205ca096574d7e066fe43424f8b494d7f737..384cd72ef91efc1e67dfc08d1c45e4c825fdfb42 100644 (file)
@@ -1,6 +1,5 @@
 package org.argeo.cms.maintenance;
 
-import static javax.jcr.Node.JCR_CONTENT;
 import static org.eclipse.swt.SWT.RIGHT;
 
 import java.text.DateFormat;
@@ -17,12 +16,11 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Value;
 
 import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.text.Img;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.util.CmsLink;
 import org.argeo.cms.util.CmsUtils;
 import org.argeo.cms.widgets.EditableImage;
+import org.argeo.cms.widgets.Img;
 import org.argeo.jcr.JcrUtils;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.jface.viewers.ILazyContentProvider;
@@ -59,8 +57,7 @@ public class Browse implements CmsUiProvider {
        private final static String BROWSE_PREFIX = "browse#";
        private final static int THUMBNAIL_WIDTH = 400;
        private final static int COLUMN_WIDTH = 160;
-       private DateFormat timeFormatter = new SimpleDateFormat(
-                       "dd-MM-yyyy', 'HH:mm");
+       private DateFormat timeFormatter = new SimpleDateFormat("dd-MM-yyyy', 'HH:mm");
 
        // keep a cache of the opened nodes
        // Key is the path
@@ -75,8 +72,7 @@ public class Browse implements CmsUiProvider {
        private String initialPath;
 
        @Override
-       public Control createUi(Composite parent, Node context)
-                       throws RepositoryException {
+       public Control createUi(Composite parent, Node context) throws RepositoryException {
                if (context == null)
                        // return null;
                        throw new CmsException("Context cannot be null");
@@ -106,8 +102,7 @@ public class Browse implements CmsUiProvider {
                return null;
        }
 
-       private void createBrowserPart(Composite parent, Node context)
-                       throws RepositoryException {
+       private void createBrowserPart(Composite parent, Node context) throws RepositoryException {
                GridLayout layout = CmsUtils.noSpaceGridLayout();
                parent.setLayout(layout);
                Composite filterCmp = new Composite(parent, SWT.NO_FOCUS);
@@ -117,8 +112,7 @@ public class Browse implements CmsUiProvider {
                addFilterPanel(filterCmp);
 
                // scrolled composite
-               scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER
-                               | SWT.NO_FOCUS);
+               scrolledCmp = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.BORDER | SWT.NO_FOCUS);
                scrolledCmp.setLayoutData(CmsUtils.fillAll());
                scrolledCmp.setExpandVertical(true);
                scrolledCmp.setExpandHorizontal(true);
@@ -132,25 +126,21 @@ public class Browse implements CmsUiProvider {
                        @Override
                        public void controlResized(ControlEvent e) {
                                Rectangle r = scrolledCmp.getClientArea();
-                               scrolledCmp.setMinSize(colViewer.computeSize(SWT.DEFAULT,
-                                               r.height));
+                               scrolledCmp.setMinSize(colViewer.computeSize(SWT.DEFAULT, r.height));
                        }
                });
                initExplorer(colViewer, context);
        }
 
-       private Control initExplorer(Composite parent, Node context)
-                       throws RepositoryException {
+       private Control initExplorer(Composite parent, Node context) throws RepositoryException {
                parent.setLayout(CmsUtils.noSpaceGridLayout());
                createBrowserColumn(parent, context);
                return null;
        }
 
-       private Control createBrowserColumn(Composite parent, Node context)
-                       throws RepositoryException {
+       private Control createBrowserColumn(Composite parent, Node context) throws RepositoryException {
                // TODO style is not correctly managed.
-               FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(
-                               parent, SWT.BORDER | SWT.NO_FOCUS, context);
+               FilterEntitiesVirtualTable table = new FilterEntitiesVirtualTable(parent, SWT.BORDER | SWT.NO_FOCUS, context);
                // CmsUtils.style(table, ArgeoOrgStyle.browserColumn.style());
                table.filterList("*");
                table.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true));
@@ -189,8 +179,7 @@ public class Browse implements CmsUiProvider {
                                // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
                                FilterEntitiesVirtualTable currTable = null;
                                if (currEdited != null) {
-                                       FilterEntitiesVirtualTable table = browserCols
-                                                       .get(getPath(currEdited));
+                                       FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
                                        if (table != null && !table.isDisposed())
                                                currTable = table;
                                }
@@ -200,26 +189,21 @@ public class Browse implements CmsUiProvider {
                                                currTable.setFocus();
                                        else if (e.keyCode == SWT.BS) {
                                                if (filterTxt.getText().equals("")
-                                                               && !(getPath(currEdited).equals("/") || getPath(
-                                                                               currEdited).equals(initialPath))) {
+                                                               && !(getPath(currEdited).equals("/") || getPath(currEdited).equals(initialPath))) {
                                                        setEdited(currEdited.getParent());
                                                        e.doit = false;
                                                        filterTxt.setFocus();
                                                }
                                        } else if (e.keyCode == SWT.TAB && !shiftPressed) {
-                                               if (currEdited.getNodes(filterTxt.getText() + "*")
-                                                               .getSize() == 1) {
-                                                       setEdited(currEdited.getNodes(
-                                                                       filterTxt.getText() + "*").nextNode());
+                                               if (currEdited.getNodes(filterTxt.getText() + "*").getSize() == 1) {
+                                                       setEdited(currEdited.getNodes(filterTxt.getText() + "*").nextNode());
                                                }
                                                filterTxt.setFocus();
                                                e.doit = false;
                                        }
                                } catch (RepositoryException e1) {
-                                       throw new CmsException(
-                                                       "Unexpected error in key management for "
-                                                                       + currEdited + "with filter "
-                                                                       + filterTxt.getText(), e1);
+                                       throw new CmsException("Unexpected error in key management for " + currEdited + "with filter "
+                                                       + filterTxt.getText(), e1);
                                }
 
                        }
@@ -255,9 +239,6 @@ public class Browse implements CmsUiProvider {
                        currParPath = JcrUtils.parentPath(currNodePath);
                if ("".equals(currParPath))
                        currParPath = "/";
-               
-               
-               
 
                Object[][] colMatrix = new Object[browserCols.size()][2];
 
@@ -271,13 +252,9 @@ public class Browse implements CmsUiProvider {
                                // workaround for same name siblings
                                // fix me weird side effect when we go left or click on anb
                                // already selected, unfocused node
-                               if (leaveOpened
-                                               && (path.lastIndexOf("/") == 0
-                                                               && currNodePath.lastIndexOf("/") == 0 || JcrUtils
-                                                               .parentPath(path).equals(
-                                                                               JcrUtils.parentPath(currNodePath))))
-                                       leaveOpened = JcrUtils.lastPathElement(path).equals(
-                                                       JcrUtils.lastPathElement(currNodePath));
+                               if (leaveOpened && (path.lastIndexOf("/") == 0 && currNodePath.lastIndexOf("/") == 0
+                                               || JcrUtils.parentPath(path).equals(JcrUtils.parentPath(currNodePath))))
+                                       leaveOpened = JcrUtils.lastPathElement(path).equals(JcrUtils.lastPathElement(currNodePath));
 
                                if (!leaveOpened)
                                        k = i;
@@ -306,8 +283,7 @@ public class Browse implements CmsUiProvider {
                if (!browserCols.containsKey(currNodePath))
                        createBrowserColumn(colViewer, node);
 
-               colViewer.setLayout(CmsUtils.noSpaceGridLayout(new GridLayout(
-                               browserCols.size(), false)));
+               colViewer.setLayout(CmsUtils.noSpaceGridLayout(new GridLayout(browserCols.size(), false)));
                // colViewer.pack();
                colViewer.layout();
                // also resize the scrolled composite
@@ -323,8 +299,7 @@ public class Browse implements CmsUiProvider {
                if (!fromOutside)
                        if (currEdited != null) {
                                String filter = filterTxt.getText() + "*";
-                               FilterEntitiesVirtualTable table = browserCols
-                                               .get(getPath(currEdited));
+                               FilterEntitiesVirtualTable table = browserCols.get(getPath(currEdited));
                                if (table != null && !table.isDisposed())
                                        table.filterList(filter);
                        }
@@ -342,34 +317,29 @@ public class Browse implements CmsUiProvider {
        private Point imageWidth = new Point(250, 0);
 
        /**
-        * Recreates the content of the box that displays information about the
-        * current selected node.
+        * Recreates the content of the box that displays information about the current
+        * selected node.
         */
-       private Control createNodeView(Composite parent, Node context)
-                       throws RepositoryException {
+       private Control createNodeView(Composite parent, Node context) throws RepositoryException {
 
                parent.setLayout(new GridLayout(2, false));
 
                if (isImg(context)) {
                        EditableImage image = new Img(parent, RIGHT, context, imageWidth);
-                       image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true,
-                                       false, 2, 1));
+                       image.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 2, 1));
                }
 
                // Name and primary type
                Label contextL = new Label(parent, SWT.NONE);
                contextL.setData(RWT.MARKUP_ENABLED, true);
                contextL.setText("<b>" + context.getName() + "</b>");
-               new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType()
-                               .getName());
+               new Label(parent, SWT.NONE).setText(context.getPrimaryNodeType().getName());
 
                // Children
                for (NodeIterator nIt = context.getNodes(); nIt.hasNext();) {
                        Node child = nIt.nextNode();
-                       new CmsLink(child.getName(), BROWSE_PREFIX + child.getPath())
-                                       .createUi(parent, context);
-                       new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType()
-                                       .getName());
+                       new CmsLink(child.getName(), BROWSE_PREFIX + child.getPath()).createUi(parent, context);
+                       new Label(parent, SWT.NONE).setText(child.getPrimaryNodeType().getName());
                }
 
                // Properties
@@ -377,8 +347,7 @@ public class Browse implements CmsUiProvider {
                        Property property = pIt.nextProperty();
                        Label label = new Label(parent, SWT.NONE);
                        label.setText(property.getName());
-                       label.setToolTipText(JcrUtils
-                                       .getPropertyDefinitionAsString(property));
+                       label.setToolTipText(JcrUtils.getPropertyDefinitionAsString(property));
                        new Label(parent, SWT.NONE).setText(getPropAsString(property));
                }
 
@@ -386,11 +355,12 @@ public class Browse implements CmsUiProvider {
        }
 
        private boolean isImg(Node node) throws RepositoryException {
-               return node.hasNode(JCR_CONTENT) && node.isNodeType(CmsTypes.CMS_IMAGE);
+               // TODO support images
+               return false;
+//             return node.hasNode(JCR_CONTENT) && node.isNodeType(CmsTypes.CMS_IMAGE);
        }
 
-       private String getPropAsString(Property property)
-                       throws RepositoryException {
+       private String getPropAsString(Property property) throws RepositoryException {
                String result = "";
                if (property.isMultiple()) {
                        result = getMultiAsString(property, ", ");
@@ -406,8 +376,7 @@ public class Browse implements CmsUiProvider {
                return result;
        }
 
-       private String getMultiAsString(Property property, String separator)
-                       throws RepositoryException {
+       private String getMultiAsString(Property property, String separator) throws RepositoryException {
                if (separator == null)
                        separator = "; ";
                Value[] values = property.getValues();
@@ -445,8 +414,7 @@ public class Browse implements CmsUiProvider {
                        if (entityViewer.getSelection().isEmpty()) {
                                Object first = entityViewer.getElementAt(0);
                                if (first != null) {
-                                       entityViewer.setSelection(new StructuredSelection(first),
-                                                       true);
+                                       entityViewer.setSelection(new StructuredSelection(first), true);
                                }
                        }
                        return entityViewer.getTable().setFocus();
@@ -457,14 +425,12 @@ public class Browse implements CmsUiProvider {
                                NodeIterator nit = context.getNodes(filter);
                                refreshFilteredList(nit);
                        } catch (RepositoryException e) {
-                               throw new CmsException("Unable to filter " + getNode()
-                                               + " children with filter " + filter, e);
+                               throw new CmsException("Unable to filter " + getNode() + " children with filter " + filter, e);
                        }
 
                }
 
-               public FilterEntitiesVirtualTable(Composite parent, int style,
-                               Node context) {
+               public FilterEntitiesVirtualTable(Composite parent, int style, Node context) {
                        super(parent, SWT.NO_FOCUS);
                        this.context = context;
                        populate();
@@ -500,28 +466,25 @@ public class Browse implements CmsUiProvider {
                        CmsUtils.style(table, MaintenanceStyles.BROWSER_COLUMN);
 
                        // first column
-                       TableViewerColumn column = new TableViewerColumn(entityViewer,
-                                       SWT.NONE);
+                       TableViewerColumn column = new TableViewerColumn(entityViewer, SWT.NONE);
                        TableColumn tcol = column.getColumn();
                        tcol.setWidth(COLUMN_WIDTH);
                        tcol.setResizable(true);
                        column.setLabelProvider(new SimpleNameLP());
 
                        entityViewer.setContentProvider(new MyLazyCP(entityViewer));
-                       entityViewer
-                                       .addSelectionChangedListener(new ISelectionChangedListener() {
-
-                                               @Override
-                                               public void selectionChanged(SelectionChangedEvent event) {
-                                                       IStructuredSelection selection = (IStructuredSelection) entityViewer
-                                                                       .getSelection();
-                                                       if (selection.isEmpty())
-                                                               return;
-                                                       else
-                                                               setEdited((Node) selection.getFirstElement());
+                       entityViewer.addSelectionChangedListener(new ISelectionChangedListener() {
 
-                                               }
-                                       });
+                               @Override
+                               public void selectionChanged(SelectionChangedEvent event) {
+                                       IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
+                                       if (selection.isEmpty())
+                                               return;
+                                       else
+                                               setEdited((Node) selection.getFirstElement());
+
+                               }
+                       });
 
                        table.addKeyListener(new KeyListener() {
                                private static final long serialVersionUID = -330694313896036230L;
@@ -533,8 +496,7 @@ public class Browse implements CmsUiProvider {
                                @Override
                                public void keyPressed(KeyEvent e) {
 
-                                       IStructuredSelection selection = (IStructuredSelection) entityViewer
-                                                       .getSelection();
+                                       IStructuredSelection selection = (IStructuredSelection) entityViewer.getSelection();
                                        Node selected = null;
                                        if (!selection.isEmpty())
                                                selected = ((Node) selection.getFirstElement());
@@ -556,8 +518,8 @@ public class Browse implements CmsUiProvider {
                                                        }
                                                }
                                        } catch (RepositoryException ie) {
-                                               throw new CmsException("Error while managing arrow "
-                                                               + "events in the browser for " + selected, ie);
+                                               throw new CmsException("Error while managing arrow " + "events in the browser for " + selected,
+                                                               ie);
                                        }
                                }
                        });
@@ -575,8 +537,7 @@ public class Browse implements CmsUiProvider {
                        public void dispose() {
                        }
 
-                       public void inputChanged(Viewer viewer, Object oldInput,
-                                       Object newInput) {
+                       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
                                // IMPORTANT: don't forget this: an exception will be thrown if
                                // a selected object is not part of the results anymore.
                                viewer.setSelection(null);
@@ -605,8 +566,7 @@ public class Browse implements CmsUiProvider {
                                        try {
                                                return curr.getName();
                                        } catch (RepositoryException e) {
-                                               throw new CmsException("Unable to get name for"
-                                                               + curr);
+                                               throw new CmsException("Unable to get name for" + curr);
                                        }
                                }
                                return super.getText(element);
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/AbstractTextViewer.java b/org.argeo.cms.ui/src/org/argeo/cms/text/AbstractTextViewer.java
deleted file mode 100644 (file)
index 2416cbc..0000000
+++ /dev/null
@@ -1,888 +0,0 @@
-package org.argeo.cms.text;
-
-import static javax.jcr.Property.JCR_TITLE;
-import static org.argeo.cms.util.CmsUtils.fillWidth;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Observer;
-
-import javax.jcr.Item;
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.AbstractPageViewer;
-import org.argeo.cms.viewers.EditablePart;
-import org.argeo.cms.viewers.NodePart;
-import org.argeo.cms.viewers.PropertyPart;
-import org.argeo.cms.viewers.Section;
-import org.argeo.cms.viewers.SectionPart;
-import org.argeo.cms.widgets.EditableImage;
-import org.argeo.cms.widgets.EditableText;
-import org.argeo.cms.widgets.StyledControl;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.fileupload.FileDetails;
-import org.eclipse.rap.fileupload.FileUploadEvent;
-import org.eclipse.rap.fileupload.FileUploadHandler;
-import org.eclipse.rap.fileupload.FileUploadListener;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-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.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Text;
-
-/** Base class for text viewers and editors. */
-public abstract class AbstractTextViewer extends AbstractPageViewer implements
-               CmsNames, KeyListener, Observer {
-       private static final long serialVersionUID = -2401274679492339668L;
-       private final static Log log = LogFactory.getLog(AbstractTextViewer.class);
-
-       private final Section mainSection;
-
-       private TextInterpreter textInterpreter = new TextInterpreterImpl();
-       private CmsImageManager imageManager = CmsUtils.getCmsView()
-                       .getImageManager();
-
-       private FileUploadListener fileUploadListener;
-       private TextContextMenu styledTools;
-
-       private final boolean flat;
-
-       protected AbstractTextViewer(Section parent, int style,
-                       CmsEditable cmsEditable) {
-               super(parent, style, cmsEditable);
-               flat = SWT.FLAT == (style & SWT.FLAT);
-
-               if (getCmsEditable().canEdit()) {
-                       fileUploadListener = new FUL();
-                       styledTools = new TextContextMenu(this, parent.getDisplay());
-               }
-               this.mainSection = parent;
-               initModelIfNeeded(mainSection.getNode());
-               // layout(this.mainSection);
-       }
-
-       @Override
-       public Control getControl() {
-               return mainSection;
-       }
-
-       protected void refresh(Control control) throws RepositoryException {
-               if (!(control instanceof Section))
-                       return;
-               Section section = (Section) control;
-               if (section instanceof TextSection) {
-                       CmsUtils.clear(section);
-                       Node node = section.getNode();
-                       TextSection textSection = (TextSection) section;
-                       if (node.hasProperty(Property.JCR_TITLE)) {
-                               if (section.getHeader() == null)
-                                       section.createHeader();
-                               if (node.hasProperty(Property.JCR_TITLE)) {
-                                       SectionTitle title = newSectionTitle(textSection, node);
-                                       title.setLayoutData(CmsUtils.fillWidth());
-                                       updateContent(title);
-                               }
-                       }
-
-                       for (NodeIterator ni = node.getNodes(CMS_P); ni.hasNext();) {
-                               Node child = ni.nextNode();
-                               final SectionPart sectionPart;
-                               if (child.isNodeType(CmsTypes.CMS_IMAGE)
-                                               || child.isNodeType(NodeType.NT_FILE)) {
-                                       sectionPart = newImg(textSection, child);
-                               } else if (child.isNodeType(CmsTypes.CMS_STYLED)) {
-                                       sectionPart = newParagraph(textSection, child);
-                               } else {
-                                       sectionPart = newSectionPart(textSection, child);
-                                       if (sectionPart == null)
-                                               throw new CmsException("Unsupported node " + child);
-                                       // TODO list node types in exception
-                               }
-                               if (sectionPart instanceof Control)
-                                       ((Control) sectionPart).setLayoutData(CmsUtils.fillWidth());
-                       }
-
-                       if (!flat)
-                               for (NodeIterator ni = section.getNode().getNodes(CMS_H); ni
-                                               .hasNext();) {
-                                       Node child = ni.nextNode();
-                                       if (child.isNodeType(CmsTypes.CMS_SECTION)) {
-                                               TextSection newSection = new TextSection(section,
-                                                               SWT.NONE, child);
-                                               newSection.setLayoutData(CmsUtils.fillWidth());
-                                               refresh(newSection);
-                                       }
-                               }
-               } else {
-                       for (Section s : section.getSubSections().values())
-                               refresh(s);
-               }
-               // section.layout();
-       }
-
-       /** To be overridden in order to provide additional SectionPart types */
-       protected SectionPart newSectionPart(TextSection textSection, Node node) {
-               return null;
-       }
-
-       // CRUD
-       protected Paragraph newParagraph(TextSection parent, Node node)
-                       throws RepositoryException {
-               Paragraph paragraph = new Paragraph(parent, parent.getStyle(), node);
-               updateContent(paragraph);
-               paragraph.setLayoutData(fillWidth());
-               paragraph.setMouseListener(getMouseListener());
-               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;
-
-                       @Override
-                       protected void setContainerLayoutData(Composite composite) {
-                               composite.setLayoutData(CmsUtils.grabWidth(SWT.CENTER,
-                                               SWT.DEFAULT));
-                       }
-
-                       @Override
-                       protected void setControlLayoutData(Control control) {
-                               control.setLayoutData(CmsUtils.grabWidth(SWT.CENTER,
-                                               SWT.DEFAULT));
-                       }
-               };
-               img.setLayoutData(CmsUtils.grabWidth(SWT.CENTER, SWT.DEFAULT));
-               updateContent(img);
-               img.setMouseListener(getMouseListener());
-               return img;
-       }
-
-       protected SectionTitle newSectionTitle(TextSection parent, Node node)
-                       throws RepositoryException {
-               SectionTitle title = new SectionTitle(parent.getHeader(),
-                               parent.getStyle(), node.getProperty(JCR_TITLE));
-               updateContent(title);
-               title.setMouseListener(getMouseListener());
-               return title;
-       }
-
-       protected SectionTitle prepareSectionTitle(Section newSection,
-                       String titleText) throws RepositoryException {
-               Node sectionNode = newSection.getNode();
-               if (!sectionNode.hasProperty(JCR_TITLE))
-                       sectionNode.setProperty(Property.JCR_TITLE, "");
-               getTextInterpreter().write(sectionNode.getProperty(Property.JCR_TITLE),
-                               titleText);
-               if (newSection.getHeader() == null)
-                       newSection.createHeader();
-               SectionTitle sectionTitle = newSectionTitle((TextSection) newSection,
-                               sectionNode);
-               return sectionTitle;
-       }
-
-       protected void updateContent(EditablePart part) throws RepositoryException {
-               if (part instanceof SectionPart) {
-                       SectionPart sectionPart = (SectionPart) part;
-                       Node partNode = sectionPart.getNode();
-
-                       if (part instanceof StyledControl
-                                       && (sectionPart.getSection() instanceof TextSection)) {
-                               TextSection section = (TextSection) sectionPart.getSection();
-                               StyledControl styledControl = (StyledControl) part;
-                               if (partNode.isNodeType(CmsTypes.CMS_STYLED)) {
-                                       String style = partNode.hasProperty(CMS_STYLE) ? partNode
-                                                       .getProperty(CMS_STYLE).getString() : section
-                                                       .getDefaultTextStyle();
-                                       styledControl.setStyle(style);
-                               }
-                       }
-                       // use control AFTER setting style, since it may have been reset
-
-                       if (part instanceof EditableText) {
-                               EditableText paragraph = (EditableText) part;
-                               if (paragraph == getEdited())
-                                       paragraph.setText(textInterpreter.read(partNode));
-                               else
-                                       paragraph.setText(textInterpreter.raw(partNode));
-                       } else if (part instanceof EditableImage) {
-                               EditableImage editableImage = (EditableImage) part;
-                               imageManager.load(partNode, part.getControl(),
-                                               editableImage.getPreferredImageSize());
-                       }
-               } else if (part instanceof SectionTitle) {
-                       SectionTitle title = (SectionTitle) part;
-                       title.setStyle(title.getSection().getTitleStyle());
-                       // use control AFTER setting style
-                       if (title == getEdited())
-                               title.setText(textInterpreter.read(title.getProperty()));
-                       else
-                               title.setText(textInterpreter.raw(title.getProperty()));
-               }
-       }
-
-       // OVERRIDDEN FROM PARENT VIEWER
-       @Override
-       protected void save(EditablePart part) throws RepositoryException {
-               if (part instanceof EditableText) {
-                       EditableText et = (EditableText) part;
-                       String text = ((Text) et.getControl()).getText();
-
-                       String[] lines = text.split("[\r\n]+");
-                       assert lines.length != 0;
-                       saveLine(part, lines[0]);
-                       if (lines.length > 1) {
-                               ArrayList<Control> toLayout = new ArrayList<Control>();
-                               if (part instanceof Paragraph) {
-                                       Paragraph currentParagraph = (Paragraph) et;
-                                       Section section = currentParagraph.getSection();
-                                       Node sectionNode = section.getNode();
-                                       Node currentParagraphN = currentParagraph.getNode();
-                                       for (int i = 1; i < lines.length; i++) {
-                                               Node newNode = sectionNode.addNode(CMS_P);
-                                               newNode.addMixin(CmsTypes.CMS_STYLED);
-                                               saveLine(newNode, lines[i]);
-                                               // second node was create as last, if it is not the next
-                                               // one, it
-                                               // means there are some in between and we can take the
-                                               // one at
-                                               // index+1 for the re-order
-                                               if (newNode.getIndex() > currentParagraphN.getIndex() + 1) {
-                                                       sectionNode.orderBefore(p(newNode.getIndex()),
-                                                                       p(currentParagraphN.getIndex() + 1));
-                                               }
-                                               Paragraph newParagraph = newParagraph(
-                                                               (TextSection) section, newNode);
-                                               newParagraph.moveBelow(currentParagraph);
-                                               toLayout.add(newParagraph);
-
-                                               currentParagraph = newParagraph;
-                                               currentParagraphN = newNode;
-                                       }
-                                       persistChanges(sectionNode);
-                               }
-                               // TODO or rather return the created paragarphs?
-                               layout(toLayout.toArray(new Control[toLayout.size()]));
-                       }
-               }
-       }
-
-       protected void saveLine(EditablePart part, String line) {
-               if (part instanceof NodePart) {
-                       saveLine(((NodePart) part).getNode(), line);
-               } else if (part instanceof PropertyPart) {
-                       saveLine(((PropertyPart) part).getProperty(), line);
-               } else {
-                       throw new CmsException("Unsupported part " + part);
-               }
-       }
-
-       protected void saveLine(Item item, String line) {
-               line = line.trim();
-               textInterpreter.write(item, line);
-       }
-
-       @Override
-       protected void prepare(EditablePart part, Object caretPosition) {
-               Control control = part.getControl();
-               if (control instanceof Text) {
-                       Text text = (Text) control;
-                       if (caretPosition != null)
-                               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
-                               }
-                       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" });
-                       text.setData(RWT.CANCEL_KEYS, new String[] { "RETURN",
-                                       "ALT+ARROW_LEFT", "ALT+ARROW_RIGHT" });
-                       text.addKeyListener(this);
-               } else if (part instanceof Img) {
-                       ((Img) part).setFileUploadListener(fileUploadListener);
-               }
-       }
-
-       // REQUIRED BY CONTEXT MENU
-       void setParagraphStyle(Paragraph paragraph, String style) {
-               try {
-                       Node paragraphNode = paragraph.getNode();
-                       paragraphNode.setProperty(CMS_STYLE, style);
-                       persistChanges(paragraphNode);
-                       updateContent(paragraph);
-                       layout(paragraph);
-               } catch (RepositoryException e1) {
-                       throw new CmsException("Cannot set style " + style + " on "
-                                       + paragraph, e1);
-               }
-       }
-
-       void deletePart(SectionPart paragraph) {
-               try {
-                       Node paragraphNode = paragraph.getNode();
-                       Section section = paragraph.getSection();
-                       Session session = paragraphNode.getSession();
-                       paragraphNode.remove();
-                       session.save();
-                       if (paragraph instanceof Control)
-                               ((Control) paragraph).dispose();
-                       layout(section);
-               } catch (RepositoryException e1) {
-                       throw new CmsException("Cannot delete " + paragraph, e1);
-               }
-       }
-
-       String getRawParagraphText(Paragraph paragraph) {
-               return textInterpreter.raw(paragraph.getNode());
-       }
-
-       // COMMANDS
-       protected void splitEdit() {
-               checkEdited();
-               try {
-                       if (getEdited() instanceof Paragraph) {
-                               Paragraph paragraph = (Paragraph) getEdited();
-                               Text text = (Text) paragraph.getControl();
-                               int caretPosition = text.getCaretPosition();
-                               String txt = text.getText();
-                               String first = txt.substring(0, caretPosition);
-                               String second = txt.substring(caretPosition);
-                               Node firstNode = paragraph.getNode();
-                               Node sectionNode = firstNode.getParent();
-                               firstNode.setProperty(CMS_CONTENT, first);
-                               Node secondNode = sectionNode.addNode(CMS_P);
-                               secondNode.addMixin(CmsTypes.CMS_STYLED);
-                               // second node was create as last, if it is not the next one, it
-                               // means there are some in between and we can take the one at
-                               // index+1 for the re-order
-                               if (secondNode.getIndex() > firstNode.getIndex() + 1) {
-                                       sectionNode.orderBefore(p(secondNode.getIndex()),
-                                                       p(firstNode.getIndex() + 1));
-                               }
-
-                               // if we die in between, at least we still have the whole text
-                               // in the first node
-                               try {
-                                       textInterpreter.write(secondNode, second);
-                                       textInterpreter.write(firstNode, first);
-                               } catch (Exception e) {
-                                       // so that no additional nodes are created:
-                                       JcrUtils.discardUnderlyingSessionQuietly(firstNode);
-                                       throw e;
-                               }
-
-                               persistChanges(firstNode);
-
-                               Paragraph secondParagraph = paragraphSplitted(paragraph,
-                                               secondNode);
-                               edit(secondParagraph, 0);
-                       } else if (getEdited() instanceof SectionTitle) {
-                               SectionTitle sectionTitle = (SectionTitle) getEdited();
-                               Text text = (Text) sectionTitle.getControl();
-                               String txt = text.getText();
-                               int caretPosition = text.getCaretPosition();
-                               Section section = sectionTitle.getSection();
-                               Node sectionNode = section.getNode();
-                               Node paragraphNode = sectionNode.addNode(CMS_P);
-                               paragraphNode.addMixin(CmsTypes.CMS_STYLED);
-                               textInterpreter.write(paragraphNode,
-                                               txt.substring(caretPosition));
-                               textInterpreter.write(
-                                               sectionNode.getProperty(Property.JCR_TITLE),
-                                               txt.substring(0, caretPosition));
-                               sectionNode.orderBefore(p(paragraphNode.getIndex()), p(1));
-                               persistChanges(sectionNode);
-
-                               Paragraph paragraph = sectionTitleSplitted(sectionTitle,
-                                               paragraphNode);
-                               // section.layout();
-                               edit(paragraph, 0);
-                       }
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot split " + getEdited(), e);
-               }
-       }
-
-       protected void mergeWithPrevious() {
-               checkEdited();
-               try {
-                       Paragraph paragraph = (Paragraph) getEdited();
-                       Text text = (Text) paragraph.getControl();
-                       String txt = text.getText();
-                       Node paragraphNode = paragraph.getNode();
-                       if (paragraphNode.getIndex() == 1)
-                               return;// do nothing
-                       Node sectionNode = paragraphNode.getParent();
-                       Node previousNode = sectionNode
-                                       .getNode(p(paragraphNode.getIndex() - 1));
-                       String previousTxt = textInterpreter.read(previousNode);
-                       textInterpreter.write(previousNode, previousTxt + txt);
-                       paragraphNode.remove();
-                       persistChanges(sectionNode);
-
-                       Paragraph previousParagraph = paragraphMergedWithPrevious(
-                                       paragraph, previousNode);
-                       edit(previousParagraph, previousTxt.length());
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot stop editing", e);
-               }
-       }
-
-       protected void mergeWithNext() {
-               checkEdited();
-               try {
-                       Paragraph paragraph = (Paragraph) getEdited();
-                       Text text = (Text) paragraph.getControl();
-                       String txt = text.getText();
-                       Node paragraphNode = paragraph.getNode();
-                       Node sectionNode = paragraphNode.getParent();
-                       NodeIterator paragraphNodes = sectionNode.getNodes(CMS_P);
-                       long size = paragraphNodes.getSize();
-                       if (paragraphNode.getIndex() == size)
-                               return;// do nothing
-                       Node nextNode = sectionNode
-                                       .getNode(p(paragraphNode.getIndex() + 1));
-                       String nextTxt = textInterpreter.read(nextNode);
-                       textInterpreter.write(paragraphNode, txt + nextTxt);
-
-                       Section section = paragraph.getSection();
-                       Paragraph removed = (Paragraph) section.getSectionPart(nextNode
-                                       .getIdentifier());
-
-                       nextNode.remove();
-                       persistChanges(sectionNode);
-
-                       paragraphMergedWithNext(paragraph, removed);
-                       edit(paragraph, txt.length());
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot stop editing", e);
-               }
-       }
-
-       protected synchronized void upload(EditablePart part) {
-               try {
-                       if (part instanceof SectionPart) {
-                               SectionPart sectionPart = (SectionPart) part;
-                               Node partNode = sectionPart.getNode();
-                               int partIndex = partNode.getIndex();
-                               Section section = sectionPart.getSection();
-                               Node sectionNode = section.getNode();
-
-                               if (part instanceof Paragraph) {
-                                       Node newNode = sectionNode.addNode(CMS_P, NodeType.NT_FILE);
-                                       newNode.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
-                                       JcrUtils.copyBytesAsFile(sectionNode,
-                                                       p(newNode.getIndex()), new byte[0]);
-                                       if (partIndex < newNode.getIndex() - 1) {
-                                               // was not last
-                                               sectionNode.orderBefore(p(newNode.getIndex()),
-                                                               p(partIndex - 1));
-                                       }
-                                       // sectionNode.orderBefore(p(partNode.getIndex()),
-                                       // p(newNode.getIndex()));
-                                       persistChanges(sectionNode);
-                                       Img img = newImg((TextSection) section, newNode);
-                                       edit(img, null);
-                                       layout(img.getControl());
-                               } else if (part instanceof Img) {
-                                       if (getEdited() == part)
-                                               return;
-                                       edit(part, null);
-                                       layout(part.getControl());
-                               }
-                       }
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot upload", e);
-               }
-       }
-
-       protected void deepen() {
-               if (flat)
-                       return;
-               checkEdited();
-               try {
-                       if (getEdited() instanceof Paragraph) {
-                               Paragraph paragraph = (Paragraph) getEdited();
-                               Text text = (Text) paragraph.getControl();
-                               String txt = text.getText();
-                               Node paragraphNode = paragraph.getNode();
-                               Section section = paragraph.getSection();
-                               Node sectionNode = section.getNode();
-                               // main title
-                               if (section == mainSection && section instanceof TextSection
-                                               && paragraphNode.getIndex() == 1
-                                               && !sectionNode.hasProperty(JCR_TITLE)) {
-                                       SectionTitle sectionTitle = prepareSectionTitle(section,
-                                                       txt);
-                                       edit(sectionTitle, 0);
-                                       return;
-                               }
-                               Node newSectionNode = sectionNode.addNode(CMS_H,
-                                               CmsTypes.CMS_SECTION);
-                               sectionNode.orderBefore(h(newSectionNode.getIndex()), h(1));
-
-                               int paragraphIndex = paragraphNode.getIndex();
-                               String sectionPath = sectionNode.getPath();
-                               String newSectionPath = newSectionNode.getPath();
-                               while (sectionNode.hasNode(p(paragraphIndex + 1))) {
-                                       Node parag = sectionNode.getNode(p(paragraphIndex + 1));
-                                       sectionNode.getSession().move(
-                                                       sectionPath + '/' + p(paragraphIndex + 1),
-                                                       newSectionPath + '/' + CMS_P);
-                                       SectionPart sp = section.getSectionPart(parag
-                                                       .getIdentifier());
-                                       if (sp instanceof Control)
-                                               ((Control) sp).dispose();
-                               }
-                               // create property
-                               newSectionNode.setProperty(Property.JCR_TITLE, "");
-                               getTextInterpreter().write(
-                                               newSectionNode.getProperty(Property.JCR_TITLE), txt);
-
-                               TextSection newSection = new TextSection(section,
-                                               section.getStyle(), newSectionNode);
-                               newSection.setLayoutData(CmsUtils.fillWidth());
-                               newSection.moveBelow(paragraph);
-
-                               // dispose
-                               paragraphNode.remove();
-                               paragraph.dispose();
-
-                               refresh(newSection);
-                               newSection.getParent().layout();
-                               layout(newSection);
-                               persistChanges(sectionNode);
-                       } else if (getEdited() instanceof SectionTitle) {
-                               SectionTitle sectionTitle = (SectionTitle) getEdited();
-                               Section section = sectionTitle.getSection();
-                               Section parentSection = section.getParentSection();
-                               if (parentSection == null)
-                                       return;// cannot deepen main section
-                               Node sectionN = section.getNode();
-                               Node parentSectionN = parentSection.getNode();
-                               if (sectionN.getIndex() == 1)
-                                       return;// cannot deepen first section
-                               Node previousSectionN = parentSectionN.getNode(h(sectionN
-                                               .getIndex() - 1));
-                               NodeIterator subSections = previousSectionN.getNodes(CMS_H);
-                               int subsectionsCount = (int) subSections.getSize();
-                               previousSectionN.getSession().move(
-                                               sectionN.getPath(),
-                                               previousSectionN.getPath() + "/"
-                                                               + h(subsectionsCount + 1));
-                               section.dispose();
-                               TextSection newSection = new TextSection(section,
-                                               section.getStyle(), sectionN);
-                               refresh(newSection);
-                               persistChanges(previousSectionN);
-                       }
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot deepen " + getEdited(), e);
-               }
-       }
-
-       protected void undeepen() {
-               if (flat)
-                       return;
-               checkEdited();
-               try {
-                       if (getEdited() instanceof Paragraph) {
-                               upload(getEdited());
-                       } else if (getEdited() instanceof SectionTitle) {
-                               SectionTitle sectionTitle = (SectionTitle) getEdited();
-                               Section section = sectionTitle.getSection();
-                               Node sectionNode = section.getNode();
-                               Section parentSection = section.getParentSection();
-                               if (parentSection == null)
-                                       return;// cannot undeepen main section
-
-                               // choose in which section to merge
-                               Section mergedSection;
-                               if (sectionNode.getIndex() == 1)
-                                       mergedSection = section.getParentSection();
-                               else {
-                                       Map<String, Section> parentSubsections = parentSection
-                                                       .getSubSections();
-                                       ArrayList<Section> lst = new ArrayList<Section>(
-                                                       parentSubsections.values());
-                                       mergedSection = lst.get(sectionNode.getIndex() - 1);
-                               }
-                               Node mergedNode = mergedSection.getNode();
-                               boolean mergedHasSubSections = mergedNode.hasNode(CMS_H);
-
-                               // title as paragraph
-                               Node newParagrapheNode = mergedNode.addNode(CMS_P);
-                               newParagrapheNode.addMixin(CmsTypes.CMS_STYLED);
-                               if (mergedHasSubSections)
-                                       mergedNode.orderBefore(p(newParagrapheNode.getIndex()),
-                                                       h(1));
-                               String txt = getTextInterpreter().read(
-                                               sectionNode.getProperty(Property.JCR_TITLE));
-                               getTextInterpreter().write(newParagrapheNode, txt);
-                               // move
-                               NodeIterator paragraphs = sectionNode.getNodes(CMS_P);
-                               while (paragraphs.hasNext()) {
-                                       Node p = paragraphs.nextNode();
-                                       SectionPart sp = section.getSectionPart(p.getIdentifier());
-                                       if (sp instanceof Control)
-                                               ((Control) sp).dispose();
-                                       mergedNode.getSession().move(p.getPath(),
-                                                       mergedNode.getPath() + '/' + CMS_P);
-                                       if (mergedHasSubSections)
-                                               mergedNode.orderBefore(p(p.getIndex()), h(1));
-                               }
-
-                               Iterator<Section> subsections = section.getSubSections()
-                                               .values().iterator();
-                               // NodeIterator sections = sectionNode.getNodes(CMS_H);
-                               while (subsections.hasNext()) {
-                                       Section subsection = subsections.next();
-                                       Node s = subsection.getNode();
-                                       mergedNode.getSession().move(s.getPath(),
-                                                       mergedNode.getPath() + '/' + CMS_H);
-                                       subsection.dispose();
-                               }
-
-                               // remove section
-                               section.getNode().remove();
-                               section.dispose();
-
-                               refresh(mergedSection);
-                               mergedSection.getParent().layout();
-                               layout(mergedSection);
-                               persistChanges(mergedNode);
-                       }
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot undeepen " + getEdited(), e);
-               }
-       }
-
-       // UI CHANGES
-       protected Paragraph paragraphSplitted(Paragraph paragraph, Node newNode)
-                       throws RepositoryException {
-               Section section = paragraph.getSection();
-               updateContent(paragraph);
-               Paragraph newParagraph = newParagraph((TextSection) section, newNode);
-               newParagraph.setLayoutData(CmsUtils.fillWidth());
-               newParagraph.moveBelow(paragraph);
-               layout(paragraph.getControl(), newParagraph.getControl());
-               return newParagraph;
-       }
-
-       protected Paragraph sectionTitleSplitted(SectionTitle sectionTitle,
-                       Node newNode) throws RepositoryException {
-               updateContent(sectionTitle);
-               Paragraph newParagraph = newParagraph(sectionTitle.getSection(),
-                               newNode);
-               // we assume beforeFirst is not null since there was a sectionTitle
-               newParagraph.moveBelow(sectionTitle.getSection().getHeader());
-               layout(sectionTitle.getControl(), newParagraph.getControl());
-               return newParagraph;
-       }
-
-       protected Paragraph paragraphMergedWithPrevious(Paragraph removed,
-                       Node remaining) throws RepositoryException {
-               Section section = removed.getSection();
-               removed.dispose();
-
-               Paragraph paragraph = (Paragraph) section.getSectionPart(remaining
-                               .getIdentifier());
-               updateContent(paragraph);
-               layout(paragraph.getControl());
-               return paragraph;
-       }
-
-       protected void paragraphMergedWithNext(Paragraph remaining,
-                       Paragraph removed) throws RepositoryException {
-               removed.dispose();
-               updateContent(remaining);
-               layout(remaining.getControl());
-       }
-
-       // UTILITIES
-       protected String p(Integer index) {
-               StringBuilder sb = new StringBuilder(6);
-               sb.append(CMS_P).append('[').append(index).append(']');
-               return sb.toString();
-       }
-
-       protected String h(Integer index) {
-               StringBuilder sb = new StringBuilder(5);
-               sb.append(CMS_H).append('[').append(index).append(']');
-               return sb.toString();
-       }
-
-       // GETTERS / SETTERS
-       public Section getMainSection() {
-               return mainSection;
-       }
-
-       public boolean isFlat() {
-               return flat;
-       }
-
-       public TextInterpreter getTextInterpreter() {
-               return textInterpreter;
-       }
-
-       // KEY LISTENER
-       @Override
-       public void keyPressed(KeyEvent ke) {
-               if (log.isTraceEnabled())
-                       log.trace(ke);
-
-               if (getEdited() == null)
-                       return;
-               boolean altPressed = (ke.stateMask & SWT.ALT) != 0;
-               boolean shiftPressed = (ke.stateMask & SWT.SHIFT) != 0;
-               boolean ctrlPressed = (ke.stateMask & SWT.CTRL) != 0;
-
-               try {
-                       // Common
-                       if (ke.keyCode == SWT.ESC) {
-                               cancelEdit();
-                       } else if (ke.character == '\r') {
-                               splitEdit();
-                       } else if (ke.character == 'S') {
-                               if (ctrlPressed)
-                                       saveEdit();
-                       } else if (ke.character == '\t') {
-                               if (!shiftPressed) {
-                                       deepen();
-                               } else if (shiftPressed) {
-                                       undeepen();
-                               }
-                       } else {
-                               if (getEdited() instanceof Paragraph) {
-                                       Paragraph paragraph = (Paragraph) getEdited();
-                                       Section section = paragraph.getSection();
-                                       if (altPressed && ke.keyCode == SWT.ARROW_RIGHT) {
-                                               edit(section.nextSectionPart(paragraph), 0);
-                                       } else if (altPressed && ke.keyCode == SWT.ARROW_LEFT) {
-                                               edit(section.previousSectionPart(paragraph), 0);
-                                       } else if (ke.character == SWT.BS) {
-                                               Text text = (Text) paragraph.getControl();
-                                               int caretPosition = text.getCaretPosition();
-                                               if (caretPosition == 0) {
-                                                       mergeWithPrevious();
-                                               }
-                                       } else if (ke.character == SWT.DEL) {
-                                               Text text = (Text) paragraph.getControl();
-                                               int caretPosition = text.getCaretPosition();
-                                               int charcount = text.getCharCount();
-                                               if (caretPosition == charcount) {
-                                                       mergeWithNext();
-                                               }
-                                       }
-                               }
-                       }
-               } catch (Exception e) {
-                       ke.doit = false;
-                       notifyEditionException(e);
-               }
-       }
-
-       @Override
-       public void keyReleased(KeyEvent e) {
-       }
-
-       // MOUSE LISTENER
-       @Override
-       protected MouseListener createMouseListener() {
-               return new ML();
-       }
-
-       private class ML extends MouseAdapter {
-               private static final long serialVersionUID = 8526890859876770905L;
-
-               @Override
-               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();
-                                       }
-                               }
-                       }
-               }
-
-               @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) {
-                                       EditablePart composite = findDataParent((Control) e
-                                                       .getSource());
-                                       if (styledTools != null)
-                                               styledTools.show(composite, new Point(e.x, e.y));
-                               }
-                       }
-               }
-
-               @Override
-               public void mouseUp(MouseEvent e) {
-               }
-       }
-
-       // FILE UPLOAD LISTENER
-       private class FUL implements FileUploadListener {
-               public void uploadProgress(FileUploadEvent event) {
-                       // TODO Monitor upload progress
-               }
-
-               public void uploadFailed(FileUploadEvent event) {
-                       throw new CmsException("Upload failed " + event,
-                                       event.getException());
-               }
-
-               public void uploadFinished(FileUploadEvent event) {
-                       for (FileDetails file : event.getFileDetails()) {
-                               if (log.isDebugEnabled())
-                                       log.debug("Received: " + file.getFileName());
-                       }
-                       mainSection.getDisplay().syncExec(new Runnable() {
-                               @Override
-                               public void run() {
-                                       saveEdit();
-                               }
-                       });
-                       FileUploadHandler uploadHandler = (FileUploadHandler) event
-                                       .getSource();
-                       uploadHandler.dispose();
-               }
-       }
-}
\ No newline at end of file
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java b/org.argeo.cms.ui/src/org/argeo/cms/text/CustomTextEditor.java
deleted file mode 100644 (file)
index 94be420..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.argeo.cms.text;
-
-import static org.argeo.cms.util.CmsUtils.fillWidth;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.viewers.Section;
-import org.eclipse.swt.widgets.Composite;
-
-/**
- * Manages hardcoded sections as an arbitrary hierarchy under the main section,
- * which contains no text and no title.
- */
-public class CustomTextEditor extends AbstractTextViewer {
-       private static final long serialVersionUID = 5277789504209413500L;
-
-       public CustomTextEditor(Composite parent, int style, Node textNode,
-                       CmsEditable cmsEditable) throws RepositoryException {
-               this(new Section(parent, style, textNode), style, cmsEditable);
-       }
-
-       public CustomTextEditor(Section mainSection, int style,
-                       CmsEditable cmsEditable) throws RepositoryException {
-               super(mainSection, style, cmsEditable);
-               mainSection.setLayoutData(fillWidth());
-       }
-
-       @Override
-       public Section getMainSection() {
-               return super.getMainSection();
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/IdentityTextInterpreter.java b/org.argeo.cms.ui/src/org/argeo/cms/text/IdentityTextInterpreter.java
deleted file mode 100644 (file)
index 79f6ede..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Item;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.CmsTypes;
-
-/** Based on HTML with a few Wiki-like shortcuts. */
-public class IdentityTextInterpreter implements TextInterpreter, CmsNames {
-
-       @Override
-       public void write(Item item, String content) {
-               try {
-                       if (item instanceof Node) {
-                               Node node = (Node) item;
-                               if (node.isNodeType(CmsTypes.CMS_STYLED)) {
-                                       String raw = convertToStorage(node, content);
-                                       validateBeforeStoring(raw);
-                                       node.setProperty(CMS_CONTENT, raw);
-                               } else {
-                                       throw new CmsException("Don't know how to interpret "
-                                                       + node);
-                               }
-                       } else {// property
-                               Property property = (Property) item;
-                               property.setValue(content);
-                       }
-                       // item.getSession().save();
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot set content on " + item, e);
-               }
-       }
-
-       @Override
-       public String read(Item item) {
-               try {
-                       String raw = raw(item);
-                       return convertFromStorage(item, raw);
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get " + item + " for edit", e);
-               }
-       }
-
-       @Override
-       public String raw(Item item) {
-               try {
-                       item.getSession().refresh(true);
-                       if (item instanceof Node) {
-                               Node node = (Node) item;
-                               if (node.isNodeType(CmsTypes.CMS_STYLED)) {
-                                       // WORKAROUND FOR BROKEN PARARAPHS
-                                       if (!node.hasProperty(CMS_CONTENT)) {
-                                               node.setProperty(CMS_CONTENT, "");
-                                               node.getSession().save();
-                                       }
-
-                                       return node.getProperty(CMS_CONTENT).getString();
-                               } else {
-                                       throw new CmsException("Don't know how to interpret "
-                                                       + node);
-                               }
-                       } else {// property
-                               Property property = (Property) item;
-                               return property.getString();
-                       }
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot get " + item + " content", e);
-               }
-       }
-
-       // EXTENSIBILITY
-       /**
-        * To be overridden, in order to make sure that only valid strings are being
-        * stored.
-        */
-       protected void validateBeforeStoring(String raw) {
-       }
-
-       /** To be overridden, in order to support additional formatting. */
-       protected String convertToStorage(Item item, String content)
-                       throws RepositoryException {
-               return content;
-
-       }
-
-       /** To be overridden, in order to support additional formatting. */
-       protected String convertFromStorage(Item item, String content)
-                       throws RepositoryException {
-               return content;
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java b/org.argeo.cms.ui/src/org/argeo/cms/text/Img.java
deleted file mode 100644 (file)
index 12f65f3..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.CmsException;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.ui.internal.JcrFileUploadReceiver;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.NodePart;
-import org.argeo.cms.viewers.Section;
-import org.argeo.cms.viewers.SectionPart;
-import org.argeo.cms.widgets.EditableImage;
-import org.eclipse.rap.fileupload.FileUploadHandler;
-import org.eclipse.rap.fileupload.FileUploadListener;
-import org.eclipse.rap.fileupload.FileUploadReceiver;
-import org.eclipse.rap.rwt.service.ServerPushSession;
-import org.eclipse.rap.rwt.widgets.FileUpload;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** An image within the Argeo Text framework */
-public class Img extends EditableImage implements SectionPart, NodePart {
-       private static final long serialVersionUID = 6233572783968188476L;
-
-       private final Section section;
-
-       private final CmsImageManager imageManager;
-       private FileUploadHandler currentUploadHandler = null;
-       private FileUploadListener fileUploadListener;
-
-       public Img(Composite parent, int swtStyle, Node imgNode,
-                       Point preferredImageSize) throws RepositoryException {
-               this(Section.findSection(parent), parent, swtStyle, imgNode,
-                               preferredImageSize);
-               setStyle(TextStyles.TEXT_IMAGE);
-       }
-
-       public Img(Composite parent, int swtStyle, Node imgNode)
-                       throws RepositoryException {
-               this(Section.findSection(parent), parent, swtStyle, imgNode, null);
-               setStyle(TextStyles.TEXT_IMAGE);
-       }
-
-       Img(Section section, Composite parent, int swtStyle, Node imgNode,
-                       Point preferredImageSize) throws RepositoryException {
-               super(parent, swtStyle, imgNode, false, preferredImageSize);
-               this.section = section;
-               imageManager = CmsUtils.getCmsView().getImageManager();
-               CmsUtils.style(this, TextStyles.TEXT_IMG);
-       }
-
-       @Override
-       protected Control createControl(Composite box, String style) {
-               if (isEditing()) {
-                       try {
-                               return createImageChooser(box, style);
-                       } catch (RepositoryException e) {
-                               throw new CmsException("Cannot create image chooser", e);
-                       }
-               } else {
-                       return createLabel(box, style);
-               }
-       }
-
-       @Override
-       public synchronized void stopEditing() {
-               super.stopEditing();
-               fileUploadListener = null;
-       }
-
-       @Override
-       protected synchronized Boolean load(Control lbl) {
-               try {
-                       Node imgNode = getNode();
-                       boolean loaded = imageManager.load(imgNode, lbl,
-                                       getPreferredImageSize());
-                       // getParent().layout();
-                       return loaded;
-               } catch (RepositoryException e) {
-                       throw new CmsException("Cannot load " + getNodeId()
-                                       + " from image manager", e);
-               }
-       }
-
-       protected Control createImageChooser(Composite box, String style)
-                       throws RepositoryException {
-               // FileDialog fileDialog = new FileDialog(getShell());
-               // fileDialog.open();
-               // String fileName = fileDialog.getFileName();
-               CmsImageManager imageManager = CmsUtils.getCmsView().getImageManager();
-               Node node = getNode();
-               JcrFileUploadReceiver receiver = new JcrFileUploadReceiver(
-                               node.getParent(), node.getName() + '[' + node.getIndex() + ']',
-                               imageManager);
-               if (currentUploadHandler != null)
-                       currentUploadHandler.dispose();
-               currentUploadHandler = prepareUpload(receiver);
-               final ServerPushSession pushSession = new ServerPushSession();
-               final FileUpload fileUpload = new FileUpload(box, SWT.NONE);
-               CmsUtils.style(fileUpload, style);
-               fileUpload.addSelectionListener(new SelectionAdapter() {
-                       private static final long serialVersionUID = -9158471843941668562L;
-
-                       @Override
-                       public void widgetSelected(SelectionEvent e) {
-                               pushSession.start();
-                               fileUpload.submit(currentUploadHandler.getUploadUrl());
-                       }
-               });
-               return fileUpload;
-       }
-
-       protected FileUploadHandler prepareUpload(FileUploadReceiver receiver) {
-               final FileUploadHandler uploadHandler = new FileUploadHandler(receiver);
-               if (fileUploadListener != null)
-                       uploadHandler.addUploadListener(fileUploadListener);
-               return uploadHandler;
-       }
-
-       @Override
-       public Section getSection() {
-               return section;
-       }
-
-       public void setFileUploadListener(FileUploadListener fileUploadListener) {
-               this.fileUploadListener = fileUploadListener;
-               if (currentUploadHandler != null)
-                       currentUploadHandler.addUploadListener(fileUploadListener);
-       }
-
-       @Override
-       public Node getItem() throws RepositoryException {
-               return getNode();
-       }
-
-       @Override
-       public String getPartId() {
-               return getNodeId();
-       }
-
-       @Override
-       public String toString() {
-               return "Img #" + getPartId();
-       }
-
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/MarkupValidatorCopy.java b/org.argeo.cms.ui/src/org/argeo/cms/text/MarkupValidatorCopy.java
deleted file mode 100644 (file)
index 26b77cb..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-package org.argeo.cms.text;
-
-import java.io.StringReader;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.argeo.cms.forms.FormPageViewer;
-import org.eclipse.rap.rwt.SingletonUtil;
-import org.eclipse.swt.widgets.Widget;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Copy of RAP v2.3 since it is in an internal package.
- * 
- * FIXME made public to enable validation from the {@link FormPageViewer}
- */
-public class MarkupValidatorCopy {
-
-       // Used by Eclipse Scout project
-       public static final String MARKUP_VALIDATION_DISABLED = "org.eclipse.rap.rwt.markupValidationDisabled";
-
-       private static final String DTD = createDTD();
-       private static final Map<String, String[]> SUPPORTED_ELEMENTS = createSupportedElementsMap();
-       private final SAXParser saxParser;
-
-       public static MarkupValidatorCopy getInstance() {
-               return SingletonUtil.getSessionInstance(MarkupValidatorCopy.class);
-       }
-
-       public MarkupValidatorCopy() {
-               saxParser = createSAXParser();
-       }
-
-       public void validate(String text) {
-               StringBuilder markup = new StringBuilder();
-               markup.append(DTD);
-               markup.append("<html>");
-               markup.append(text);
-               markup.append("</html>");
-               InputSource inputSource = new InputSource(new StringReader(
-                               markup.toString()));
-               try {
-                       saxParser.parse(inputSource, new MarkupHandler());
-               } catch (RuntimeException exception) {
-                       throw exception;
-               } catch (Exception exception) {
-                       throw new IllegalArgumentException("Failed to parse markup text",
-                                       exception);
-               }
-       }
-
-       public static boolean isValidationDisabledFor(Widget widget) {
-               return Boolean.TRUE.equals(widget.getData(MARKUP_VALIDATION_DISABLED));
-       }
-
-       private static SAXParser createSAXParser() {
-               SAXParser result = null;
-               SAXParserFactory parserFactory = SAXParserFactory.newInstance();
-               try {
-                       result = parserFactory.newSAXParser();
-               } catch (Exception exception) {
-                       throw new RuntimeException("Failed to create SAX parser", exception);
-               }
-               return result;
-       }
-
-       private static String createDTD() {
-               StringBuilder result = new StringBuilder();
-               result.append("<!DOCTYPE html [");
-               result.append("<!ENTITY quot \"&#34;\">");
-               result.append("<!ENTITY amp \"&#38;\">");
-               result.append("<!ENTITY apos \"&#39;\">");
-               result.append("<!ENTITY lt \"&#60;\">");
-               result.append("<!ENTITY gt \"&#62;\">");
-               result.append("<!ENTITY nbsp \"&#160;\">");
-               result.append("<!ENTITY ensp \"&#8194;\">");
-               result.append("<!ENTITY emsp \"&#8195;\">");
-               result.append("<!ENTITY ndash \"&#8211;\">");
-               result.append("<!ENTITY mdash \"&#8212;\">");
-               result.append("]>");
-               return result.toString();
-       }
-
-       private static Map<String, String[]> createSupportedElementsMap() {
-               Map<String, String[]> result = new HashMap<String, String[]>();
-               result.put("html", new String[0]);
-               result.put("br", new String[0]);
-               result.put("b", new String[] { "style" });
-               result.put("strong", new String[] { "style" });
-               result.put("i", new String[] { "style" });
-               result.put("em", new String[] { "style" });
-               result.put("sub", new String[] { "style" });
-               result.put("sup", new String[] { "style" });
-               result.put("big", new String[] { "style" });
-               result.put("small", new String[] { "style" });
-               result.put("del", new String[] { "style" });
-               result.put("ins", new String[] { "style" });
-               result.put("code", new String[] { "style" });
-               result.put("samp", new String[] { "style" });
-               result.put("kbd", new String[] { "style" });
-               result.put("var", new String[] { "style" });
-               result.put("cite", new String[] { "style" });
-               result.put("dfn", new String[] { "style" });
-               result.put("q", new String[] { "style" });
-               result.put("abbr", new String[] { "style", "title" });
-               result.put("span", new String[] { "style" });
-               result.put("img", new String[] { "style", "src", "width", "height",
-                               "title", "alt" });
-               result.put("a", new String[] { "style", "href", "target", "title" });
-               return result;
-       }
-
-       private static class MarkupHandler extends DefaultHandler {
-
-               @Override
-               public void startElement(String uri, String localName, String name,
-                               Attributes attributes) {
-                       checkSupportedElements(name, attributes);
-                       checkSupportedAttributes(name, attributes);
-                       checkMandatoryAttributes(name, attributes);
-               }
-
-               private static void checkSupportedElements(String elementName,
-                               Attributes attributes) {
-                       if (!SUPPORTED_ELEMENTS.containsKey(elementName)) {
-                               throw new IllegalArgumentException(
-                                               "Unsupported element in markup text: " + elementName);
-                       }
-               }
-
-               private static void checkSupportedAttributes(String elementName,
-                               Attributes attributes) {
-                       if (attributes.getLength() > 0) {
-                               List<String> supportedAttributes = Arrays
-                                               .asList(SUPPORTED_ELEMENTS.get(elementName));
-                               int index = 0;
-                               String attributeName = attributes.getQName(index);
-                               while (attributeName != null) {
-                                       if (!supportedAttributes.contains(attributeName)) {
-                                               String message = "Unsupported attribute \"{0}\" for element \"{1}\" in markup text";
-                                               message = MessageFormat.format(message, new Object[] {
-                                                               attributeName, elementName });
-                                               throw new IllegalArgumentException(message);
-                                       }
-                                       index++;
-                                       attributeName = attributes.getQName(index);
-                               }
-                       }
-               }
-
-               private static void checkMandatoryAttributes(String elementName,
-                               Attributes attributes) {
-                       checkIntAttribute(elementName, attributes, "img", "width");
-                       checkIntAttribute(elementName, attributes, "img", "height");
-               }
-
-               private static void checkIntAttribute(String elementName,
-                               Attributes attributes, String checkedElementName,
-                               String checkedAttributeName) {
-                       if (checkedElementName.equals(elementName)) {
-                               String attribute = attributes.getValue(checkedAttributeName);
-                               try {
-                                       Integer.parseInt(attribute);
-                               } catch (NumberFormatException exception) {
-                                       String message = "Mandatory attribute \"{0}\" for element \"{1}\" is missing or not a valid integer";
-                                       Object[] arguments = new Object[] { checkedAttributeName,
-                                                       checkedElementName };
-                                       message = MessageFormat.format(message, arguments);
-                                       throw new IllegalArgumentException(message);
-                               }
-                       }
-               }
-
-       }
-
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/Paragraph.java b/org.argeo.cms.ui/src/org/argeo/cms/text/Paragraph.java
deleted file mode 100644 (file)
index a7a7964..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.Section;
-import org.argeo.cms.viewers.SectionPart;
-import org.argeo.cms.widgets.EditableText;
-
-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 {
-               super(section, style, node);
-               this.section = section;
-               CmsUtils.style(this, TextStyles.TEXT_PARAGRAPH);
-       }
-
-       public Section getSection() {
-               return section;
-       }
-
-       @Override
-       public String getPartId() {
-               return getNodeId();
-       }
-
-       @Override
-       public Node getItem() throws RepositoryException {
-               return getNode();
-       }
-
-       @Override
-       public String toString() {
-               return "Paragraph #" + getPartId();
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/SectionTitle.java b/org.argeo.cms.ui/src/org/argeo/cms/text/SectionTitle.java
deleted file mode 100644 (file)
index 15be32b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.viewers.EditablePart;
-import org.argeo.cms.viewers.PropertyPart;
-import org.argeo.cms.widgets.EditableText;
-import org.eclipse.swt.widgets.Composite;
-
-/** The title of a section. */
-public class SectionTitle extends EditableText implements EditablePart,
-               PropertyPart {
-       private static final long serialVersionUID = -1787983154946583171L;
-
-       private final TextSection section;
-
-       public SectionTitle(Composite parent, int swtStyle, Property title)
-                       throws RepositoryException {
-               super(parent, swtStyle, title);
-               section = (TextSection) TextSection.findSection(this);
-       }
-
-       public TextSection getSection() {
-               return section;
-       }
-
-       // @Override
-       // public Property getProperty() throws RepositoryException {
-       // return getSection().getNode().getProperty(Property.JCR_TITLE);
-       // }
-
-       @Override
-       public Property getItem() throws RepositoryException {
-               return getProperty();
-       }
-
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java b/org.argeo.cms.ui/src/org/argeo/cms/text/StandardTextEditor.java
deleted file mode 100644 (file)
index 8a4fd11..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.argeo.cms.text;
-
-import static javax.jcr.Property.JCR_TITLE;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.Section;
-import org.eclipse.swt.widgets.Composite;
-
-/** Text editor where sections and subsections can be managed by the user. */
-public class StandardTextEditor extends AbstractTextViewer {
-       private static final long serialVersionUID = 6049661610883342325L;
-
-       public StandardTextEditor(Composite parent, int style, Node textNode,
-                       CmsEditable cmsEditable) throws RepositoryException {
-               super(new TextSection(parent, style, textNode), style, cmsEditable);
-               refresh();
-               getMainSection().setLayoutData(CmsUtils.fillWidth());
-       }
-
-       @Override
-       protected void initModel(Node textNode) throws RepositoryException {
-               if (isFlat())
-                       textNode.addNode(CMS_P).addMixin(CmsTypes.CMS_STYLED);
-               else
-                       textNode.setProperty(JCR_TITLE, textNode.getName());
-       }
-
-       @Override
-       protected Boolean isModelInitialized(Node textNode)
-                       throws RepositoryException {
-               return textNode.hasProperty(Property.JCR_TITLE)
-                               || textNode.hasNode(CMS_P)
-                               || (!isFlat() && textNode.hasNode(CMS_H));
-       }
-
-       @Override
-       public Section getMainSection() {
-               // TODO Auto-generated method stub
-               return super.getMainSection();
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextContextMenu.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextContextMenu.java
deleted file mode 100644 (file)
index eb85bde..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package org.argeo.cms.text;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.viewers.EditablePart;
-import org.argeo.cms.viewers.SectionPart;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.ShellEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/** Dialog to edit a text part. */
-class TextContextMenu extends Shell implements CmsNames, TextStyles {
-       private final static String[] DEFAULT_TEXT_STYLES = {
-                       TextStyles.TEXT_DEFAULT, TextStyles.TEXT_PRE, TextStyles.TEXT_QUOTE };
-
-       private final AbstractTextViewer textViewer;
-
-       private static final long serialVersionUID = -3826246895162050331L;
-       private List<StyleButton> styleButtons = new ArrayList<TextContextMenu.StyleButton>();
-
-       private Label deleteButton, publishButton, editButton;
-
-       private EditablePart currentTextPart;
-
-       public TextContextMenu(AbstractTextViewer textViewer, Display display) {
-               super(display, SWT.NO_TRIM | SWT.BORDER | SWT.ON_TOP);
-               this.textViewer = textViewer;
-               setLayout(new GridLayout());
-               setData(RWT.CUSTOM_VARIANT, TEXT_STYLED_TOOLS_DIALOG);
-
-               StyledToolMouseListener stml = new StyledToolMouseListener();
-               if (textViewer.getCmsEditable().isEditing()) {
-                       for (String style : DEFAULT_TEXT_STYLES) {
-                               StyleButton styleButton = new StyleButton(this, SWT.WRAP);
-                               styleButton.setData(RWT.CUSTOM_VARIANT, style);
-                               styleButton.setData(RWT.MARKUP_ENABLED, true);
-                               styleButton.addMouseListener(stml);
-                               styleButtons.add(styleButton);
-                       }
-
-                       // Delete
-                       deleteButton = new Label(this, SWT.NONE);
-                       deleteButton.setText("Delete");
-                       deleteButton.addMouseListener(stml);
-
-                       // Publish
-                       publishButton = new Label(this, SWT.NONE);
-                       publishButton.setText("Publish");
-                       publishButton.addMouseListener(stml);
-               } else if (textViewer.getCmsEditable().canEdit()) {
-                       // Edit
-                       editButton = new Label(this, SWT.NONE);
-                       editButton.setText("Edit");
-                       editButton.addMouseListener(stml);
-               }
-               addShellListener(new ToolsShellListener());
-       }
-
-       public void show(EditablePart source, Point location) {
-               if (isVisible())
-                       setVisible(false);
-
-               this.currentTextPart = source;
-
-               if (currentTextPart instanceof Paragraph) {
-                       final int size = 32;
-                       String text = textViewer
-                                       .getRawParagraphText((Paragraph) currentTextPart);
-                       String textToShow = text.length() > size ? text.substring(0,
-                                       size - 3) + "..." : text;
-                       for (StyleButton styleButton : styleButtons) {
-                               styleButton.setText(textToShow);
-                       }
-               }
-               pack();
-               layout();
-               if (source instanceof Control)
-                       setLocation(((Control) source).toDisplay(location.x, location.y));
-               open();
-       }
-
-       class StyleButton extends Label {
-               private static final long serialVersionUID = 7731102609123946115L;
-
-               public StyleButton(Composite parent, int swtStyle) {
-                       super(parent, swtStyle);
-               }
-
-       }
-
-       class StyledToolMouseListener extends MouseAdapter {
-               private static final long serialVersionUID = 8516297091549329043L;
-
-               @Override
-               public void mouseDown(MouseEvent e) {
-                       Object eventSource = e.getSource();
-                       if (eventSource instanceof StyleButton) {
-                               StyleButton sb = (StyleButton) e.getSource();
-                               String style = sb.getData(RWT.CUSTOM_VARIANT).toString();
-                               textViewer
-                                               .setParagraphStyle((Paragraph) currentTextPart, style);
-                       } else if (eventSource == deleteButton) {
-                               textViewer.deletePart((SectionPart) currentTextPart);
-                       } else if (eventSource == editButton) {
-                               textViewer.getCmsEditable().startEditing();
-                       } else if (eventSource == publishButton) {
-                               textViewer.getCmsEditable().stopEditing();
-                       }
-                       setVisible(false);
-               }
-       }
-
-       class ToolsShellListener extends org.eclipse.swt.events.ShellAdapter {
-               private static final long serialVersionUID = 8432350564023247241L;
-
-               @Override
-               public void shellDeactivated(ShellEvent e) {
-                       setVisible(false);
-               }
-
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextEditorHeader.java
deleted file mode 100644 (file)
index 5ae0536..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.argeo.cms.text;
-
-import java.util.Observable;
-import java.util.Observer;
-
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.util.CmsUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-
-/** Adds editing capabilities to a page editing text */
-public class TextEditorHeader implements SelectionListener, Observer {
-       private static final long serialVersionUID = 4186756396045701253L;
-
-       private final CmsEditable cmsEditable;
-       private Button publish;
-
-       private Composite parent;
-       private Composite display;
-       private Object layoutData;
-
-       public TextEditorHeader(CmsEditable cmsEditable, Composite parent, int style) {
-               this.cmsEditable = cmsEditable;
-               this.parent = parent;
-               if (this.cmsEditable instanceof Observable)
-                       ((Observable) this.cmsEditable).addObserver(this);
-               refresh();
-       }
-
-       protected void refresh() {
-               if (display != null && !display.isDisposed())
-                       display.dispose();
-               display = null;
-               publish = null;
-               if (cmsEditable.isEditing()) {
-                       display = new Composite(parent, SWT.NONE);
-                       // display.setBackgroundMode(SWT.INHERIT_NONE);
-                       display.setLayoutData(layoutData);
-                       display.setLayout(CmsUtils.noSpaceGridLayout());
-                       CmsUtils.style(display, TextStyles.TEXT_EDITOR_HEADER);
-                       publish = new Button(display, SWT.FLAT | SWT.PUSH);
-                       publish.setText(getPublishButtonLabel());
-                       CmsUtils.style(publish, TextStyles.TEXT_EDITOR_HEADER);
-                       publish.addSelectionListener(this);
-                       display.moveAbove(null);
-               }
-               parent.layout();
-       }
-
-       private String getPublishButtonLabel() {
-               if (cmsEditable.isEditing())
-                       return "Publish";
-               else
-                       return "Edit";
-       }
-
-       @Override
-       public void widgetSelected(SelectionEvent e) {
-               if (e.getSource() == publish) {
-                       if (cmsEditable.isEditing()) {
-                               cmsEditable.stopEditing();
-                       } else {
-                               cmsEditable.startEditing();
-                       }
-                       // publish.setText(getPublishButtonLabel());
-               }
-       }
-
-       @Override
-       public void widgetDefaultSelected(SelectionEvent e) {
-       }
-
-       @Override
-       public void update(Observable o, Object arg) {
-               if (o == cmsEditable) {
-                       // publish.setText(getPublishButtonLabel());
-                       refresh();
-               }
-       }
-
-       public void setLayoutData(Object layoutData) {
-               this.layoutData = layoutData;
-               if (display != null && !display.isDisposed())
-                       display.setLayoutData(layoutData);
-       }
-
-}
\ No newline at end of file
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreter.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreter.java
deleted file mode 100644 (file)
index f39a2b3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Item;
-
-/** Convert from/to data layer to/from presentation layer. */
-public interface TextInterpreter {
-       public String raw(Item item);
-
-       public String read(Item item);
-
-       public void write(Item item, String content);
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreterImpl.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextInterpreterImpl.java
deleted file mode 100644 (file)
index f9ee195..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-
-/**
- * Text interpreter that sanitise and validates before saving, and support CMS
- * specific formatting and integration.
- */
-class TextInterpreterImpl extends IdentityTextInterpreter {
-       private MarkupValidatorCopy markupValidator = MarkupValidatorCopy
-                       .getInstance();
-
-       @Override
-       protected void validateBeforeStoring(String raw) {
-               markupValidator.validate(raw);
-       }
-
-       @Override
-       protected String convertToStorage(Item item, String content)
-                       throws RepositoryException {
-               return super.convertToStorage(item, content);
-       }
-
-       @Override
-       protected String convertFromStorage(Item item, String content)
-                       throws RepositoryException {
-               return super.convertFromStorage(item, content);
-       }
-
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextSection.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextSection.java
deleted file mode 100644 (file)
index ac93e4b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.Section;
-import org.eclipse.swt.widgets.Composite;
-
-public class TextSection extends Section implements CmsNames {
-       private static final long serialVersionUID = -8625209546243220689L;
-       private String defaultTextStyle = TextStyles.TEXT_DEFAULT;
-       private String titleStyle;
-
-       public TextSection(Composite parent, int style, Node node)
-                       throws RepositoryException {
-               this(parent, findSection(parent), style, node);
-       }
-
-       public TextSection(TextSection section, int style, Node node)
-                       throws RepositoryException {
-               this(section, section.getParentSection(), style, node);
-       }
-
-       private TextSection(Composite parent, Section parentSection, int style,
-                       Node node) throws RepositoryException {
-               super(parent, parentSection, style, node);
-               CmsUtils.style(this, TextStyles.TEXT_SECTION);
-       }
-
-       public String getDefaultTextStyle() {
-               return defaultTextStyle;
-       }
-
-       public String getTitleStyle() {
-               if (titleStyle != null)
-                       return titleStyle;
-               // TODO make base H styles configurable
-               Integer relativeDepth = getRelativeDepth();
-               return relativeDepth == 0 ? TextStyles.TEXT_TITLE : TextStyles.TEXT_H
-                               + relativeDepth;
-       }
-
-       public void setDefaultTextStyle(String defaultTextStyle) {
-               this.defaultTextStyle = defaultTextStyle;
-       }
-
-       public void setTitleStyle(String titleStyle) {
-               this.titleStyle = titleStyle;
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/TextStyles.java b/org.argeo.cms.ui/src/org/argeo/cms/text/TextStyles.java
deleted file mode 100644 (file)
index 44c3ad0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.argeo.cms.text;
-
-/** Styles references in the CSS. */
-public interface TextStyles {
-       /** The whole page area */
-       public final static String TEXT_AREA = "text_area";
-       /** Area providing controls for editing text */
-       public final static String TEXT_EDITOR_HEADER = "text_editor_header";
-       /** The styled composite for editing the text */
-       public final static String TEXT_STYLED_COMPOSITE = "text_styled_composite";
-       /** A section */
-       public final static String TEXT_SECTION = "text_section";
-       /** A paragraph */
-       public final static String TEXT_PARAGRAPH = "text_paragraph";
-       /** An image */
-       public final static String TEXT_IMG = "text_img";
-       /** The dialog to edit styled paragraph */
-       public final static String TEXT_STYLED_TOOLS_DIALOG = "text_styled_tools_dialog";
-
-       /*
-        * DEFAULT TEXT STYLES
-        */
-       /** Default style for text body */
-       public final static String TEXT_DEFAULT = "text_default";
-       /** Fixed-width, typically code */
-       public final static String TEXT_PRE = "text_pre";
-       /** Quote */
-       public final static String TEXT_QUOTE = "text_quote";
-       /** Title */
-       public final static String TEXT_TITLE = "text_title";
-       /** Header (to be dynamically completed with the depth, e.g. text_h1) */
-       public final static String TEXT_H = "text_h";
-
-       /** Default style for images */
-       public final static String TEXT_IMAGE = "text_image";
-
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java b/org.argeo.cms.ui/src/org/argeo/cms/text/WikiPage.java
deleted file mode 100644 (file)
index a01cc35..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.argeo.cms.text;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeType;
-
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.ui.CmsEditable;
-import org.argeo.cms.ui.CmsUiProvider;
-import org.argeo.cms.util.CmsLink;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.cms.viewers.JcrVersionCmsEditable;
-import org.argeo.cms.widgets.ScrolledPage;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-
-/** Display the text of the context, and provide an editor if the user can edit. */
-public class WikiPage implements CmsUiProvider, CmsNames {
-       @Override
-       public Control createUi(Composite parent, Node context)
-                       throws RepositoryException {
-               CmsEditable cmsEditable = new JcrVersionCmsEditable(context);
-               if (cmsEditable.canEdit())
-                       new TextEditorHeader(cmsEditable, parent, SWT.NONE)
-                                       .setLayoutData(CmsUtils.fillWidth());
-
-               ScrolledPage page = new ScrolledPage(parent, SWT.NONE);
-               page.setLayout(CmsUtils.noSpaceGridLayout());
-               GridData textGd = CmsUtils.fillAll();
-               page.setLayoutData(textGd);
-
-               if (context.isNodeType(CmsTypes.CMS_TEXT)) {
-                       new StandardTextEditor(page, SWT.NONE, context, cmsEditable);
-               } else if (context.isNodeType(NodeType.NT_FOLDER)
-                               || context.getPath().equals("/")) {
-                       parent.setBackgroundMode(SWT.INHERIT_NONE);
-                       if (context.getSession().hasPermission(context.getPath(),
-                                       Session.ACTION_ADD_NODE)) {
-                               Node indexNode = JcrUtils.getOrAdd(context, CMS_INDEX,
-                                               CmsTypes.CMS_TEXT);
-                               new StandardTextEditor(page, SWT.NONE, indexNode, cmsEditable);
-                               textGd.heightHint = 400;
-
-                               for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
-                                       Node textNode = ni.nextNode();
-                                       if (textNode.isNodeType(NodeType.NT_FOLDER))
-                                               new CmsLink(textNode.getName() + "/",
-                                                               textNode.getPath()).createUi(parent, textNode);
-                               }
-                               for (NodeIterator ni = context.getNodes(); ni.hasNext();) {
-                                       Node textNode = ni.nextNode();
-                                       if (textNode.isNodeType(CmsTypes.CMS_TEXT)
-                                                       && !textNode.getName().equals(CMS_INDEX))
-                                               new CmsLink(textNode.getName(), textNode.getPath())
-                                                               .createUi(parent, textNode);
-                               }
-                       }
-               }
-               return page;
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/img/Dummy.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/img/Dummy.java
new file mode 100644 (file)
index 0000000..4c48f71
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.cms.ui.img;
+
+public class Dummy {
+
+}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java
deleted file mode 100644 (file)
index 48c5812..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-package org.argeo.cms.ui.internal;
-
-import static javax.jcr.Node.JCR_CONTENT;
-import static javax.jcr.Property.JCR_DATA;
-import static javax.jcr.nodetype.NodeType.NT_FILE;
-import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
-import static org.argeo.cms.CmsNames.CMS_IMAGE_HEIGHT;
-import static org.argeo.cms.CmsNames.CMS_IMAGE_WIDTH;
-import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import javax.jcr.Binary;
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.cms.CmsException;
-import org.argeo.cms.CmsNames;
-import org.argeo.cms.CmsTypes;
-import org.argeo.cms.ui.CmsImageManager;
-import org.argeo.cms.util.CmsUtils;
-import org.argeo.jcr.JcrUtils;
-import org.eclipse.rap.rwt.RWT;
-import org.eclipse.rap.rwt.service.ResourceManager;
-import org.eclipse.rap.rwt.widgets.FileUpload;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
-
-/** Manages only public images so far. */
-public class ImageManagerImpl implements CmsImageManager {
-       private final static Log log = LogFactory.getLog(ImageManagerImpl.class);
-//     private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
-
-       public Boolean load(Node node, Control control, Point preferredSize) throws RepositoryException {
-               Point imageSize = getImageSize(node);
-               Point size;
-               String imgTag = null;
-               if (preferredSize == null || imageSize.x == 0 || imageSize.y == 0
-                               || (preferredSize.x == 0 && preferredSize.y == 0)) {
-                       if (imageSize.x != 0 && imageSize.y != 0) {
-                               // actual image size if completely known
-                               size = imageSize;
-                       } else {
-                               // no image if not completely known
-                               size = resizeTo(NO_IMAGE_SIZE, preferredSize != null ? preferredSize : imageSize);
-                               imgTag = CmsUtils.noImg(size);
-                       }
-
-               } else if (preferredSize.x != 0 && preferredSize.y != 0) {
-                       // given size if completely provided
-                       size = preferredSize;
-               } else {
-                       // at this stage :
-                       // image is completely known
-                       assert imageSize.x != 0 && imageSize.y != 0;
-                       // one and only one of the dimension as been specified
-                       assert preferredSize.x == 0 || preferredSize.y == 0;
-                       size = resizeTo(imageSize, preferredSize);
-               }
-
-               boolean loaded = false;
-               if (control == null)
-                       return loaded;
-
-               if (control instanceof Label) {
-                       if (imgTag == null) {
-                               // IMAGE RETRIEVED HERE
-                               imgTag = getImageTag(node, size);
-                               //
-                               if (imgTag == null)
-                                       imgTag = CmsUtils.noImg(size);
-                               else
-                                       loaded = true;
-                       }
-
-                       Label lbl = (Label) control;
-                       lbl.setText(imgTag);
-                       // lbl.setSize(size);
-               } else if (control instanceof FileUpload) {
-                       FileUpload lbl = (FileUpload) control;
-                       lbl.setImage(CmsUtils.noImage(size));
-                       lbl.setSize(size);
-                       return loaded;
-               } else
-                       loaded = false;
-
-               return loaded;
-       }
-
-       private Point resizeTo(Point orig, Point constraints) {
-               if (constraints.x != 0 && constraints.y != 0) {
-                       return constraints;
-               } else if (constraints.x == 0 && constraints.y == 0) {
-                       return orig;
-               } else if (constraints.y == 0) {// force width
-                       return new Point(constraints.x, scale(orig.y, orig.x, constraints.x));
-               } else if (constraints.x == 0) {// force height
-                       return new Point(scale(orig.x, orig.y, constraints.y), constraints.y);
-               }
-               throw new CmsException("Cannot resize " + orig + " to " + constraints);
-       }
-
-       private int scale(int origDimension, int otherDimension, int otherConstraint) {
-               return Math.round(origDimension * divide(otherConstraint, otherDimension));
-       }
-
-       private float divide(int a, int b) {
-               return ((float) a) / ((float) b);
-       }
-
-       public Point getImageSize(Node node) throws RepositoryException {
-               return new Point(node.hasProperty(CMS_IMAGE_WIDTH) ? (int) node.getProperty(CMS_IMAGE_WIDTH).getLong() : 0,
-                               node.hasProperty(CMS_IMAGE_HEIGHT) ? (int) node.getProperty(CMS_IMAGE_HEIGHT).getLong() : 0);
-       }
-
-       /** @return null if not available */
-       @Override
-       public String getImageTag(Node node) throws RepositoryException {
-               return getImageTag(node, getImageSize(node));
-       }
-
-       private String getImageTag(Node node, Point size) throws RepositoryException {
-               StringBuilder buf = getImageTagBuilder(node, size);
-               if (buf == null)
-                       return null;
-               return buf.append("/>").toString();
-       }
-
-       /** @return null if not available */
-       @Override
-       public StringBuilder getImageTagBuilder(Node node, Point size) throws RepositoryException {
-               return getImageTagBuilder(node, Integer.toString(size.x), Integer.toString(size.y));
-       }
-
-       /** @return null if not available */
-       private StringBuilder getImageTagBuilder(Node node, String width, String height) throws RepositoryException {
-               String url = getImageUrl(node);
-               if (url == null)
-                       return null;
-               return CmsUtils.imgBuilder(url, width, height);
-       }
-
-       /** @return null if not available */
-       @Override
-       public String getImageUrl(Node node) throws RepositoryException {
-               return CmsUtils.getDataPath(node);
-               // String name = getResourceName(node);
-               // ResourceManager resourceManager = RWT.getResourceManager();
-               // if (!resourceManager.isRegistered(name)) {
-               // InputStream inputStream = null;
-               // Binary binary = getImageBinary(node);
-               // if (binary == null)
-               // return null;
-               // try {
-               // inputStream = binary.getStream();
-               // resourceManager.register(name, inputStream);
-               // } finally {
-               // IOUtils.closeQuietly(inputStream);
-               // JcrUtils.closeQuietly(binary);
-               // }
-               // if (log.isTraceEnabled())
-               // log.trace("Registered image " + name);
-               // }
-               // return resourceManager.getLocation(name);
-       }
-
-       protected String getResourceName(Node node) throws RepositoryException {
-               String workspace = node.getSession().getWorkspace().getName();
-               if (node.hasNode(JCR_CONTENT))
-                       return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
-               else
-                       return workspace + '_' + node.getIdentifier();
-       }
-
-       public Binary getImageBinary(Node node) throws RepositoryException {
-               if (node.isNodeType(NT_FILE)) {
-                       return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
-               } else if (node.isNodeType(CmsTypes.CMS_STYLED) && node.hasProperty(CmsNames.CMS_DATA)) {
-                       return node.getProperty(CmsNames.CMS_DATA).getBinary();
-               } else {
-                       return null;
-               }
-       }
-
-       public Image getSwtImage(Node node) throws RepositoryException {
-               InputStream inputStream = null;
-               Binary binary = getImageBinary(node);
-               if (binary == null)
-                       return null;
-               try {
-                       inputStream = binary.getStream();
-                       return new Image(Display.getCurrent(), inputStream);
-               } finally {
-                       IOUtils.closeQuietly(inputStream);
-                       JcrUtils.closeQuietly(binary);
-               }
-       }
-
-       @Override
-       public String uploadImage(Node parentNode, String fileName, InputStream in) throws RepositoryException {
-               InputStream inputStream = null;
-               try {
-                       String previousResourceName = null;
-                       if (parentNode.hasNode(fileName)) {
-                               Node node = parentNode.getNode(fileName);
-                               previousResourceName = getResourceName(node);
-                               if (node.hasNode(JCR_CONTENT)) {
-                                       node.getNode(JCR_CONTENT).remove();
-                                       node.addNode(JCR_CONTENT, NT_RESOURCE);
-                               }
-                       }
-
-                       byte[] arr = IOUtils.toByteArray(in);
-                       Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
-                       fileNode.addMixin(CmsTypes.CMS_IMAGE);
-
-                       inputStream = new ByteArrayInputStream(arr);
-                       ImageData id = new ImageData(inputStream);
-                       fileNode.setProperty(CMS_IMAGE_WIDTH, id.width);
-                       fileNode.setProperty(CMS_IMAGE_HEIGHT, id.height);
-                       String mime = Files.probeContentType(Paths.get(fileName));
-                       fileNode.setProperty(Property.JCR_MIMETYPE, mime);
-                       fileNode.getSession().save();
-
-                       // reset resource manager
-                       ResourceManager resourceManager = RWT.getResourceManager();
-                       if (previousResourceName != null && resourceManager.isRegistered(previousResourceName)) {
-                               resourceManager.unregister(previousResourceName);
-                               if (log.isDebugEnabled())
-                                       log.debug("Unregistered image " + previousResourceName);
-                       }
-                       return getImageUrl(fileNode);
-               } catch (IOException e) {
-                       throw new CmsException("Cannot upload image " + fileName + " in " + parentNode, e);
-               } finally {
-                       IOUtils.closeQuietly(inputStream);
-               }
-       }
-}
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/util/DefaultImageManager.java b/org.argeo.cms.ui/src/org/argeo/cms/util/DefaultImageManager.java
new file mode 100644 (file)
index 0000000..015ca1c
--- /dev/null
@@ -0,0 +1,246 @@
+package org.argeo.cms.util;
+
+import static javax.jcr.Node.JCR_CONTENT;
+import static javax.jcr.Property.JCR_DATA;
+import static javax.jcr.nodetype.NodeType.NT_FILE;
+import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
+import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.CmsException;
+import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.jcr.JcrUtils;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.service.ResourceManager;
+import org.eclipse.rap.rwt.widgets.FileUpload;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/** Manages only public images so far. */
+public class DefaultImageManager implements CmsImageManager {
+       private final static Log log = LogFactory.getLog(DefaultImageManager.class);
+//     private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
+
+       public Boolean load(Node node, Control control, Point preferredSize) throws RepositoryException {
+               Point imageSize = getImageSize(node);
+               Point size;
+               String imgTag = null;
+               if (preferredSize == null || imageSize.x == 0 || imageSize.y == 0
+                               || (preferredSize.x == 0 && preferredSize.y == 0)) {
+                       if (imageSize.x != 0 && imageSize.y != 0) {
+                               // actual image size if completely known
+                               size = imageSize;
+                       } else {
+                               // no image if not completely known
+                               size = resizeTo(NO_IMAGE_SIZE, preferredSize != null ? preferredSize : imageSize);
+                               imgTag = CmsUtils.noImg(size);
+                       }
+
+               } else if (preferredSize.x != 0 && preferredSize.y != 0) {
+                       // given size if completely provided
+                       size = preferredSize;
+               } else {
+                       // at this stage :
+                       // image is completely known
+                       assert imageSize.x != 0 && imageSize.y != 0;
+                       // one and only one of the dimension as been specified
+                       assert preferredSize.x == 0 || preferredSize.y == 0;
+                       size = resizeTo(imageSize, preferredSize);
+               }
+
+               boolean loaded = false;
+               if (control == null)
+                       return loaded;
+
+               if (control instanceof Label) {
+                       if (imgTag == null) {
+                               // IMAGE RETRIEVED HERE
+                               imgTag = getImageTag(node, size);
+                               //
+                               if (imgTag == null)
+                                       imgTag = CmsUtils.noImg(size);
+                               else
+                                       loaded = true;
+                       }
+
+                       Label lbl = (Label) control;
+                       lbl.setText(imgTag);
+                       // lbl.setSize(size);
+               } else if (control instanceof FileUpload) {
+                       FileUpload lbl = (FileUpload) control;
+                       lbl.setImage(CmsUtils.noImage(size));
+                       lbl.setSize(size);
+                       return loaded;
+               } else
+                       loaded = false;
+
+               return loaded;
+       }
+
+       private Point resizeTo(Point orig, Point constraints) {
+               if (constraints.x != 0 && constraints.y != 0) {
+                       return constraints;
+               } else if (constraints.x == 0 && constraints.y == 0) {
+                       return orig;
+               } else if (constraints.y == 0) {// force width
+                       return new Point(constraints.x, scale(orig.y, orig.x, constraints.x));
+               } else if (constraints.x == 0) {// force height
+                       return new Point(scale(orig.x, orig.y, constraints.y), constraints.y);
+               }
+               throw new CmsException("Cannot resize " + orig + " to " + constraints);
+       }
+
+       private int scale(int origDimension, int otherDimension, int otherConstraint) {
+               return Math.round(origDimension * divide(otherConstraint, otherDimension));
+       }
+
+       private float divide(int a, int b) {
+               return ((float) a) / ((float) b);
+       }
+
+       public Point getImageSize(Node node) throws RepositoryException {
+               // TODO load the SWT image ?
+               return new Point(0, 0);
+       }
+
+       /** @return null if not available */
+       @Override
+       public String getImageTag(Node node) throws RepositoryException {
+               return getImageTag(node, getImageSize(node));
+       }
+
+       private String getImageTag(Node node, Point size) throws RepositoryException {
+               StringBuilder buf = getImageTagBuilder(node, size);
+               if (buf == null)
+                       return null;
+               return buf.append("/>").toString();
+       }
+
+       /** @return null if not available */
+       @Override
+       public StringBuilder getImageTagBuilder(Node node, Point size) throws RepositoryException {
+               return getImageTagBuilder(node, Integer.toString(size.x), Integer.toString(size.y));
+       }
+
+       /** @return null if not available */
+       private StringBuilder getImageTagBuilder(Node node, String width, String height) throws RepositoryException {
+               String url = getImageUrl(node);
+               if (url == null)
+                       return null;
+               return CmsUtils.imgBuilder(url, width, height);
+       }
+
+       /** @return null if not available */
+       @Override
+       public String getImageUrl(Node node) throws RepositoryException {
+               return CmsUtils.getDataPath(node);
+               // String name = getResourceName(node);
+               // ResourceManager resourceManager = RWT.getResourceManager();
+               // if (!resourceManager.isRegistered(name)) {
+               // InputStream inputStream = null;
+               // Binary binary = getImageBinary(node);
+               // if (binary == null)
+               // return null;
+               // try {
+               // inputStream = binary.getStream();
+               // resourceManager.register(name, inputStream);
+               // } finally {
+               // IOUtils.closeQuietly(inputStream);
+               // JcrUtils.closeQuietly(binary);
+               // }
+               // if (log.isTraceEnabled())
+               // log.trace("Registered image " + name);
+               // }
+               // return resourceManager.getLocation(name);
+       }
+
+       protected String getResourceName(Node node) throws RepositoryException {
+               String workspace = node.getSession().getWorkspace().getName();
+               if (node.hasNode(JCR_CONTENT))
+                       return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
+               else
+                       return workspace + '_' + node.getIdentifier();
+       }
+
+       public Binary getImageBinary(Node node) throws RepositoryException {
+               if (node.isNodeType(NT_FILE)) {
+                       return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
+               } else {
+                       return null;
+               }
+       }
+
+       public Image getSwtImage(Node node) throws RepositoryException {
+               InputStream inputStream = null;
+               Binary binary = getImageBinary(node);
+               if (binary == null)
+                       return null;
+               try {
+                       inputStream = binary.getStream();
+                       return new Image(Display.getCurrent(), inputStream);
+               } finally {
+                       IOUtils.closeQuietly(inputStream);
+                       JcrUtils.closeQuietly(binary);
+               }
+       }
+
+       @Override
+       public String uploadImage(Node parentNode, String fileName, InputStream in) throws RepositoryException {
+               InputStream inputStream = null;
+               try {
+                       String previousResourceName = null;
+                       if (parentNode.hasNode(fileName)) {
+                               Node node = parentNode.getNode(fileName);
+                               previousResourceName = getResourceName(node);
+                               if (node.hasNode(JCR_CONTENT)) {
+                                       node.getNode(JCR_CONTENT).remove();
+                                       node.addNode(JCR_CONTENT, NT_RESOURCE);
+                               }
+                       }
+
+                       byte[] arr = IOUtils.toByteArray(in);
+                       Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
+                       inputStream = new ByteArrayInputStream(arr);
+                       ImageData id = new ImageData(inputStream);
+                       processNewImageFile(fileNode, id);
+
+                       String mime = Files.probeContentType(Paths.get(fileName));
+                       fileNode.setProperty(Property.JCR_MIMETYPE, mime);
+                       fileNode.getSession().save();
+
+                       // reset resource manager
+                       ResourceManager resourceManager = RWT.getResourceManager();
+                       if (previousResourceName != null && resourceManager.isRegistered(previousResourceName)) {
+                               resourceManager.unregister(previousResourceName);
+                               if (log.isDebugEnabled())
+                                       log.debug("Unregistered image " + previousResourceName);
+                       }
+                       return getImageUrl(fileNode);
+               } catch (IOException e) {
+                       throw new CmsException("Cannot upload image " + fileName + " in " + parentNode, e);
+               } finally {
+                       IOUtils.closeQuietly(inputStream);
+               }
+       }
+
+       /** Does nothign by default. */
+       protected void processNewImageFile(Node fileNode, ImageData id) throws RepositoryException, IOException {
+       }
+}
index ca563600cc7ca139fb060f043bf987017f4a48a5..3f06d88e881e814cc36f1f7a0adab322c2fa5e91 100644 (file)
@@ -14,7 +14,6 @@ import org.argeo.cms.ui.CmsImageManager;
 import org.argeo.cms.ui.CmsStyles;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.UxContext;
-import org.argeo.cms.ui.internal.ImageManagerImpl;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FillLayout;
@@ -44,7 +43,7 @@ public class SimpleErgonomics extends AbstractCmsEntryPoint {
        private CmsUiProvider end;
        private CmsUiProvider footer;
 
-       private CmsImageManager imageManager = new ImageManagerImpl();
+       private CmsImageManager imageManager = new DefaultImageManager();
        private UxContext uxContext = null;
 
        public SimpleErgonomics(Repository repository, String workspace, String defaultPath, CmsUiProvider uiProvider,
index 77d61cb4f2091b9dd6f556a8f1c36dbc0c3a872c..4e90766a674e1487bc27fba7ccd0103626365161 100644 (file)
@@ -1,7 +1,5 @@
 package org.argeo.cms.util;
 
-import org.argeo.cms.ui.internal.ImageManagerImpl;
-
-public class SimpleImageManager extends ImageManagerImpl {
+public class SimpleImageManager extends DefaultImageManager {
 
 }
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/widgets/Img.java b/org.argeo.cms.ui/src/org/argeo/cms/widgets/Img.java
new file mode 100644 (file)
index 0000000..59c4823
--- /dev/null
@@ -0,0 +1,150 @@
+package org.argeo.cms.widgets;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.argeo.cms.CmsException;
+import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.cms.ui.internal.JcrFileUploadReceiver;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.cms.viewers.NodePart;
+import org.argeo.cms.viewers.Section;
+import org.argeo.cms.viewers.SectionPart;
+import org.eclipse.rap.fileupload.FileUploadHandler;
+import org.eclipse.rap.fileupload.FileUploadListener;
+import org.eclipse.rap.fileupload.FileUploadReceiver;
+import org.eclipse.rap.rwt.service.ServerPushSession;
+import org.eclipse.rap.rwt.widgets.FileUpload;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/** An image within the Argeo Text framework */
+public class Img extends EditableImage implements SectionPart, NodePart {
+       private static final long serialVersionUID = 6233572783968188476L;
+
+       private final Section section;
+
+       private final CmsImageManager imageManager;
+       private FileUploadHandler currentUploadHandler = null;
+       private FileUploadListener fileUploadListener;
+
+       public Img(Composite parent, int swtStyle, Node imgNode,
+                       Point preferredImageSize) throws RepositoryException {
+               this(Section.findSection(parent), parent, swtStyle, imgNode,
+                               preferredImageSize);
+               setStyle(TextStyles.TEXT_IMAGE);
+       }
+
+       public Img(Composite parent, int swtStyle, Node imgNode)
+                       throws RepositoryException {
+               this(Section.findSection(parent), parent, swtStyle, imgNode, null);
+               setStyle(TextStyles.TEXT_IMAGE);
+       }
+
+       Img(Section section, Composite parent, int swtStyle, Node imgNode,
+                       Point preferredImageSize) throws RepositoryException {
+               super(parent, swtStyle, imgNode, false, preferredImageSize);
+               this.section = section;
+               imageManager = CmsUtils.getCmsView().getImageManager();
+               CmsUtils.style(this, TextStyles.TEXT_IMG);
+       }
+
+       @Override
+       protected Control createControl(Composite box, String style) {
+               if (isEditing()) {
+                       try {
+                               return createImageChooser(box, style);
+                       } catch (RepositoryException e) {
+                               throw new CmsException("Cannot create image chooser", e);
+                       }
+               } else {
+                       return createLabel(box, style);
+               }
+       }
+
+       @Override
+       public synchronized void stopEditing() {
+               super.stopEditing();
+               fileUploadListener = null;
+       }
+
+       @Override
+       protected synchronized Boolean load(Control lbl) {
+               try {
+                       Node imgNode = getNode();
+                       boolean loaded = imageManager.load(imgNode, lbl,
+                                       getPreferredImageSize());
+                       // getParent().layout();
+                       return loaded;
+               } catch (RepositoryException e) {
+                       throw new CmsException("Cannot load " + getNodeId()
+                                       + " from image manager", e);
+               }
+       }
+
+       protected Control createImageChooser(Composite box, String style)
+                       throws RepositoryException {
+               // FileDialog fileDialog = new FileDialog(getShell());
+               // fileDialog.open();
+               // String fileName = fileDialog.getFileName();
+               CmsImageManager imageManager = CmsUtils.getCmsView().getImageManager();
+               Node node = getNode();
+               JcrFileUploadReceiver receiver = new JcrFileUploadReceiver(
+                               node.getParent(), node.getName() + '[' + node.getIndex() + ']',
+                               imageManager);
+               if (currentUploadHandler != null)
+                       currentUploadHandler.dispose();
+               currentUploadHandler = prepareUpload(receiver);
+               final ServerPushSession pushSession = new ServerPushSession();
+               final FileUpload fileUpload = new FileUpload(box, SWT.NONE);
+               CmsUtils.style(fileUpload, style);
+               fileUpload.addSelectionListener(new SelectionAdapter() {
+                       private static final long serialVersionUID = -9158471843941668562L;
+
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               pushSession.start();
+                               fileUpload.submit(currentUploadHandler.getUploadUrl());
+                       }
+               });
+               return fileUpload;
+       }
+
+       protected FileUploadHandler prepareUpload(FileUploadReceiver receiver) {
+               final FileUploadHandler uploadHandler = new FileUploadHandler(receiver);
+               if (fileUploadListener != null)
+                       uploadHandler.addUploadListener(fileUploadListener);
+               return uploadHandler;
+       }
+
+       @Override
+       public Section getSection() {
+               return section;
+       }
+
+       public void setFileUploadListener(FileUploadListener fileUploadListener) {
+               this.fileUploadListener = fileUploadListener;
+               if (currentUploadHandler != null)
+                       currentUploadHandler.addUploadListener(fileUploadListener);
+       }
+
+       @Override
+       public Node getItem() throws RepositoryException {
+               return getNode();
+       }
+
+       @Override
+       public String getPartId() {
+               return getNodeId();
+       }
+
+       @Override
+       public String toString() {
+               return "Img #" + getPartId();
+       }
+
+}
index da4d949a40dbace86071e96c8a09da288710a784..4d999d5013ac02fbb9dc3748577f7989730b880f 100644 (file)
@@ -3,7 +3,6 @@ package org.argeo.cms.widgets;
 import javax.jcr.Item;
 import javax.jcr.RepositoryException;
 
-import org.argeo.cms.CmsNames;
 import org.argeo.cms.ui.CmsConstants;
 import org.argeo.cms.util.CmsUtils;
 import org.eclipse.swt.SWT;
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/widgets/TextStyles.java b/org.argeo.cms.ui/src/org/argeo/cms/widgets/TextStyles.java
new file mode 100644 (file)
index 0000000..be5bc5f
--- /dev/null
@@ -0,0 +1,37 @@
+package org.argeo.cms.widgets;
+
+/** Styles references in the CSS. */
+public interface TextStyles {
+       /** The whole page area */
+       public final static String TEXT_AREA = "text_area";
+       /** Area providing controls for editing text */
+       public final static String TEXT_EDITOR_HEADER = "text_editor_header";
+       /** The styled composite for editing the text */
+       public final static String TEXT_STYLED_COMPOSITE = "text_styled_composite";
+       /** A section */
+       public final static String TEXT_SECTION = "text_section";
+       /** A paragraph */
+       public final static String TEXT_PARAGRAPH = "text_paragraph";
+       /** An image */
+       public final static String TEXT_IMG = "text_img";
+       /** The dialog to edit styled paragraph */
+       public final static String TEXT_STYLED_TOOLS_DIALOG = "text_styled_tools_dialog";
+
+       /*
+        * DEFAULT TEXT STYLES
+        */
+       /** Default style for text body */
+       public final static String TEXT_DEFAULT = "text_default";
+       /** Fixed-width, typically code */
+       public final static String TEXT_PRE = "text_pre";
+       /** Quote */
+       public final static String TEXT_QUOTE = "text_quote";
+       /** Title */
+       public final static String TEXT_TITLE = "text_title";
+       /** Header (to be dynamically completed with the depth, e.g. text_h1) */
+       public final static String TEXT_H = "text_h";
+
+       /** Default style for images */
+       public final static String TEXT_IMAGE = "text_image";
+
+}
index f32e1fafcaa47ee96bf99b7fba19ff04addc206a..ab54cd60ef3c789e6521be96ebe6199996e4484e 100644 (file)
@@ -10,6 +10,4 @@ org.apache.commons.httpclient.cookie;resolution:=optional,\
 org.osgi.*;version=0.0.0,\
 *
 
-Provide-Capability: cms.datamodel;name=argeo;cnd=/org/argeo/cms/argeo.cnd;abstract=true,\
-cms.datamodel;name=cms;cnd=/org/argeo/cms/cms.cnd;abstract=true,\
-cms.datamodel;name=dn;cnd=/org/argeo/cms/dn.cnd;abstract=true
\ No newline at end of file
+Provide-Capability: cms.datamodel;name=argeo;cnd=/org/argeo/cms/argeo.cnd;abstract=true
diff --git a/org.argeo.cms/src/org/argeo/cms/CmsNames.java b/org.argeo.cms/src/org/argeo/cms/CmsNames.java
deleted file mode 100644 (file)
index be10b76..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.argeo.cms;
-
-/** JCR names. */
-public interface CmsNames {
-       /*
-        * TEXT
-        */
-       public final static String CMS_DRAFTS = "cms:drafts";
-
-       public final static String CMS_P = "cms:p";
-       public final static String CMS_H = "cms:h";
-
-       public final static String CMS_CONTENT = "cms:content";
-       public final static String CMS_STYLE = "cms:style";
-
-       public final static String CMS_INDEX = "cms:index";
-
-       /*
-        * IMAGES
-        */
-       public final static String CMS_IMAGE_WIDTH = "cms:imageWidth";
-       public final static String CMS_IMAGE_HEIGHT = "cms:imageHeight";
-       public final static String CMS_DATA = "cms:data";
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/CmsTypes.java b/org.argeo.cms/src/org/argeo/cms/CmsTypes.java
deleted file mode 100644 (file)
index a8ef076..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.argeo.cms;
-
-/** JCR types. */
-public interface CmsTypes {
-       public final static String CMS_TEXT = "cms:text";
-       public final static String CMS_IMAGE = "cms:image";
-       public final static String CMS_SECTION = "cms:section";
-       public final static String CMS_STYLED = "cms:styled";
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/cms.cnd b/org.argeo.cms/src/org/argeo/cms/cms.cnd
deleted file mode 100644 (file)
index 0e420f5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<cms = 'http://www.argeo.org/ns/cms'>
-
-// TEXT
-[cms:styled]
-mixin
-- cms:style (STRING)
-- cms:content (STRING)
-- cms:data (BINARY)
-
-[cms:image] > mix:title, mix:mimeType
-mixin
-- cms:imageWidth (STRING)
-- cms:imageHeight (STRING)
-
-[cms:section] > nt:folder, mix:created, mix:lastModified, mix:title
-orderable
-+ cms:p (nt:base) = nt:unstructured * 
-+ cms:h (cms:section) *
-+ cms:attached (nt:folder)
-
-[cms:text] > cms:section
-+ cms:history (nt:folder)
index 34bdcaa176587558bed883d067877db7a467c7cf..f9e17a107ea9d3f17f7e6ce722ef5f084055bb52 100644 (file)
@@ -3,7 +3,6 @@ package org.argeo.cms.internal.http;
 import static javax.jcr.Property.JCR_DESCRIPTION;
 import static javax.jcr.Property.JCR_LAST_MODIFIED;
 import static javax.jcr.Property.JCR_TITLE;
-import static org.argeo.cms.CmsTypes.CMS_IMAGE;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -102,14 +101,15 @@ public class LinkServlet extends HttpServlet {
                                        : null;
                        String url = getCanonicalUrl(node, request);
                        String imgUrl = null;
-                       loop: for (NodeIterator it = node.getNodes(); it.hasNext();) {
-                               // Takes the first found cms:image
-                               Node child = it.nextNode();
-                               if (child.isNodeType(CMS_IMAGE)) {
-                                       imgUrl = getDataUrl(child, request);
-                                       break loop;
-                               }
-                       }
+                       // TODO support images
+//                     loop: for (NodeIterator it = node.getNodes(); it.hasNext();) {
+//                             // Takes the first found cms:image
+//                             Node child = it.nextNode();
+//                             if (child.isNodeType(CMS_IMAGE)) {
+//                                     imgUrl = getDataUrl(child, request);
+//                                     break loop;
+//                             }
+//                     }
                        StringBuilder buf = new StringBuilder();
                        buf.append("<html>");
                        buf.append("<head>");