From: Mathieu Baudier Date: Thu, 4 Oct 2018 07:16:46 +0000 (+0200) Subject: Work on CMS Text, introduce CMS Demo E4 X-Git-Tag: argeo-commons-2.1.76~44 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=64d3c6f490a863ad1f91c2f440e10ec7e46edd04 Work on CMS Text, introduce CMS Demo E4 --- diff --git a/demo/log4j.properties b/demo/log4j.properties index 01027a532..05932ba6c 100644 --- a/demo/log4j.properties +++ b/demo/log4j.properties @@ -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 diff --git a/dep/org.argeo.dep.cms.e4.rap/pom.xml b/dep/org.argeo.dep.cms.e4.rap/pom.xml index c32bb4a1c..9f530155d 100644 --- a/dep/org.argeo.dep.cms.e4.rap/pom.xml +++ b/dep/org.argeo.dep.cms.e4.rap/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 org.argeo.commons @@ -59,6 +61,21 @@ javax.mail + + + org.argeo.tp.rap.e4 + org.eclipse.rap.nebula.widgets.richtext + + + org.argeo.tp.rap.e4 + org.eclipse.rap.nebula.widgets.grid + + + org.argeo.tp.rap.e4 + org.eclipse.rap.nebula.jface.gridviewer + + + org.argeo.tp.spring 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 index 000000000..2fa018276 --- /dev/null +++ b/org.argeo.cms.e4.rap/OSGI-INF/cms-demo-rap.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.cms.e4.rap/bnd.bnd b/org.argeo.cms.e4.rap/bnd.bnd index d22ec8e7d..53aa94193 100644 --- a/org.argeo.cms.e4.rap/bnd.bnd +++ b/org.argeo.cms.e4.rap/bnd.bnd @@ -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 index 000000000..358980b08 --- /dev/null +++ b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsE4DemoApp.java @@ -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"); + } + +} diff --git a/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java index 047fb371e..a062bea6b 100644 --- a/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java +++ b/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java @@ -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() { diff --git a/org.argeo.cms.e4/build.properties b/org.argeo.cms.e4/build.properties index eefb4da70..e46a7baee 100644 --- a/org.argeo.cms.e4/build.properties +++ b/org.argeo.cms.e4/build.properties @@ -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 index 000000000..673fc6db9 --- /dev/null +++ b/org.argeo.cms.e4/e4xmi/cms-demo.e4xmi @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 index 000000000..20e82e34a --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-removeButtons.js @@ -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 index 000000000..305865546 --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbar.js @@ -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 index 000000000..a886c2791 --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CkEditor-toolbarGroups.json @@ -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 index 000000000..b39feab14 --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsDocBookEditor.java @@ -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 index 000000000..4021ead6c --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/CmsTextEditor.java @@ -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 index 000000000..9b8c2d0b6 --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/HtmlEditor.java @@ -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("Google"); + 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 index 000000000..eed3f0e87 --- /dev/null +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/parts/test.json @@ -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 +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/text/AbstractDbkViewer.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/text/AbstractDbkViewer.java index 32c51adf5..b75aa3e92 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/text/AbstractDbkViewer.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/text/AbstractDbkViewer.java @@ -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 index 000000000..77d61cb4f --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/util/SimpleImageManager.java @@ -0,0 +1,7 @@ +package org.argeo.cms.util; + +import org.argeo.cms.ui.internal.ImageManagerImpl; + +public class SimpleImageManager extends ImageManagerImpl { + +} diff --git a/org.argeo.jcr/src/org/argeo/jcr/docbook/docbook.cnd b/org.argeo.jcr/src/org/argeo/jcr/docbook/docbook.cnd index c737cee63..74ec3cc88 100644 --- a/org.argeo.jcr/src/org/argeo/jcr/docbook/docbook.cnd +++ b/org.argeo.jcr/src/org/argeo/jcr/docbook/docbook.cnd @@ -85,6 +85,7 @@ mixin [argeodbk:base] abstract +orderable - dbk:annotations (String) - dbk:arch (String) - dbk:audience (String)