]> git.argeo.org Git - gpl/argeo-suite.git/blob - RecentItems.java
d481f2b0eda0a278ce5963017d11419a5978f149
[gpl/argeo-suite.git] / RecentItems.java
1 package org.argeo.suite.ui;
2
3 import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
4
5 import java.util.List;
6 import java.util.Map;
7
8 import javax.jcr.Node;
9 import javax.jcr.NodeIterator;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12 import javax.jcr.observation.Event;
13 import javax.jcr.observation.EventIterator;
14 import javax.jcr.observation.EventListener;
15 import javax.jcr.query.Query;
16 import javax.jcr.query.QueryResult;
17
18 import org.argeo.cms.ui.CmsTheme;
19 import org.argeo.cms.ui.CmsUiProvider;
20 import org.argeo.cms.ui.util.CmsUiUtils;
21 import org.argeo.connect.ui.ConnectUiConstants;
22 import org.argeo.connect.ui.util.BasicNodeListContentProvider;
23 import org.argeo.connect.ui.widgets.DelayedText;
24 import org.argeo.connect.util.XPathUtils;
25 import org.argeo.eclipse.ui.EclipseUiUtils;
26 import org.argeo.entity.EntityNames;
27 import org.argeo.entity.EntityTypes;
28 import org.argeo.jcr.JcrUtils;
29 import org.eclipse.jface.layout.TableColumnLayout;
30 import org.eclipse.jface.viewers.ColumnLabelProvider;
31 import org.eclipse.jface.viewers.ColumnWeightData;
32 import org.eclipse.jface.viewers.ILabelProvider;
33 import org.eclipse.jface.viewers.ISelectionChangedListener;
34 import org.eclipse.jface.viewers.IStructuredSelection;
35 import org.eclipse.jface.viewers.SelectionChangedEvent;
36 import org.eclipse.jface.viewers.TableViewer;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.events.KeyEvent;
39 import org.eclipse.swt.events.KeyListener;
40 import org.eclipse.swt.events.ModifyEvent;
41 import org.eclipse.swt.events.ModifyListener;
42 import org.eclipse.swt.layout.GridData;
43 import org.eclipse.swt.layout.GridLayout;
44 import org.eclipse.swt.widgets.Composite;
45 import org.eclipse.swt.widgets.Control;
46 import org.eclipse.swt.widgets.Label;
47 import org.eclipse.swt.widgets.Table;
48 import org.eclipse.swt.widgets.TableColumn;
49 import org.eclipse.swt.widgets.Text;
50
51 /** List recent items. */
52 public class RecentItems implements CmsUiProvider {
53 int SEARCH_TEXT_DELAY = 800;
54 private CmsTheme theme;
55
56 private String entityType;
57
58 @Override
59 public Control createUi(Composite parent, Node context) throws RepositoryException {
60 theme = CmsTheme.getCmsTheme(parent);
61 parent.setLayout(new GridLayout());
62
63 // Composite top = new Composite(parent, SWT.NONE);
64 // top.setLayoutData(CmsUiUtils.fillWidth());
65 // top.setLayout(new GridLayout(2, false));
66
67 Label lbl = new Label(parent, SWT.NONE);
68 // search.setImage(SuiteIcon.search.getSmallIcon(theme));
69 lbl.setText(SuiteMsg.recentItems.lead());
70 CmsUiUtils.style(lbl, SuiteStyle.recentItems);
71
72 if (context == null)
73 return null;
74 SingleEntityViewer entityViewer = new SingleEntityViewer(parent, SWT.NONE, context.getSession());
75 entityViewer.setLayoutData(CmsUiUtils.fillAll());
76 entityViewer.createUi();
77 return entityViewer;
78
79 }
80
81 public void init(Map<String, String> properties) {
82 entityType = properties.get(EntityNames.ENTITY_TYPE);
83 }
84
85 class SingleEntityViewer extends Composite {
86 Text filterTxt;
87 TableViewer entityViewer;
88 Session session;
89
90 public SingleEntityViewer(Composite parent, int style, Session session) {
91 super(parent, style);
92 this.session = session;
93 }
94
95 public void createUi() {
96 // MainLayout
97 setLayout(new GridLayout());
98 addFilterPanel(this);
99 entityViewer = createListPart(this, new SingleEntityLabelProvider());
100 refreshFilteredList();
101
102 try {
103 String[] nodeTypes = entityType != null && entityType.contains(":") ? new String[] { entityType }
104 : null;
105 session.getWorkspace().getObservationManager().addEventListener(new EventListener() {
106
107 @Override
108 public void onEvent(EventIterator events) {
109 getDisplay().asyncExec(() -> refreshFilteredList());
110 }
111 }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true,
112 null, nodeTypes, false);
113 } catch (RepositoryException e) {
114 throw new IllegalStateException("Cannot add JCR observer", e);
115 }
116
117 }
118
119 private void addFilterPanel(Composite parent) {
120 // Use a delayed text: the query won't be done until the user stop
121 // typing for 800ms
122 int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL;
123 DelayedText delayedText = new DelayedText(parent, style, ConnectUiConstants.SEARCH_TEXT_DELAY);
124 filterTxt = delayedText.getText();
125 filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
126
127 // final ServerPushSession pushSession = new ServerPushSession();
128 delayedText.addDelayedModifyListener(null, new ModifyListener() {
129 private static final long serialVersionUID = 5003010530960334977L;
130
131 public void modifyText(ModifyEvent event) {
132 delayedText.getText().getDisplay().asyncExec(new Runnable() {
133 @Override
134 public void run() {
135 refreshFilteredList();
136 }
137 });
138 // pushSession.stop();
139 }
140 });
141
142 // Jump to the first item of the list using the down arrow
143 filterTxt.addKeyListener(new KeyListener() {
144 private static final long serialVersionUID = -4523394262771183968L;
145
146 @Override
147 public void keyReleased(KeyEvent e) {
148 }
149
150 @Override
151 public void keyPressed(KeyEvent e) {
152 // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
153 // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
154 if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) {
155 // Object first = entityViewer.getElementAt(0);
156 // if (first != null) {
157 // entityViewer.getTable().setFocus();
158 // entityViewer.setSelection(new StructuredSelection(first), true);
159 // }
160 e.doit = false;
161 }
162 }
163 });
164
165 addDisposeListener((e) -> {
166 delayedText.close();
167 });
168 }
169
170 protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) {
171 parent.setLayout(new GridLayout());
172
173 Composite tableComposite = new Composite(parent, SWT.NONE);
174 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL
175 | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
176 tableComposite.setLayoutData(gd);
177
178 TableViewer v = new TableViewer(tableComposite);
179 v.setLabelProvider(labelProvider);
180
181 TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
182 TableColumnLayout tableColumnLayout = new TableColumnLayout();
183 tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
184 tableComposite.setLayout(tableColumnLayout);
185
186 // Corresponding table & style
187 Table table = v.getTable();
188 table.setLinesVisible(true);
189 table.setHeaderVisible(false);
190 CmsUiUtils.markup(table);
191 CmsUiUtils.setItemHeight(table, 26);
192
193 v.setContentProvider(new BasicNodeListContentProvider());
194 // v.addDoubleClickListener(new
195 // JcrViewerDClickListener(systemWorkbenchService));
196 v.addSelectionChangedListener(new ISelectionChangedListener() {
197 public void selectionChanged(SelectionChangedEvent event) {
198 IStructuredSelection selection = (IStructuredSelection) event.getSelection();
199 List<?> lst = selection.toList();
200 // if (lst != null && !lst.isEmpty())
201 // selectionService.setSelection(selection.toList());
202 // else
203 // selectionService.setSelection(null);
204 }
205 });
206 return v;
207 }
208
209 // public void dispose() {
210 // JcrUtils.logoutQuietly(session);
211 // }
212
213 public boolean setFocus() {
214 refreshFilteredList();
215 return super.setFocus();
216 // filterTxt.setFocus();
217 }
218
219 public void forceRefresh(Object object) {
220 refreshFilteredList();
221 }
222
223 protected void refreshFilteredList() {
224 try {
225 String filter = filterTxt.getText();
226 // Prevents the query on the full repository
227 // if (isEmpty(filter)) {
228 // entityViewer.setInput(null);
229 // return;
230 // }
231
232 // XPATH Query
233 String xpathQueryStr;
234 if (entityType != null)
235 xpathQueryStr = entityType.contains(":") ? "//element(*, " + entityType + ")"
236 : "//element(*, " + EntityTypes.ENTITY_ENTITY + ")[@entity:type='" + entityType + "']";
237 else
238 xpathQueryStr = "//element(*, " + EntityTypes.ENTITY_ENTITY + ")";
239 // String xpathQueryStr = "//element(*, " + ConnectTypes.CONNECT_ENTITY + ")";
240 String xpathFilter = XPathUtils.getFreeTextConstraint(filter);
241 if (notEmpty(xpathFilter))
242 xpathQueryStr += "[" + xpathFilter + "]";
243
244 long begin = System.currentTimeMillis();
245 // session.refresh(false);
246 Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr);
247
248 xpathQuery.setLimit(ConnectUiConstants.SEARCH_DEFAULT_LIMIT);
249 QueryResult result = xpathQuery.execute();
250
251 NodeIterator nit = result.getNodes();
252 entityViewer.setInput(JcrUtils.nodeIteratorToList(nit));
253 // if (log.isTraceEnabled()) {
254 // long end = System.currentTimeMillis();
255 // log.trace("Quick Search - Found: " + nit.getSize() + " in " + (end - begin)
256 // + " ms by executing XPath query (" + xpathQueryStr + ").");
257 // }
258 } catch (RepositoryException e) {
259 throw new IllegalStateException("Unable to list entities", e);
260 }
261 }
262
263 class SingleEntityLabelProvider extends ColumnLabelProvider {
264
265 }
266 }
267 }