Use horizontal row layout for multi terms.
[gpl/argeo-suite.git] / core / org.argeo.entity.ui / src / org / argeo / entity / ui / forms / MultiTermsPart.java
1 package org.argeo.entity.ui.forms;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.Item;
7
8 import org.argeo.cms.ui.forms.FormStyle;
9 import org.argeo.cms.ui.util.CmsUiUtils;
10 import org.argeo.cms.ui.viewers.EditablePart;
11 import org.argeo.cms.ui.widgets.ContextOverlay;
12 import org.argeo.eclipse.ui.MouseDoubleClick;
13 import org.argeo.eclipse.ui.MouseDown;
14 import org.argeo.eclipse.ui.Selected;
15 import org.argeo.entity.Term;
16 import org.argeo.entity.TermsManager;
17 import org.argeo.jcr.Jcr;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.events.FocusEvent;
20 import org.eclipse.swt.events.FocusListener;
21 import org.eclipse.swt.layout.FillLayout;
22 import org.eclipse.swt.layout.GridLayout;
23 import org.eclipse.swt.layout.RowLayout;
24 import org.eclipse.swt.widgets.Composite;
25 import org.eclipse.swt.widgets.Control;
26 import org.eclipse.swt.widgets.Label;
27 import org.eclipse.swt.widgets.Text;
28 import org.eclipse.swt.widgets.ToolBar;
29 import org.eclipse.swt.widgets.ToolItem;
30
31 /** {@link EditablePart} for multiple terms. */
32 public class MultiTermsPart extends AbstractTermsPart {
33         private static final long serialVersionUID = -4961135649177920808L;
34
35         public MultiTermsPart(Composite parent, int style, Item item, TermsManager termsManager, String typology) {
36                 super(parent, style, item, termsManager, typology);
37         }
38
39         @Override
40         protected Control createControl(Composite box, String style) {
41                 Composite placeholder = new Composite(box, SWT.NONE);
42                 RowLayout rl = new RowLayout(SWT.HORIZONTAL);
43                 rl.wrap = true;
44                 placeholder.setLayout(rl);
45                 List<Term> currentValue = getValue();
46                 if (currentValue != null && !currentValue.isEmpty())
47                         for (Term value : currentValue) {
48                                 Composite block = new Composite(placeholder, SWT.NONE);
49                                 block.setLayout(CmsUiUtils.noSpaceGridLayout(3));
50                                 Label lbl = new Label(block, SWT.SINGLE);
51                                 String display = getTermLabel(value);
52                                 lbl.setText(display);
53                                 CmsUiUtils.style(lbl, style == null ? FormStyle.propertyText.style() : style);
54                                 if (editable)
55                                         lbl.addMouseListener((MouseDoubleClick) (e) -> {
56                                                 startEditing();
57                                         });
58                                 if (isEditing()) {
59                                         ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
60                                         ToolItem deleteItem = new ToolItem(toolBar, SWT.FLAT);
61                                         styleDelete(deleteItem);
62                                         deleteItem.addSelectionListener((Selected) (e) -> {
63                                                 // we retrieve them again here because they may have changed
64                                                 List<Term> curr = getValue();
65                                                 List<Term> newValue = new ArrayList<>();
66                                                 for (Term v : curr) {
67                                                         if (!v.equals(value))
68                                                                 newValue.add(v);
69                                                 }
70                                                 setValue(newValue);
71                                                 block.dispose();
72                                                 layout(true, true);
73                                         });
74
75                                 }
76                         }
77                 else {// empty
78                         if (editable && !isEditing()) {
79                                 ToolBar toolBar = new ToolBar(placeholder, SWT.HORIZONTAL);
80                                 ToolItem addItem = new ToolItem(toolBar, SWT.FLAT);
81                                 styleAdd(addItem);
82                                 addItem.addSelectionListener((Selected) (e) -> {
83                                         startEditing();
84                                 });
85                         }
86                 }
87
88                 if (isEditing()) {
89                         Composite block = new Composite(placeholder, SWT.NONE);
90                         block.setLayout(CmsUiUtils.noSpaceGridLayout(3));
91
92                         createHighlight(block);
93
94                         Text txt = new Text(block, SWT.SINGLE | SWT.BORDER);
95                         txt.setLayoutData(CmsUiUtils.fillWidth());
96 //                      txt.setMessage("[new]");
97
98                         CmsUiUtils.style(txt, style == null ? FormStyle.propertyText.style() : style);
99
100                         ToolBar toolBar = new ToolBar(block, SWT.HORIZONTAL);
101                         ToolItem cancelItem = new ToolItem(toolBar, SWT.FLAT);
102                         styleCancel(cancelItem);
103                         cancelItem.addSelectionListener((Selected) (e) -> {
104                                 stopEditing();
105                         });
106
107                         ContextOverlay contextOverlay = new ContextOverlay(txt, SWT.NONE) {
108                                 private static final long serialVersionUID = -7980078594405384874L;
109
110                                 @Override
111                                 protected void onHide() {
112                                         stopEditing();
113                                 }
114                         };
115                         contextOverlay.setLayout(new GridLayout());
116                         // filter
117                         txt.addModifyListener((e) -> {
118                                 String filter = txt.getText().toLowerCase();
119                                 if ("".equals(filter.trim()))
120                                         filter = null;
121                                 refresh(contextOverlay, filter, txt);
122                         });
123                         txt.addFocusListener(new FocusListener() {
124                                 private static final long serialVersionUID = -6024501573409619949L;
125
126                                 @Override
127                                 public void focusLost(FocusEvent event) {
128 //                                      if (!contextOverlay.isDisposed() && contextOverlay.isShellVisible())
129 //                                              getDisplay().asyncExec(() -> stopEditing());
130                                 }
131
132                                 @Override
133                                 public void focusGained(FocusEvent event) {
134                                         // txt.setText("");
135                                         if (!contextOverlay.isDisposed() && !contextOverlay.isShellVisible())
136                                                 refresh(contextOverlay, null, txt);
137                                 }
138                         });
139                         layout(new Control[] { txt });
140                         // getDisplay().asyncExec(() -> txt.setFocus());
141                 }
142                 return placeholder;
143         }
144
145         @Override
146         protected void refresh(ContextOverlay contextArea, String filter, Text txt) {
147                 CmsUiUtils.clear(contextArea);
148                 List<? extends Term> terms = termsManager.listAllTerms(typology.getId());
149                 List<Term> currentValue = getValue();
150                 terms: for (Term term : terms) {
151                         if (currentValue != null && currentValue.contains(term))
152                                 continue terms;
153                         String display = getTermLabel(term);
154                         if (filter != null && !display.toLowerCase().contains(filter))
155                                 continue terms;
156                         Label termL = new Label(contextArea, SWT.WRAP);
157                         termL.setText(display);
158                         processTermListLabel(term, termL);
159                         if (isTermSelectable(term))
160                                 termL.addMouseListener((MouseDown) (e) -> {
161                                         List<Term> newValue = new ArrayList<>();
162                                         List<Term> curr = getValue();
163                                         if (currentValue != null)
164                                                 newValue.addAll(curr);
165                                         newValue.add(term);
166                                         setValue(newValue);
167                                         contextArea.hide();
168                                         stopEditing();
169                                 });
170                 }
171                 contextArea.show();
172         }
173
174         protected List<Term> getValue() {
175                 String property = typology.getId();
176                 List<String> curr = Jcr.getMultiple(getNode(), property);
177                 List<Term> res = new ArrayList<>();
178                 if (curr != null)
179                         for (String str : curr) {
180                                 Term term = termsManager.getTerm(str);
181                                 res.add(term);
182                         }
183                 return res;
184         }
185
186         protected void setValue(List<Term> value) {
187                 String property = typology.getId();
188                 List<String> ids = new ArrayList<>();
189                 for (Term term : value) {
190                         ids.add(term.getId());
191                 }
192                 Jcr.set(getNode(), property, ids);
193                 Jcr.save(getNode());
194         }
195
196 }