<?xml version="1.0" encoding="UTF-8"?>
-<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.suite</groupId>
<version>${version.argeo-commons}</version>
</dependency>
+ <!-- Specific -->
+ <dependency>
+ <groupId>org.argeo.commons</groupId>
+ <artifactId>org.argeo.eclipse.ui.rap</artifactId>
+ <version>2.1.91-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- Eclipse E4 -->
<dependency>
<groupId>org.argeo.tp</groupId>
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import javax.jcr.Item;
+
+import org.argeo.cms.ui.CmsTheme;
+import org.argeo.cms.ui.util.CmsIcon;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.widgets.ContextOverlay;
+import org.argeo.cms.ui.widgets.StyledControl;
+import org.argeo.entity.TermsManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** Common logic between single and mutliple terms editable part. */
+public abstract class AbstractTermsPart extends StyledControl implements EditablePart {
+ private static final long serialVersionUID = -5497097995341927710L;
+ protected final TermsManager termsManager;
+ protected final String typology;
+
+ protected final boolean editable;
+
+ private CmsIcon deleteIcon;
+ private CmsIcon addIcon;
+ private CmsIcon cancelIcon;
+
+ private Color highlightColor;
+ private Composite highlight;
+
+ protected final CmsTheme theme;
+
+ public AbstractTermsPart(Composite parent, int style, Item item, TermsManager termsManager,
+ String typology) {
+ super(parent, style, item);
+ this.termsManager = termsManager;
+ this.typology = typology;
+ this.theme = CmsTheme.getCmsTheme(parent);
+ editable = !(SWT.READ_ONLY == (style & SWT.READ_ONLY));
+ highlightColor = parent.getDisplay().getSystemColor(SWT.COLOR_GRAY);
+ }
+
+ protected void createHighlight(Composite block) {
+ highlight = new Composite(block, SWT.NONE);
+ highlight.setBackground(highlightColor);
+ GridData highlightGd = new GridData(SWT.FILL, SWT.FILL, false, false);
+ highlightGd.widthHint = 5;
+ highlightGd.heightHint = 3;
+ highlight.setLayoutData(highlightGd);
+
+ }
+
+ protected String getTermLabel(String name) {
+ return name;
+ }
+
+ protected abstract void refresh(ContextOverlay contextArea, String filter, Text txt);
+
+ protected boolean isTermSelectable(String term) {
+ return true;
+ }
+
+ protected void processTermListLabel(String term, Label label) {
+
+ }
+
+ //
+ // STYLING
+ //
+ public void setDeleteIcon(CmsIcon deleteIcon) {
+ this.deleteIcon = deleteIcon;
+ }
+
+ public void setAddIcon(CmsIcon addIcon) {
+ this.addIcon = addIcon;
+ }
+
+ public void setCancelIcon(CmsIcon cancelIcon) {
+ this.cancelIcon = cancelIcon;
+ }
+
+ protected TermsManager getTermsManager() {
+ return termsManager;
+ }
+
+ protected void styleDelete(ToolItem deleteItem) {
+ if (deleteIcon != null)
+ deleteItem.setImage(deleteIcon.getSmallIcon(theme));
+ else
+ deleteItem.setText("-");
+ }
+
+ protected void styleCancel(ToolItem cancelItem) {
+ if (cancelIcon != null)
+ cancelItem.setImage(cancelIcon.getSmallIcon(theme));
+ else
+ cancelItem.setText("X");
+ }
+
+ protected void styleAdd(ToolItem addItem) {
+ if (addIcon != null)
+ addItem.setImage(addIcon.getSmallIcon(theme));
+ else
+ addItem.setText("+");
+ }
+}
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Item;
+
+import org.argeo.cms.ui.forms.FormStyle;
+import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.widgets.ContextOverlay;
+import org.argeo.eclipse.ui.MouseDoubleClick;
+import org.argeo.eclipse.ui.MouseDown;
+import org.argeo.eclipse.ui.Selected;
+import org.argeo.entity.TermsManager;
+import org.argeo.jcr.Jcr;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** {@link EditablePart} for multiple terms. */
+public class MultiTermsPart extends AbstractTermsPart {
+ private static final long serialVersionUID = -4961135649177920808L;
+
+ public MultiTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) {
+ super(parent, style, item, termsManager, typology);
+ }
+
+ @Override
+ protected Control createControl(Composite box, String style) {
+ Composite placeholder = new Composite(box, SWT.NONE);
+ RowLayout rl = new RowLayout(SWT.HORIZONTAL | SWT.WRAP);
+ placeholder.setLayout(rl);
+ List<String> currentValue = Jcr.getMultiple(getNode(), typology);
+ if (currentValue != null && !currentValue.isEmpty())
+ for (String value : currentValue) {
+ Composite block = new Composite(placeholder, SWT.NONE);
+ block.setLayout(CmsUiUtils.noSpaceGridLayout(3));
+ Label lbl = new Label(block, SWT.SINGLE);
+ String display = getTermLabel(value);
+ lbl.setText(display);
+ CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style);
+ if (editable)
+ lbl.addMouseListener((MouseDoubleClick) (e) -> {
+ startEditing();
+ });
+ if (isEditing()) {
+ ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
+ ToolItem deleteItem = new ToolItem(toolBar, SWT.FLAT);
+ styleDelete(deleteItem);
+ deleteItem.addSelectionListener((Selected) (e) -> {
+ List<String> newValue = new ArrayList<>();
+ for (String v : currentValue) {
+ if (!v.equals(value))
+ newValue.add(v);
+ }
+ Jcr.set(getNode(), typology, newValue);
+ Jcr.save(getNode());
+ block.dispose();
+ layout(true, true);
+ });
+
+ }
+ }
+ else {// empty
+ if (editable && !isEditing()) {
+ ToolBar toolBar = new ToolBar(placeholder, SWT.HORIZONTAL);
+ ToolItem addItem = new ToolItem(toolBar, SWT.FLAT);
+ styleAdd(addItem);
+ addItem.addSelectionListener((Selected) (e) -> {
+ startEditing();
+ });
+ }
+ }
+
+ if (isEditing()) {
+ Composite block = new Composite(placeholder, SWT.NONE);
+ block.setLayout(CmsUiUtils.noSpaceGridLayout(3));
+
+ createHighlight(block);
+
+ Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
+ txt.setLayoutData(CmsUiUtils.fillWidth());
+// txt.setMessage("[new]");
+
+ CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style);
+
+ ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
+ ToolItem cancelItem = new ToolItem(toolBar, SWT.FLAT);
+ styleCancel(cancelItem);
+ cancelItem.addSelectionListener((Selected) (e) -> {
+ stopEditing();
+ });
+
+ ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) {
+ private static final long serialVersionUID = -7980078594405384874L;
+
+ @Override
+ protected void onHide() {
+ stopEditing();
+ }
+ };
+ contextOverlay.setLayout(new GridLayout());
+ // filter
+ txt.addModifyListener((e) -> {
+ String filter = txt.getText().toLowerCase();
+ if ("".equals(filter.trim()))
+ filter = null;
+ refresh(contextOverlay, filter, txt);
+ });
+ txt.addFocusListener(new FocusListener() {
+ private static final long serialVersionUID = -6024501573409619949L;
+
+ @Override
+ public void focusLost(FocusEvent event) {
+// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible())
+// getDisplay().asyncExec(() -> stopEditing());
+ }
+
+ @Override
+ public void focusGained(FocusEvent event) {
+ // txt.setText("");
+ if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible())
+ refresh(contextOverlay, null, txt);
+ }
+ });
+ layout(new Control[] { txt });
+ // getDisplay().asyncExec(() -> txt.setFocus());
+ }
+ return placeholder;
+ }
+
+ @Override
+ protected void refresh(ContextOverlay contextArea, String filter, Text txt) {
+ CmsUiUtils.clear(contextArea);
+ List<String> terms = termsManager.listAllTerms(typology);
+ List<String> currentValue = Jcr.getMultiple(getNode(), typology);
+ terms: for (String term : terms) {
+ if (currentValue != null && currentValue.contains(term))
+ continue terms;
+ String display = getTermLabel(term);
+ if (filter != null && !display.toLowerCase().contains(filter))
+ continue terms;
+ Label termL = new Label(contextArea, SWT.WRAP);
+ termL.setText(display);
+ processTermListLabel(term, termL);
+ if (isTermSelectable(term))
+ termL.addMouseListener((MouseDown) (e) -> {
+ List<String> newValue = new ArrayList<>();
+ if (currentValue != null)
+ newValue.addAll(currentValue);
+ newValue.add(term);
+ Jcr.set(getNode(), typology, newValue);
+ Jcr.save(getNode());
+ contextArea.hide();
+ stopEditing();
+ });
+ }
+ contextArea.show();
+ }
+
+}
--- /dev/null
+package org.argeo.entity.ui.forms;
+
+import java.util.List;
+
+import javax.jcr.Item;
+
+import org.argeo.cms.ui.forms.FormStyle;
+import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.viewers.EditablePart;
+import org.argeo.cms.ui.widgets.ContextOverlay;
+import org.argeo.eclipse.ui.MouseDoubleClick;
+import org.argeo.eclipse.ui.MouseDown;
+import org.argeo.eclipse.ui.Selected;
+import org.argeo.entity.TermsManager;
+import org.argeo.jcr.Jcr;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** {@link EditablePart} for terms. */
+public class SingleTermPart extends AbstractTermsPart {
+ private static final long serialVersionUID = -4961135649177920808L;
+
+ public SingleTermPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) {
+ super(parent, style, item, termsManager, typology);
+ }
+
+ @Override
+ protected Control createControl(Composite box, String style) {
+ if (isEditing()) {
+ Composite block = new Composite(box, SWT.NONE);
+ block.setLayout(CmsUiUtils.noSpaceGridLayout(3));
+
+ createHighlight(block);
+
+ Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
+ CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style);
+
+ ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
+ ToolItem deleteItem = new ToolItem(toolBar, SWT.PUSH);
+ styleDelete(deleteItem);
+ deleteItem.addSelectionListener((Selected) (e) -> {
+ Jcr.set(getNode(), typology, null);
+ Jcr.save(getNode());
+ stopEditing();
+ });
+ ToolItem cancelItem = new ToolItem(toolBar, SWT.PUSH);
+ styleCancel(cancelItem);
+ cancelItem.addSelectionListener((Selected) (e) -> {
+ stopEditing();
+ });
+
+ ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) {
+ private static final long serialVersionUID = -7980078594405384874L;
+
+ @Override
+ protected void onHide() {
+ stopEditing();
+ }
+ };
+ contextOverlay.setLayout(new GridLayout());
+ // filter
+ txt.addModifyListener((e) -> {
+ String filter = txt.getText().toLowerCase();
+ if ("".equals(filter.trim()))
+ filter = null;
+ refresh(contextOverlay, filter, txt);
+ });
+ txt.addFocusListener(new FocusListener() {
+ private static final long serialVersionUID = -6024501573409619949L;
+
+ @Override
+ public void focusLost(FocusEvent event) {
+// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible())
+// getDisplay().asyncExec(() -> stopEditing());
+ }
+
+ @Override
+ public void focusGained(FocusEvent event) {
+ // txt.setText("");
+ if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible())
+ refresh(contextOverlay, null, txt);
+ }
+ });
+ layout(new Control[] { block });
+ getDisplay().asyncExec(() -> txt.setFocus());
+ return block;
+ } else {
+ Composite block = new Composite(box, SWT.NONE);
+ block.setLayout(CmsUiUtils.noSpaceGridLayout(2));
+ String currentValue = Jcr.get(getNode(), typology);
+ if (currentValue != null) {
+ Label lbl = new Label(block, SWT.SINGLE);
+ String display = getTermLabel(currentValue);
+ lbl.setText(display);
+ CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style);
+
+ lbl.addMouseListener((MouseDoubleClick) (e) -> {
+ startEditing();
+ });
+ } else {
+ ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
+ ToolItem addItem = new ToolItem(toolBar, SWT.FLAT);
+ styleAdd(addItem);
+ addItem.addSelectionListener((Selected) (e) -> {
+ startEditing();
+ });
+ }
+ return block;
+ }
+ }
+
+ @Override
+ protected void refresh(ContextOverlay contextArea, String filter, Text txt) {
+ CmsUiUtils.clear(contextArea);
+ List<String> terms = termsManager.listAllTerms(typology);
+ terms: for (String term : terms) {
+ String display = getTermLabel(term);
+ if (filter != null && !display.toLowerCase().contains(filter))
+ continue terms;
+ Label termL = new Label(contextArea, SWT.WRAP);
+ termL.setText(display);
+ processTermListLabel(term, termL);
+ if (isTermSelectable(term))
+ termL.addMouseListener((MouseDown) (e) -> {
+ Jcr.set(getNode(), typology, term);
+ Jcr.save(getNode());
+ contextArea.hide();
+ stopEditing();
+ });
+ }
+ contextArea.show();
+ // txt.setFocus();
+ }
+
+}
+++ /dev/null
-package org.argeo.entity.ui.forms;
-
-import java.util.List;
-
-import javax.jcr.Item;
-
-import org.argeo.cms.ui.forms.FormStyle;
-import org.argeo.cms.ui.util.CmsUiUtils;
-import org.argeo.cms.ui.viewers.EditablePart;
-import org.argeo.cms.ui.widgets.ContextOverlay;
-import org.argeo.cms.ui.widgets.StyledControl;
-import org.argeo.eclipse.ui.MouseDoubleClick;
-import org.argeo.eclipse.ui.MouseDown;
-import org.argeo.entity.TermsManager;
-import org.argeo.jcr.Jcr;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-/** {@link EditablePart} for terms. */
-public class TermsEditablePart extends StyledControl implements EditablePart {
- private static final long serialVersionUID = -4961135649177920808L;
- private TermsManager termsManager;
- private String typology;
-
- public TermsEditablePart(Composite parent, int style, Item item, TermsManager termsManager, String typology) {
- super(parent, style, item);
- this.termsManager = termsManager;
- this.typology = typology;
- }
-
- @Override
- protected Control createControl(Composite box, String style) {
- if (isEditing()) {
- Text txt = new Text(box, SWT.SINGLE | SWT.BORDER);
- CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style);
-
- ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) {
- private static final long serialVersionUID = -7980078594405384874L;
-
- @Override
- protected void onHide() {
- stopEditing();
- }
- };
- contextOverlay.setLayout(new GridLayout());
- // filter
- txt.addModifyListener((e) -> {
- String filter = txt.getText().toLowerCase();
- if ("".equals(filter.trim()))
- filter = null;
- refresh(contextOverlay, filter, txt);
- });
- txt.addFocusListener(new FocusListener() {
- private static final long serialVersionUID = -6024501573409619949L;
-
- @Override
- public void focusLost(FocusEvent event) {
-// if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible())
-// getDisplay().asyncExec(() -> stopEditing());
- }
-
- @Override
- public void focusGained(FocusEvent event) {
- // txt.setText("");
- if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible())
- refresh(contextOverlay, null, txt);
- }
- });
- layout(new Control[] { txt });
- getDisplay().asyncExec(() -> txt.setFocus());
- return txt;
- } else {
- Label lbl = new Label(box, SWT.SINGLE);
- // lbl.setEditable(false);
- String currentValue = Jcr.get(getNode(), typology);
- if (currentValue != null) {
- String display = getTermLabel(currentValue);
- lbl.setText(display);
- } else
- lbl.setText("[" + typology + "]");
- CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style);
-
- lbl.addMouseListener((MouseDoubleClick) (e) -> {
- startEditing();
- });
- return lbl;
- }
- }
-
- protected String getTermLabel(String name) {
- return name;
- }
-
- protected void refresh(ContextOverlay contextArea, String filter, Text txt) {
- CmsUiUtils.clear(contextArea);
- List<String> terms = termsManager.listAllTerms(typology);
- terms: for (String term : terms) {
- String display = getTermLabel(term);
- if (filter != null && !display.toLowerCase().contains(filter))
- continue terms;
- Label termL = new Label(contextArea, SWT.WRAP);
- termL.setText(display);
- termL.addMouseListener((MouseDown) (e) -> {
- Jcr.set(getNode(), typology, term);
- Jcr.save(getNode());
- contextArea.hide();
- stopEditing();
- });
- }
- contextArea.show();
- // txt.setFocus();
- }
-
-}