1 package org.argeo.people.ui.composites;
2
3 import static org.argeo.eclipse.ui.jcr.JcrUiUtils.getNodeSelectionAdapter;
4
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import javax.jcr.Node;
9 import javax.jcr.NodeIterator;
10 import javax.jcr.Property;
11 import javax.jcr.PropertyType;
12 import javax.jcr.RepositoryException;
13 import javax.jcr.Session;
14 import javax.jcr.query.Query;
15 import javax.jcr.query.QueryResult;
16
17 import org.argeo.connect.ConnectException;
18 import org.argeo.connect.ConnectTypes;
19 import org.argeo.connect.util.XPathUtils;
20 import org.argeo.eclipse.ui.EclipseUiUtils;
21 import org.argeo.eclipse.ui.jcr.lists.JcrColumnDefinition;
22 import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
23 import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
24 import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils;
25 import org.argeo.eclipse.ui.utils.ViewerUtils;
26 import org.argeo.jcr.JcrUtils;
27 import org.argeo.people.ui.PeopleMsg;
28 import org.eclipse.jface.viewers.CheckboxTableViewer;
29 import org.eclipse.jface.viewers.ColumnLabelProvider;
30 import org.eclipse.jface.viewers.IStructuredContentProvider;
31 import org.eclipse.jface.viewers.TableViewer;
32 import org.eclipse.jface.viewers.TableViewerColumn;
33 import org.eclipse.jface.viewers.Viewer;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.ModifyEvent;
36 import org.eclipse.swt.events.ModifyListener;
37 import org.eclipse.swt.events.SelectionAdapter;
38 import org.eclipse.swt.events.SelectionEvent;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Composite;
42 import org.eclipse.swt.widgets.Table;
43 import org.eclipse.swt.widgets.Text;
44
45
46 public class FilteredOrderableEntityTable extends Composite {
47
48
49 private static final long serialVersionUID = 1262369448445021926L;
50
51 private TableViewer entityViewer;
52 private Text filterTxt;
53 private final static String FILTER_HELP_MSG = PeopleMsg.filterHelp.lead();
54 private Session session;
55
56 private int tableStyle;
57
58 private boolean hasFilter = false;
59 private boolean hasSelectionColumn = false;
60 private List<JcrColumnDefinition> colDefs = new ArrayList<JcrColumnDefinition>();
61 {
62 colDefs.add(new JcrColumnDefinition(null, Property.JCR_TITLE, PropertyType.STRING, PeopleMsg.name.lead(), 300));
63 };
64 private String nodeType = ConnectTypes.CONNECT_ENTITY;
65
66 public List<JcrColumnDefinition> getColumnsDef() {
67 return colDefs;
68 }
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public FilteredOrderableEntityTable(Composite parent, int style, Session session) {
84 super(parent, SWT.NONE);
85 this.tableStyle = style;
86 this.session = session;
87 populate();
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101 public FilteredOrderableEntityTable(Composite parent, int style, Session session, boolean addFilter,
102 boolean addSelection) {
103 super(parent, SWT.NONE);
104 this.tableStyle = style;
105 this.session = session;
106 this.hasFilter = addFilter;
107 this.hasSelectionColumn = addSelection;
108 populate();
109 }
110
111
112
113
114
115
116
117
118
119 public FilteredOrderableEntityTable(Composite parent, int style, Session session,
120 List<JcrColumnDefinition> colDefs) {
121 super(parent, SWT.NONE);
122 this.tableStyle = style;
123 this.session = session;
124 this.colDefs = colDefs;
125 populate();
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public FilteredOrderableEntityTable(Composite parent, int style, Session session, String nodeType,
141 List<JcrColumnDefinition> colDefs, boolean addFilter, boolean addSelection) {
142 super(parent, SWT.NONE);
143 this.tableStyle = style;
144 this.session = session;
145 if (colDefs != null)
146 this.colDefs = colDefs;
147 if (nodeType != null)
148 this.nodeType = nodeType;
149 this.hasFilter = addFilter;
150 this.hasSelectionColumn = addSelection;
151 populate();
152 }
153
154 protected void populate() {
155
156 Composite parent = this;
157
158 GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
159 layout.verticalSpacing = 5;
160 this.setLayout(layout);
161 if (hasFilter)
162 createFilterPart(parent);
163 entityViewer = createTableViewer(parent);
164 EclipseUiSpecificUtils.enableToolTipSupport(entityViewer);
165 entityViewer.setContentProvider(new MyTableContentProvider());
166 refreshFilteredList();
167
168 if (hasFilter)
169 filterTxt.setFocus();
170 }
171
172 public List<Node> getSelectedEntities() {
173 if (hasSelectionColumn) {
174 Object[] elements = ((CheckboxTableViewer) entityViewer).getCheckedElements();
175
176 List<Node> result = new ArrayList<Node>();
177 for (Object obj : elements) {
178 result.add((Node) obj);
179 }
180 return result;
181 } else
182 throw new ConnectException("Unvalid request: no selection column has been created for the current table");
183 }
184
185
186 public TableViewer getTableViewer() {
187 return entityViewer;
188 }
189
190 private TableViewer createTableViewer(final Composite parent) {
191 if (hasSelectionColumn)
192 tableStyle = tableStyle | SWT.CHECK;
193
194 Table table = new Table(parent, tableStyle);
195 table.setLayoutData(EclipseUiUtils.fillAll());
196
197 TableViewer viewer;
198 if (hasSelectionColumn)
199 viewer = new CheckboxTableViewer(table);
200 else
201 viewer = new TableViewer(table);
202
203 table.setLinesVisible(true);
204 table.setHeaderVisible(true);
205
206 TableViewerColumn column;
207 int offset = 0;
208 if (hasSelectionColumn) {
209 offset = 1;
210 column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE, 25);
211 column.setLabelProvider(new ColumnLabelProvider() {
212 private static final long serialVersionUID = 1L;
213
214 @Override
215 public String getText(Object element) {
216 return null;
217 }
218 });
219 SelectionAdapter selectionAdapter = new SelectionAdapter() {
220 private static final long serialVersionUID = 1L;
221 boolean allSelected = false;
222
223 @Override
224 public void widgetSelected(SelectionEvent e) {
225 allSelected = !allSelected;
226 ((CheckboxTableViewer) entityViewer).setAllChecked(allSelected);
227 }
228 };
229 column.getColumn().addSelectionListener(selectionAdapter);
230 }
231
232 NodeViewerComparator comparator = new NodeViewerComparator();
233 int i = offset;
234 for (JcrColumnDefinition colDef : colDefs) {
235 column = ViewerUtils.createTableViewerColumn(viewer, colDef.getHeaderLabel(), SWT.NONE,
236 colDef.getColumnSize());
237 column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
238 column.getColumn().addSelectionListener(
239 getNodeSelectionAdapter(i, colDef.getPropertyType(), colDef.getPropertyName(), comparator, viewer));
240 i++;
241 }
242
243
244 JcrColumnDefinition firstCol = colDefs.get(0);
245 comparator.setColumn(firstCol.getPropertyType(), firstCol.getPropertyName());
246 viewer.setComparator(comparator);
247
248 return viewer;
249 }
250
251 private class CLProvider extends SimpleJcrNodeLabelProvider {
252 private static final long serialVersionUID = 1L;
253
254 public CLProvider(String propertyName) {
255 super(propertyName);
256 }
257
258 public String getToolTipText(Object element) {
259 return getText(element);
260 }
261 }
262
263 @Override
264 public boolean setFocus() {
265 entityViewer.getTable().setFocus();
266 return true;
267 }
268
269 @Override
270 public void dispose() {
271 super.dispose();
272 }
273
274 public void refresh() {
275 refreshFilteredList();
276 }
277
278 private class MyTableContentProvider implements IStructuredContentProvider {
279 private static final long serialVersionUID = 7164029504991808317L;
280
281 public Object[] getElements(Object inputElement) {
282 return (Object[]) inputElement;
283 }
284
285 public void dispose() {
286 }
287
288 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
289 }
290 }
291
292
293 private void createFilterPart(Composite parent) {
294
295 filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
296 filterTxt.setMessage(FILTER_HELP_MSG);
297 filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
298 filterTxt.addModifyListener(new ModifyListener() {
299 private static final long serialVersionUID = 1L;
300
301 public void modifyText(ModifyEvent event) {
302 refreshFilteredList();
303 }
304 });
305 }
306
307
308
309
310
311 protected void refreshFilteredList() {
312 List<Node> nodes;
313 try {
314 nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session, hasFilter ? filterTxt.getText() : null));
315 entityViewer.setInput(nodes.toArray());
316 } catch (RepositoryException e) {
317 throw new ConnectException("Unable to refresh list", e);
318 }
319 }
320
321
322
323
324
325 protected NodeIterator listFilteredElements(Session session, String filter) throws RepositoryException {
326 String xpathQueryStr = "//element(*, " + nodeType + ")";
327 String attrQuery = XPathUtils.getFreeTextConstraint(filter);
328 if (EclipseUiUtils.notEmpty(attrQuery))
329 xpathQueryStr += "[" + attrQuery + "]";
330 xpathQueryStr += " order by @" + Property.JCR_TITLE;
331 Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr);
332 xpathQuery.setLimit(100);
333 QueryResult result = xpathQuery.execute();
334 return result.getNodes();
335 }
336 }