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 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(); } }