Work on CMS Text, introduce CMS Demo E4
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 4 Oct 2018 07:16:46 +0000 (09:16 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 4 Oct 2018 07:16:46 +0000 (09:16 +0200)
18 files changed:
demo/log4j.properties
dep/org.argeo.dep.cms.e4.rap/pom.xml
org.argeo.cms.e4.rap/OSGI-INF/cms-demo-rap.xml [new file with mode: 0644]
org.argeo.cms.e4.rap/bnd.bnd
org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsE4DemoApp.java [new file with mode: 0644]
org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java
org.argeo.cms.e4/build.properties
org.argeo.cms.e4/e4xmi/cms-demo.e4xmi [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-removeButtons.js [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbar.js [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbarGroups.json [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsDocBookEditor.java [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsTextEditor.java [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/HtmlEditor.java [new file with mode: 0644]
org.argeo.cms.e4/src/org/argeo/cms/e4/parts/test.json [new file with mode: 0644]
org.argeo.cms.ui/src/org/argeo/cms/ui/internal/text/AbstractDbkViewer.java
org.argeo.cms.ui/src/org/argeo/cms/util/SimpleImageManager.java [new file with mode: 0644]
org.argeo.jcr/src/org/argeo/jcr/docbook/docbook.cnd

index 01027a532f4d3a49220b141bd45c352229de8301..05932ba6cd5a9621c575017d161a84f499c8735e 100644 (file)
@@ -2,6 +2,7 @@ log4j.rootLogger=WARN, development
 
 log4j.logger.org.argeo=DEBUG
 log4j.logger.org.argeo.cms.internal=TRACE
+log4j.logger.org.argeo.cms.viewers=TRACE
 
 ## Appenders
 log4j.appender.console=org.apache.log4j.ConsoleAppender
index c32bb4a1c4a66ef6850d2a4a14211acfffef8f99..9f530155d21553b182401a150f1599b8d0f9d102 100644 (file)
@@ -1,5 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.argeo.commons</groupId>
                        <artifactId>javax.mail</artifactId>
                </dependency>
 
+               <!-- Nebula -->
+               <dependency>
+                       <groupId>org.argeo.tp.rap.e4</groupId>
+                       <artifactId>org.eclipse.rap.nebula.widgets.richtext</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.rap.e4</groupId>
+                       <artifactId>org.eclipse.rap.nebula.widgets.grid</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.tp.rap.e4</groupId>
+                       <artifactId>org.eclipse.rap.nebula.jface.gridviewer</artifactId>
+               </dependency>
+
+
                <!-- Spring -->
                <dependency>
                        <groupId>org.argeo.tp.spring</groupId>
diff --git a/org.argeo.cms.e4.rap/OSGI-INF/cms-demo-rap.xml b/org.argeo.cms.e4.rap/OSGI-INF/cms-demo-rap.xml
new file mode 100644 (file)
index 0000000..2fa0182
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" configuration-policy="optional" name="CMS Demo RAP">
+   <implementation class="org.argeo.cms.e4.rap.CmsE4DemoApp"/>
+   <service>
+      <provide interface="org.eclipse.rap.rwt.application.ApplicationConfiguration"/>
+      <property name="contextName" type="String" value="demo"/>
+   </service>
+</scr:component>
index d22ec8e7d27e6d769a5d56dda15917f0bfbab5c1..53aa941930771b5816e7d61f163d19bfcfc94f06 100644 (file)
@@ -1,5 +1,6 @@
 Bundle-ActivationPolicy: lazy
-Service-Component: OSGI-INF/cms-admin-rap.xml
+Service-Component: OSGI-INF/cms-admin-rap.xml,\
+OSGI-INF/cms-demo-rap.xml
 
 Import-Package: org.argeo.node,\
 org.eclipse.swt,\
diff --git a/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsE4DemoApp.java b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsE4DemoApp.java
new file mode 100644 (file)
index 0000000..358980b
--- /dev/null
@@ -0,0 +1,10 @@
+package org.argeo.cms.e4.rap;
+
+public class CmsE4DemoApp extends AbstractRapE4App {
+       public CmsE4DemoApp() {
+               setPageTitle("CMS Demo");
+               setE4Xmi("org.argeo.cms.e4/e4xmi/cms-demo.e4xmi");
+               setPath("/cms-e4");
+       }
+
+}
index 047fb371e46e1efa464e9b53e8c88f9a5c90f03b..a062bea6bd013d062d0ea598907a76168a4e84f4 100644 (file)
@@ -14,8 +14,10 @@ import org.argeo.cms.ui.CmsImageManager;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.UxContext;
 import org.argeo.cms.ui.dialogs.CmsFeedback;
+import org.argeo.cms.util.SimpleImageManager;
 import org.argeo.cms.util.SimpleUxContext;
 import org.argeo.cms.widgets.auth.CmsLoginShell;
+import org.argeo.eclipse.ui.specific.UiContext;
 import org.argeo.node.NodeConstants;
 import org.eclipse.e4.core.services.events.IEventBroker;
 import org.eclipse.e4.ui.workbench.UIEvents;
@@ -34,6 +36,7 @@ public class CmsLoginLifecycle implements CmsView {
        private final static Log log = LogFactory.getLog(CmsLoginLifecycle.class);
 
        private UxContext uxContext;
+       private CmsImageManager imageManager;
 
        private LoginContext loginContext;
        private BrowserNavigation browserNavigation;
@@ -57,6 +60,7 @@ public class CmsLoginLifecycle implements CmsView {
 
                Subject subject = Subject.getSubject(AccessController.getContext());
                Display display = Display.getCurrent();
+               UiContext.setData(CmsView.KEY, this);
                CmsLoginShell loginShell = new CmsLoginShell(this);
                loginShell.setSubject(subject);
                try {
@@ -75,6 +79,7 @@ public class CmsLoginLifecycle implements CmsView {
                if (CurrentUser.getUsername(getSubject()) == null)
                        return false;
                uxContext = new SimpleUxContext();
+               imageManager = new SimpleImageManager();
 
                eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE, new EventHandler() {
                        @Override
@@ -138,7 +143,7 @@ public class CmsLoginLifecycle implements CmsView {
 
        @Override
        public CmsImageManager getImageManager() {
-               throw new UnsupportedOperationException();
+               return imageManager;
        }
 
        protected Subject getSubject() {
index eefb4da70380cdbfe88ea34e4d78fbb76a7b4b69..e46a7baeeb202b104ef3dcb4a021eab830673e4e 100644 (file)
@@ -4,5 +4,6 @@ bin.includes = META-INF/,\
                .,\
                OSGI-INF/homeRepository.xml,\
                OSGI-INF/userAdminWrapper.xml,\
-               OSGI-INF/defaultCallbackHandler.xml
+               OSGI-INF/defaultCallbackHandler.xml,\
+               e4xmi/cms-demo.e4xmi
 source.. = src/
diff --git a/org.argeo.cms.e4/e4xmi/cms-demo.e4xmi b/org.argeo.cms.e4/e4xmi/cms-demo.e4xmi
new file mode 100644 (file)
index 0000000..673fc6d
--- /dev/null
@@ -0,0 +1,27 @@
+<?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.cms.e4/org.argeo.cms.e4.parts.CmsDocBookEditor" 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/org.argeo.cms.e4.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/CkEditor-removeButtons.js b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-removeButtons.js
new file mode 100644 (file)
index 0000000..20e82e3
--- /dev/null
@@ -0,0 +1 @@
+'Source,Save,Templates,Strike,Subscript,Superscript,CopyFormatting,Outdent,Indent,CreateDiv,JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock,Language,Anchor,Flash,HorizontalRule,Smiley,SpecialChar,PageBreak,Iframe,Format,Font,FontSize,BGColor,TextColor,ShowBlocks,About,Preview,Print,Redo,Replace,Find,Undo,SelectAll,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,NewPage,PasteFromWord,Blockquote,BidiLtr,BidiRtl'
\ No newline at end of file
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbar.js b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbar.js
new file mode 100644 (file)
index 0000000..3058655
--- /dev/null
@@ -0,0 +1,19 @@
+CKEDITOR.editorConfig = function( config ) {
+       config.toolbarGroups = [
+               { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
+               { name: 'styles', groups: [ 'styles' ] },
+               { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
+               { name: 'forms', groups: [ 'forms' ] },
+               { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
+               { name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
+               { name: 'insert', groups: [ 'insert' ] },
+               { name: 'links', groups: [ 'links' ] },
+               { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
+               { name: 'colors', groups: [ 'colors' ] },
+               { name: 'tools', groups: [ 'tools' ] },
+               { name: 'others', groups: [ 'others' ] },
+               { name: 'about', groups: [ 'about' ] }
+       ];
+
+       config.removeButtons = 'Source,Save,Templates,Strike,Subscript,Superscript,CopyFormatting,Outdent,Indent,CreateDiv,JustifyLeft,JustifyCenter,JustifyRight,JustifyBlock,BidiLtr,BidiRtl,Language,Anchor,Flash,HorizontalRule,Smiley,SpecialChar,PageBreak,Iframe,Format,Font,FontSize,BGColor,TextColor,Maximize,ShowBlocks,About,Preview,Print,Redo,Replace,Find,Undo,SelectAll,Scayt,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,NewPage,PasteFromWord,Blockquote';
+};
\ No newline at end of file
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbarGroups.json b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbarGroups.json
new file mode 100644 (file)
index 0000000..a886c27
--- /dev/null
@@ -0,0 +1,92 @@
+[
+       {
+               "name": "document",
+               "groups": [
+                       "mode",
+                       "document",
+                       "doctools"
+               ]
+       },
+       {
+               "name": "styles",
+               "groups": [
+                       "styles"
+               ]
+       },
+       {
+               "name": "editing",
+               "groups": [
+                       "find",
+                       "selection",
+                       "spellchecker",
+                       "editing"
+               ]
+       },
+       {
+               "name": "forms",
+               "groups": [
+                       "forms"
+               ]
+       },
+       {
+               "name": "basicstyles",
+               "groups": [
+                       "basicstyles",
+                       "cleanup"
+               ]
+       },
+       {
+               "name": "paragraph",
+               "groups": [
+                       "list",
+                       "indent",
+                       "blocks",
+                       "align",
+                       "bidi",
+                       "paragraph"
+               ]
+       },
+       {
+               "name": "insert",
+               "groups": [
+                       "insert"
+               ]
+       },
+       {
+               "name": "links",
+               "groups": [
+                       "links"
+               ]
+       },
+       {
+               "name": "clipboard",
+               "groups": [
+                       "clipboard",
+                       "undo"
+               ]
+       },
+       {
+               "name": "colors",
+               "groups": [
+                       "colors"
+               ]
+       },
+       {
+               "name": "tools",
+               "groups": [
+                       "tools"
+               ]
+       },
+       {
+               "name": "others",
+               "groups": [
+                       "others"
+               ]
+       },
+       {
+               "name": "about",
+               "groups": [
+                       "about"
+               ]
+       }
+]
\ No newline at end of file
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsDocBookEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsDocBookEditor.java
new file mode 100644 (file)
index 0000000..b39feab
--- /dev/null
@@ -0,0 +1,81 @@
+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 javax.jcr.nodetype.NodeType;
+
+import org.argeo.cms.CmsException;
+import org.argeo.cms.text.DocumentTextEditor;
+import org.argeo.cms.viewers.JcrVersionCmsEditable;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.docbook.DocBookTypes;
+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 CmsDocBookEditor 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(), "article", DocBookTypes.ARTICLE);
+                       if (textNode.isCheckedOut())
+                               textNode.addMixin(NodeType.MIX_TITLE);
+                       cmsEditable = new JcrVersionCmsEditable(textNode);
+                       if (session.hasPendingChanges())
+                               session.save();
+                       cmsEditable.addObserver(this);
+                       DocumentTextEditor textEditor = new DocumentTextEditor(parent, SWT.NONE, textNode, cmsEditable);
+                       mpart.setDirty(isDirty());
+               } catch (RepositoryException e) {
+                       throw new CmsException("Cannot create text editor", e);
+               }
+       }
+
+       @PreDestroy
+       public void dispose() {
+               JcrUtils.logoutQuietly(session);
+       }
+
+       @Persist
+       public void save() {
+               try {
+                       session.save();
+               } catch (RepositoryException e) {
+                       throw new CmsException("Cannot save", e);
+               }
+               cmsEditable.stopEditing();
+       }
+
+       @Override
+       public void update(Observable o, Object arg) {
+               // CmsEditable cmsEditable = (CmsEditable) o;
+               mpart.setDirty(isDirty());
+       }
+
+       boolean isDirty() {
+               return cmsEditable.isEditing();
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..4021ead
--- /dev/null
@@ -0,0 +1,73 @@
+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();
+       }
+
+}
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/HtmlEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/HtmlEditor.java
new file mode 100644 (file)
index 0000000..9b8c2d0
--- /dev/null
@@ -0,0 +1,127 @@
+package org.argeo.cms.e4.parts;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.cms.CmsException;
+import org.argeo.cms.util.CmsUtils;
+import org.eclipse.nebula.widgets.richtext.RichTextEditor;
+import org.eclipse.nebula.widgets.richtext.RichTextEditorConfiguration;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class HtmlEditor {
+
+       @PostConstruct
+       public void createUI(Composite parent) {
+               String toolbarGroups;
+               String removeButtons;
+               try {
+                       toolbarGroups = IOUtils.toString(HtmlEditor.class.getResourceAsStream("CkEditor-toolbarGroups.json"),
+                                       StandardCharsets.UTF_8);
+                       removeButtons = IOUtils.toString(HtmlEditor.class.getResourceAsStream("CkEditor-removeButtons.js"),
+                                       StandardCharsets.UTF_8);
+               } catch (IOException e) {
+                       throw new CmsException("Cannot configure toolbar", e);
+               }
+//             System.out.println(toolbarGroups);
+//             System.out.println(removeButtons);
+               RichTextEditorConfiguration richTextEditorConfig = new RichTextEditorConfiguration();
+               richTextEditorConfig.setOption(RichTextEditorConfiguration.TOOLBAR_GROUPS, toolbarGroups);
+               richTextEditorConfig.setOption(RichTextEditorConfiguration.REMOVE_BUTTONS, removeButtons);
+//             richTextEditorConfig.setRemoveStyles(false);
+//             richTextEditorConfig.setRemovePasteFromWord(true);
+//             richTextEditorConfig.setRemovePasteText(false);
+
+//             richTextEditorConfig.setToolbarCollapsible(true);
+//             richTextEditorConfig.setToolbarInitialExpanded(false);
+               
+               final Display display = parent.getDisplay();
+               Composite composite = new Composite(parent, SWT.NONE);
+//             composite.setLayoutData(new Fill);
+               composite.setLayout(new GridLayout());
+               final RichTextEditor richTextEditor = new RichTextEditor(composite, richTextEditorConfig, SWT.BORDER);
+               richTextEditor.setText("<a href='http://googl.com'>Google</a>");
+               GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
+               richTextEditor.setLayoutData(layoutData);
+               richTextEditor.setBackground(new Color(display, 247, 247, 247));
+               Composite toolbar = new Composite(composite, SWT.NONE);
+               toolbar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               toolbar.setLayout(new GridLayout(3, false));
+               Button showContent = new Button(toolbar, SWT.PUSH);
+               showContent.setText("Show Content");
+               showContent.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               showContent(parent, richTextEditor, false);
+                       }
+               });
+               Button showSource = new Button(toolbar, SWT.PUSH);
+               showSource.setText("Show Source");
+               showSource.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               showContent(parent, richTextEditor, true);
+                       }
+               });
+               Button clearBtn = new Button(toolbar, SWT.NONE);
+               clearBtn.setText("Clear");
+               clearBtn.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               richTextEditor.setText("");
+                       }
+               });
+
+       }
+
+       private static void showContent(Composite parent, RichTextEditor editor, boolean source) {
+               int style = SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL;
+               final Shell content = new Shell(parent.getShell(), style);
+               content.setLayout(new GridLayout(1, true));
+               String text = editor.getText();
+               if (source) {
+                       content.setText("Rich Text Source");
+                       Text viewer = new Text(content, SWT.MULTI | SWT.WRAP);
+                       viewer.setLayoutData(new GridData(400, 400));
+                       viewer.setText(text);
+                       viewer.setEditable(false);
+               } else {
+                       content.setText("Rich Text");
+                       Browser viewer = new Browser(content, SWT.NONE);
+                       viewer.setLayoutData(new GridData(400, 400));
+                       viewer.setText(text);
+                       viewer.setEnabled(false);
+               }
+               Button ok = new Button(content, SWT.PUSH);
+               ok.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, false));
+               ok.setText("OK");
+               ok.addSelectionListener(new SelectionAdapter() {
+                       @Override
+                       public void widgetSelected(SelectionEvent e) {
+                               content.dispose();
+                       }
+               });
+               content.setDefaultButton(ok);
+               content.pack();
+               Display display = parent.getDisplay();
+               int left = (display.getClientArea().width / 2) - (content.getBounds().width / 2);
+               content.setLocation(left, 40);
+               content.open();
+               ok.setFocus();
+       }
+
+}
diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/test.json b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/test.json
new file mode 100644 (file)
index 0000000..eed3f0e
--- /dev/null
@@ -0,0 +1,28 @@
+{
+       "firstName": "John",
+       "lastName": "Smith",
+       "isAlive": true,
+       "age": 27,
+       "address": {
+               "streetAddress": "21 2nd Street",
+               "city": "New York",
+               "state": "NY",
+               "postalCode": "10021-3100"
+       },
+       "phoneNumbers": [
+               {
+                       "type": "home",
+                       "number": "212 555-1234"
+               },
+               {
+                       "type": "office",
+                       "number": "646 555-4567"
+               },
+               {
+                       "type": "mobile",
+                       "number": "123 456-7890"
+               }
+       ],
+       "children": [],
+       "spouse": null
+}
index 32c51adf5ca25678b65cf61b5bd075c5a19929ef..b75aa3e92301d9143395d297634dd5a13bfdf34a 100644 (file)
@@ -514,6 +514,7 @@ public abstract class AbstractDbkViewer extends AbstractPageViewer implements Ke
                                        return;
                                }
                                Node newSectionNode = sectionNode.addNode(DocBookNames.DBK_SECTION, DocBookTypes.SECTION);
+                               newSectionNode.addMixin(NodeType.MIX_TITLE);
                                sectionNode.orderBefore(h(newSectionNode.getIndex()), h(1));
 
                                int paragraphIndex = paragraphNode.getIndex();
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/util/SimpleImageManager.java b/org.argeo.cms.ui/src/org/argeo/cms/util/SimpleImageManager.java
new file mode 100644 (file)
index 0000000..77d61cb
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.cms.util;
+
+import org.argeo.cms.ui.internal.ImageManagerImpl;
+
+public class SimpleImageManager extends ImageManagerImpl {
+
+}
index c737cee63751356521570261445f51663c257884..74ec3cc88b4ea22b896ff06e17e70e387b1c4cb9 100644 (file)
@@ -85,6 +85,7 @@ mixin
 
 [argeodbk:base]
 abstract
+orderable
  - dbk:annotations (String)
  - dbk:arch (String)
  - dbk:audience (String)