1 package org.argeo.tracker.ui.controls;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.Node;
7 import javax.jcr.Property;
8
9 import org.argeo.cms.util.CmsUtils;
10 import org.argeo.connect.ui.ConnectUiStyles;
11 import org.argeo.connect.ui.ConnectUiUtils;
12 import org.argeo.connect.ui.widgets.ConnectAbstractDropDown;
13 import org.argeo.connect.util.ConnectJcrUtils;
14 import org.argeo.eclipse.ui.EclipseUiUtils;
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.events.SelectionAdapter;
17 import org.eclipse.swt.events.SelectionEvent;
18 import org.eclipse.swt.events.TraverseEvent;
19 import org.eclipse.swt.events.TraverseListener;
20 import org.eclipse.swt.layout.GridData;
21 import org.eclipse.swt.layout.GridLayout;
22 import org.eclipse.swt.layout.RowData;
23 import org.eclipse.swt.layout.RowLayout;
24 import org.eclipse.swt.widgets.Button;
25 import org.eclipse.swt.widgets.Composite;
26 import org.eclipse.swt.widgets.Control;
27 import org.eclipse.swt.widgets.Label;
28 import org.eclipse.swt.widgets.Text;
29
30
31
32
33
34 public abstract class TagListWithDropDownComposite extends Composite {
35
36 private static final long serialVersionUID = 5439358000985800234L;
37
38
39 private List<String> chosenValues;
40 private final String newTagMsg = "Add...";
41
42 public List<String> getChosenValues() {
43 return chosenValues;
44 }
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public TagListWithDropDownComposite(Composite parent, int style, List<String> initialValues) {
59 super(parent, style);
60 if (initialValues == null)
61 chosenValues = new ArrayList<>();
62 else
63 chosenValues = initialValues;
64
65 populate(this);
66 }
67
68 public void populate(Composite parent) {
69
70 RowLayout rl = new RowLayout(SWT.HORIZONTAL);
71 rl.wrap = true;
72 rl.marginLeft = rl.marginBottom = 0;
73 rl.marginTop = 4;
74 rl.marginRight = 8;
75 parent.setLayout(rl);
76
77 for (String value : chosenValues) {
78 addValueCmp(parent, value);
79 }
80
81 final Text addValueTxt = new Text(parent, SWT.BORDER);
82 addValueTxt.setMessage(newTagMsg);
83 RowData rd = new RowData(80, SWT.DEFAULT);
84 addValueTxt.setLayoutData(rd);
85 final TagLikeDropDown tagDD = new TagLikeDropDown(addValueTxt);
86
87
88
89 addValueTxt.getParent().layout();
90 Button okBtn = new Button(parent, SWT.BORDER | SWT.PUSH | SWT.BOTTOM);
91 okBtn.setText("OK");
92 rd = new RowData(SWT.DEFAULT, addValueTxt.getSize().y - 2);
93 okBtn.setLayoutData(rd);
94
95 addValueTxt.addTraverseListener(new TraverseListener() {
96 private static final long serialVersionUID = 1L;
97
98 public void keyTraversed(TraverseEvent e) {
99 if (e.keyCode == SWT.CR) {
100 String newTag = tagDD.getText();
101 addValue(addValueTxt, newTag);
102 tagDD.reset("");
103 e.doit = false;
104 }
105 }
106 });
107
108 okBtn.addSelectionListener(new SelectionAdapter() {
109 private static final long serialVersionUID = 2780819012423622369L;
110
111 @Override
112 public void widgetSelected(SelectionEvent e) {
113 String newTag = tagDD.getText();
114 if (EclipseUiUtils.isEmpty(newTag))
115 return;
116 else
117 addValue(addValueTxt, newTag);
118 tagDD.reset("");
119 }
120 });
121 }
122
123 private void addValue(Control dropdownTxt, String newTag) {
124 if (!tagExists(newTag))
125
126 return;
127
128 if (chosenValues.contains(newTag))
129 return;
130
131 chosenValues.add(newTag);
132 Composite parent = dropdownTxt.getParent();
133 Composite valueCmp = addValueCmp(parent, newTag);
134 valueCmp.moveAbove(dropdownTxt);
135 parent.layout(true, true);
136 }
137
138 private Composite addValueCmp(Composite parent, String value) {
139 Composite valueCmp = new Composite(parent, SWT.NO_FOCUS);
140 GridLayout layout = ConnectUiUtils.noSpaceGridLayout(2);
141 layout.horizontalSpacing = 3;
142 valueCmp.setLayout(layout);
143 Label valueLbl = new Label(valueCmp, SWT.NONE);
144 valueLbl.setText(" " + value);
145 addDeleteButton(valueCmp, value);
146 return valueCmp;
147 }
148
149 private void addDeleteButton(Composite parent, String value) {
150 final Button deleteBtn = new Button(parent, SWT.FLAT);
151 CmsUtils.style(deleteBtn, ConnectUiStyles.SMALL_DELETE_BTN);
152 deleteBtn.setLayoutData(new GridData(8, 8));
153 deleteBtn.addSelectionListener(new SelectionAdapter() {
154 private static final long serialVersionUID = 1L;
155
156 @Override
157 public void widgetSelected(final SelectionEvent event) {
158 chosenValues.remove(value);
159 Composite lineCmp = parent.getParent();
160 parent.dispose();
161 lineCmp.layout(true, true);
162 }
163 });
164 }
165
166 private class TagLikeDropDown extends ConnectAbstractDropDown {
167
168 public TagLikeDropDown(Text text) {
169 super(text);
170 init();
171 }
172
173 @Override
174 protected List<String> getFilteredValues(String filter) {
175 return TagListWithDropDownComposite.this.getFilteredValues(filter);
176 }
177 }
178
179
180
181
182 abstract protected List<String> getFilteredValues(String filter);
183
184
185
186
187 protected boolean tagExists(String tagKey) {
188 List<String> existings = getFilteredValues(null);
189 return existings.contains(tagKey);
190 }
191
192
193 protected String getTagKey(Node tagDefinition) {
194 return ConnectJcrUtils.get(tagDefinition, Property.JCR_TITLE);
195 }
196
197
198 protected String getEncodedTagValue(String tagKey) {
199 return tagKey;
200 }
201
202
203
204
205
206 protected String getDecodedTagValue(String tagValue) {
207 return tagValue;
208 }
209
210
211
212
213
214 protected void callOpenEditor(String tagKey) {
215 }
216 }