]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/parts/UsersTable.java
Add some utilities to eclipse UI Utils to ease UI implementation.
[lgpl/argeo-commons.git] / org.argeo.eclipse.ui / src / org / argeo / eclipse / ui / parts / UsersTable.java
1 package org.argeo.eclipse.ui.parts;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.Node;
7 import javax.jcr.NodeIterator;
8 import javax.jcr.Property;
9 import javax.jcr.PropertyType;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.query.QueryManager;
13 import javax.jcr.query.QueryResult;
14 import javax.jcr.query.qom.Constraint;
15 import javax.jcr.query.qom.Ordering;
16 import javax.jcr.query.qom.QueryObjectModel;
17 import javax.jcr.query.qom.QueryObjectModelFactory;
18 import javax.jcr.query.qom.Selector;
19 import javax.jcr.query.qom.StaticOperand;
20
21 import org.argeo.ArgeoException;
22 import org.argeo.eclipse.ui.EclipseUiUtils;
23 import org.argeo.eclipse.ui.jcr.JcrUiUtils;
24 import org.argeo.eclipse.ui.jcr.lists.ColumnDefinition;
25 import org.argeo.eclipse.ui.jcr.lists.NodeViewerComparator;
26 import org.argeo.eclipse.ui.jcr.lists.SimpleJcrNodeLabelProvider;
27 import org.argeo.eclipse.ui.utils.ViewerUtils;
28 import org.argeo.jcr.ArgeoNames;
29 import org.argeo.jcr.ArgeoTypes;
30 import org.argeo.jcr.JcrUtils;
31 import org.eclipse.jface.viewers.CheckboxTableViewer;
32 import org.eclipse.jface.viewers.ColumnLabelProvider;
33 import org.eclipse.jface.viewers.IStructuredContentProvider;
34 import org.eclipse.jface.viewers.TableViewer;
35 import org.eclipse.jface.viewers.TableViewerColumn;
36 import org.eclipse.jface.viewers.Viewer;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.events.ModifyEvent;
39 import org.eclipse.swt.events.ModifyListener;
40 import org.eclipse.swt.events.SelectionAdapter;
41 import org.eclipse.swt.events.SelectionEvent;
42 import org.eclipse.swt.graphics.Font;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Table;
47 import org.eclipse.swt.widgets.Text;
48
49 public class UsersTable extends Composite implements ArgeoNames {
50 // private final static Log log =
51 // LogFactory.getLog(UserTableComposite.class);
52
53 private static final long serialVersionUID = -7385959046279360420L;
54
55 private Session session;
56
57 private boolean hasFilter;
58 private boolean hasSelectionColumn;
59 private int tableStyle;
60
61 private TableViewer usersViewer;
62 private Text filterTxt;
63 private String filterHelpMsg = "Type filter criterion "
64 + "separated by a space";
65
66 private Font italic;
67 private Font bold;
68
69 /** Overwrite to display other columns */
70 public List<ColumnDefinition> getColumnsDef() {
71 List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
72
73 // User ID
74 columnDefs.add(new ColumnDefinition(null, ARGEO_USER_ID,
75 PropertyType.STRING, "User ID", 100));
76 // Displayed name
77 columnDefs.add(new ColumnDefinition(null, Property.JCR_TITLE,
78 PropertyType.STRING, "Name", 150));
79
80 // E-mail
81 columnDefs.add(new ColumnDefinition(null, ARGEO_PRIMARY_EMAIL,
82 PropertyType.STRING, "E-mail", 150));
83
84 // Description
85 columnDefs.add(new ColumnDefinition(null, Property.JCR_DESCRIPTION,
86 PropertyType.STRING, "Description", 200));
87
88 return columnDefs;
89 }
90
91 public UsersTable(Composite parent, int style, Session session) {
92 super(parent, SWT.NO_FOCUS);
93 this.tableStyle = style;
94 this.session = session;
95 }
96
97 /**
98 *
99 * @param addFilter
100 * choose to add a field to filter results or not
101 * @param addSelection
102 * choose to add a column to select some of the displayed results
103 * or not
104 */
105 public void populate(boolean addFilter, boolean addSelection) {
106 // initialization
107 Composite parent = this;
108 italic = EclipseUiUtils.getItalicFont(parent);
109 bold = EclipseUiUtils.getBoldFont(parent);
110 hasFilter = addFilter;
111 hasSelectionColumn = addSelection;
112
113 // Main Layout
114 GridLayout layout = EclipseUiUtils.noSpaceGridLayout();
115 layout.verticalSpacing = 5;
116 this.setLayout(layout);
117 if (hasFilter)
118 createFilterPart(parent);
119 usersViewer = createTableViewer(parent);
120 // EclipseUiSpecificUtils.enableToolTipSupport(usersViewer);
121 usersViewer.setContentProvider(new UsersContentProvider());
122 refreshFilteredList();
123 }
124
125 public List<Node> getSelectedUsers() {
126 if (hasSelectionColumn) {
127 Object[] elements = ((CheckboxTableViewer) usersViewer)
128 .getCheckedElements();
129
130 List<Node> result = new ArrayList<Node>();
131 for (Object obj : elements) {
132 result.add((Node) obj);
133 }
134 return result;
135 } else
136 throw new ArgeoException("Unvalid request: no selection column "
137 + "has been created for the current table");
138 }
139
140 /** Returns the User table viewer, typically to add doubleclick listener */
141 public TableViewer getTableViewer() {
142 return usersViewer;
143 }
144
145 /** Returns filter String or null */
146 protected String getFilterString() {
147 return hasFilter ? filterTxt.getText() : null;
148 }
149
150 private TableViewer createTableViewer(final Composite parent) {
151 int style = tableStyle | SWT.H_SCROLL | SWT.V_SCROLL;
152 if (hasSelectionColumn)
153 style = style | SWT.CHECK;
154
155 Table table = new Table(parent, style);
156 table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
157
158 TableViewer viewer;
159 if (hasSelectionColumn)
160 viewer = new CheckboxTableViewer(table);
161 else
162 viewer = new TableViewer(table);
163 table.setLinesVisible(true);
164 table.setHeaderVisible(true);
165
166 TableViewerColumn column;
167 int offset = 0;
168 if (hasSelectionColumn) {
169 offset = 1;
170 column = ViewerUtils.createTableViewerColumn(viewer, "", SWT.NONE,
171 25);
172 column.setLabelProvider(new ColumnLabelProvider() {
173 private static final long serialVersionUID = 1L;
174
175 @Override
176 public String getText(Object element) {
177 return null;
178 }
179 });
180 SelectionAdapter selectionAdapter = new SelectionAdapter() {
181 private static final long serialVersionUID = 1L;
182
183 boolean allSelected = false;
184
185 @Override
186 public void widgetSelected(SelectionEvent e) {
187 allSelected = !allSelected;
188 ((CheckboxTableViewer) usersViewer)
189 .setAllChecked(allSelected);
190 }
191 };
192 column.getColumn().addSelectionListener(selectionAdapter);
193 }
194
195 // Create other columns
196 List<ColumnDefinition> colDefs = getColumnsDef();
197
198 NodeViewerComparator comparator = new NodeViewerComparator();
199 int i = offset;
200 for (ColumnDefinition colDef : colDefs) {
201 column = ViewerUtils.createTableViewerColumn(viewer,
202 colDef.getHeaderLabel(), SWT.NONE, colDef.getColumnSize());
203 column.setLabelProvider(new CLProvider(colDef.getPropertyName()));
204 column.getColumn().addSelectionListener(
205 JcrUiUtils.getNodeSelectionAdapter(i,
206 colDef.getPropertyType(), colDef.getPropertyName(),
207 comparator, viewer));
208 i++;
209 }
210
211 // IMPORTANT: initialize comparator before setting it
212 ColumnDefinition firstCol = colDefs.get(0);
213 comparator.setColumn(firstCol.getPropertyType(),
214 firstCol.getPropertyName());
215 viewer.setComparator(comparator);
216
217 return viewer;
218 }
219
220 private class CLProvider extends SimpleJcrNodeLabelProvider {
221
222 private static final long serialVersionUID = 1L;
223
224 public CLProvider(String propertyName) {
225 super(propertyName);
226 }
227
228 public String getToolTipText(Object element) {
229 return getText(element);
230 }
231
232 @Override
233 public Font getFont(Object elem) {
234 // self
235 String username = getProperty(elem, ARGEO_USER_ID);
236 if (username.equals(session.getUserID()))
237 return bold;
238 // disabled
239 try {
240 Node userProfile = (Node) elem;
241 if (!userProfile.getProperty(ARGEO_ENABLED).getBoolean())
242 return italic;
243 else
244 return null;
245 } catch (RepositoryException e) {
246 throw new ArgeoException("Cannot get font for " + username, e);
247 }
248 }
249 }
250
251 @Override
252 public boolean setFocus() {
253 usersViewer.getTable().setFocus();
254 return true;
255 }
256
257 @Override
258 public void dispose() {
259 super.dispose();
260 }
261
262 public void refresh() {
263 refreshFilteredList();
264 }
265
266 private String getProperty(Object element, String name) {
267 try {
268 Node userProfile = (Node) element;
269 return userProfile.hasProperty(name) ? userProfile
270 .getProperty(name).getString() : "";
271 } catch (RepositoryException e) {
272 throw new ArgeoException("Cannot get property " + name, e);
273 }
274 }
275
276 private class UsersContentProvider implements IStructuredContentProvider {
277 private static final long serialVersionUID = 1L;
278
279 public Object[] getElements(Object inputElement) {
280 return (Object[]) inputElement;
281 }
282
283 public void dispose() {
284 }
285
286 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
287 }
288 }
289
290 /* MANAGE FILTER */
291 private void createFilterPart(Composite parent) {
292 // Text Area for the filter
293 filterTxt = new Text(parent, SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH
294 | SWT.ICON_CANCEL);
295 filterTxt.setMessage(filterHelpMsg);
296 filterTxt.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL
297 | 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 * Refresh the user list: caller might overwrite in order to display a
309 * subset of all users, typically to remove current user from the list
310 */
311 protected void refreshFilteredList() {
312 List<Node> nodes;
313 try {
314 nodes = JcrUtils.nodeIteratorToList(listFilteredElements(session,
315 hasFilter ? filterTxt.getText() : null));
316 usersViewer.setInput(nodes.toArray());
317 } catch (RepositoryException e) {
318 throw new ArgeoException("Unable to list users", e);
319 }
320 }
321
322 /**
323 * Build repository request : caller might overwrite in order to display a
324 * subset of all users
325 */
326 protected NodeIterator listFilteredElements(Session session, String filter)
327 throws RepositoryException {
328 QueryManager queryManager = session.getWorkspace().getQueryManager();
329 QueryObjectModelFactory factory = queryManager.getQOMFactory();
330
331 Selector source = factory.selector(ArgeoTypes.ARGEO_USER_PROFILE,
332 ArgeoTypes.ARGEO_USER_PROFILE);
333
334 // Dynamically build constraint depending on the filter String
335 Constraint defaultC = null;
336 if (filter != null && !"".equals(filter.trim())) {
337 String[] strs = filter.trim().split(" ");
338 for (String token : strs) {
339 StaticOperand so = factory.literal(session.getValueFactory()
340 .createValue("*" + token + "*"));
341 Constraint currC = factory.fullTextSearch(
342 source.getSelectorName(), null, so);
343 if (defaultC == null)
344 defaultC = currC;
345 else
346 defaultC = factory.and(defaultC, currC);
347 }
348 }
349
350 Ordering order = factory.ascending(factory.propertyValue(
351 source.getSelectorName(), ARGEO_USER_ID));
352 Ordering[] orderings = { order };
353
354 QueryObjectModel query = factory.createQuery(source, defaultC,
355 orderings, null);
356
357 QueryResult result = query.execute();
358 return result.getNodes();
359 }
360 }