]> git.argeo.org Git - gpl/argeo-suite.git/blob - org.argeo.suite.e4/src/org/argeo/suite/e4/parts/QuickSearchView.java
Introduce Argeo WM
[gpl/argeo-suite.git] / org.argeo.suite.e4 / src / org / argeo / suite / e4 / parts / QuickSearchView.java
1 package org.argeo.suite.e4.parts;
2
3 import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty;
4
5 import javax.annotation.PostConstruct;
6 import javax.annotation.PreDestroy;
7 import javax.inject.Inject;
8 import javax.jcr.NodeIterator;
9 import javax.jcr.Repository;
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.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.activities.ActivitiesService;
21 import org.argeo.cms.util.CmsUtils;
22 import org.argeo.connect.ConnectException;
23 import org.argeo.connect.ConnectTypes;
24 import org.argeo.connect.resources.ResourcesService;
25 import org.argeo.connect.ui.ConnectUiConstants;
26 import org.argeo.connect.ui.Refreshable;
27 import org.argeo.connect.ui.SystemWorkbenchService;
28 import org.argeo.connect.ui.util.BasicNodeListContentProvider;
29 import org.argeo.connect.ui.util.JcrViewerDClickListener;
30 import org.argeo.connect.ui.widgets.DelayedText;
31 import org.argeo.connect.util.ConnectJcrUtils;
32 import org.argeo.connect.util.XPathUtils;
33 import org.argeo.eclipse.ui.EclipseUiUtils;
34 import org.argeo.jcr.JcrUtils;
35 import org.argeo.people.PeopleService;
36 import org.eclipse.jface.layout.TableColumnLayout;
37 import org.eclipse.jface.viewers.ColumnWeightData;
38 import org.eclipse.jface.viewers.ILabelProvider;
39 import org.eclipse.jface.viewers.StructuredSelection;
40 import org.eclipse.jface.viewers.TableViewer;
41 import org.eclipse.swt.SWT;
42 import org.eclipse.swt.events.KeyEvent;
43 import org.eclipse.swt.events.KeyListener;
44 import org.eclipse.swt.events.ModifyEvent;
45 import org.eclipse.swt.events.ModifyListener;
46 import org.eclipse.swt.layout.GridData;
47 import org.eclipse.swt.layout.GridLayout;
48 import org.eclipse.swt.widgets.Composite;
49 import org.eclipse.swt.widgets.Table;
50 import org.eclipse.swt.widgets.TableColumn;
51 import org.eclipse.swt.widgets.Text;
52
53 /** A table with a quick search field. */
54 public class QuickSearchView implements Refreshable {
55 private final static Log log = LogFactory.getLog(QuickSearchView.class);
56 // public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView";
57
58 /* DEPENDENCY INJECTION */
59 @Inject
60 private Repository repository;
61 @Inject
62 private ResourcesService resourcesService;
63 @Inject
64 private ActivitiesService activitiesService;
65 @Inject
66 private PeopleService peopleService;
67 @Inject
68 private SystemWorkbenchService systemWorkbenchService;
69
70 // This page widgets
71 private TableViewer entityViewer;
72 private Text filterTxt;
73
74 private Session session;
75
76 // @Override
77 // public void init(IViewSite site) throws PartInitException {
78 // super.init(site);
79 // }
80
81 @PostConstruct
82 public void createPartControl(Composite parent) {
83 session = ConnectJcrUtils.login(repository);
84 // MainLayout
85 parent.setLayout(new GridLayout());
86 addFilterPanel(parent);
87 entityViewer = createListPart(parent, new EntitySingleColumnLabelProvider(resourcesService, activitiesService,
88 peopleService, systemWorkbenchService));
89 refreshFilteredList();
90
91 try {
92 session.getWorkspace().getObservationManager().addEventListener(new EventListener() {
93
94 @Override
95 public void onEvent(EventIterator events) {
96 parent.getDisplay().asyncExec(() -> refreshFilteredList());
97 }
98 }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, null,
99 new String[] { ConnectTypes.CONNECT_ENTITY }, true);
100 } catch (RepositoryException e) {
101 throw new ConnectException("Cannot add JCR observer", e);
102 }
103
104 }
105
106 private void addFilterPanel(Composite parent) {
107 // Use a delayed text: the query won't be done until the user stop
108 // typing for 800ms
109 int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL;
110 DelayedText delayedText = new DelayedText(parent, style, ConnectUiConstants.SEARCH_TEXT_DELAY);
111 filterTxt = delayedText.getText();
112 filterTxt.setLayoutData(EclipseUiUtils.fillWidth());
113
114 // final ServerPushSession pushSession = new ServerPushSession();
115 delayedText.addDelayedModifyListener(null, new ModifyListener() {
116 private static final long serialVersionUID = 5003010530960334977L;
117
118 public void modifyText(ModifyEvent event) {
119 delayedText.getText().getDisplay().asyncExec(new Runnable() {
120 @Override
121 public void run() {
122 refreshFilteredList();
123 }
124 });
125 // pushSession.stop();
126 }
127 });
128
129 // Jump to the first item of the list using the down arrow
130 filterTxt.addKeyListener(new KeyListener() {
131 private static final long serialVersionUID = -4523394262771183968L;
132
133 @Override
134 public void keyReleased(KeyEvent e) {
135 }
136
137 @Override
138 public void keyPressed(KeyEvent e) {
139 // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0;
140 // boolean altPressed = (e.stateMask & SWT.ALT) != 0;
141 if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) {
142 Object first = entityViewer.getElementAt(0);
143 if (first != null) {
144 entityViewer.getTable().setFocus();
145 entityViewer.setSelection(new StructuredSelection(first), true);
146 }
147 e.doit = false;
148 }
149 }
150 });
151 }
152
153 protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) {
154 parent.setLayout(new GridLayout());
155
156 Composite tableComposite = new Composite(parent, SWT.NONE);
157 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL
158 | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
159 tableComposite.setLayoutData(gd);
160
161 TableViewer v = new TableViewer(tableComposite);
162 v.setLabelProvider(labelProvider);
163
164 TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL);
165 TableColumnLayout tableColumnLayout = new TableColumnLayout();
166 tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85));
167 tableComposite.setLayout(tableColumnLayout);
168
169 // Corresponding table & style
170 Table table = v.getTable();
171 table.setLinesVisible(true);
172 table.setHeaderVisible(false);
173 CmsUtils.markup(table);
174 CmsUtils.setItemHeight(table, 26);
175
176 v.setContentProvider(new BasicNodeListContentProvider());
177 v.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService));
178 return v;
179 }
180
181 @PreDestroy
182 public void dispose() {
183 JcrUtils.logoutQuietly(session);
184 }
185
186
187 public void setFocus() {
188 refreshFilteredList();
189 filterTxt.setFocus();
190 }
191
192 @Override
193 public void forceRefresh(Object object) {
194 refreshFilteredList();
195 }
196
197 protected void refreshFilteredList() {
198 try {
199 String filter = filterTxt.getText();
200 // Prevents the query on the full repository
201 // if (isEmpty(filter)) {
202 // entityViewer.setInput(null);
203 // return;
204 // }
205
206 // XPATH Query
207 String xpathQueryStr = "//element(*, " + ConnectTypes.CONNECT_ENTITY + ")";
208 String xpathFilter = XPathUtils.getFreeTextConstraint(filter);
209 if (notEmpty(xpathFilter))
210 xpathQueryStr += "[" + xpathFilter + "]";
211
212 // boolean doOrder = orderResultsBtn != null
213 // && !(orderResultsBtn.isDisposed())
214 // && orderResultsBtn.getSelection();
215 // if (doOrder) {
216 // xpathQueryStr += " order by jcr:title";
217 // }
218
219 long begin = System.currentTimeMillis();
220 Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr);
221
222 xpathQuery.setLimit(ConnectUiConstants.SEARCH_DEFAULT_LIMIT);
223 QueryResult result = xpathQuery.execute();
224
225 NodeIterator nit = result.getNodes();
226 entityViewer.setInput(JcrUtils.nodeIteratorToList(nit));
227 if (log.isDebugEnabled()) {
228 long end = System.currentTimeMillis();
229 log.debug("Quick Search - Found: " + nit.getSize() + " in " + (end - begin)
230 + " ms by executing XPath query (" + xpathQueryStr + ").");
231 }
232 } catch (RepositoryException e) {
233 throw new ConnectException("Unable to list entities", e);
234 }
235 }
236
237 // public void setRepository(Repository repository) {
238 // this.repository = repository;
239 // }
240 //
241 // public void setResourcesService(ResourcesService resourcesService) {
242 // this.resourcesService = resourcesService;
243 // }
244 //
245 // public void setActivitiesService(ActivitiesService activitiesService) {
246 // this.activitiesService = activitiesService;
247 // }
248 //
249 // public void setPeopleService(PeopleService peopleService) {
250 // this.peopleService = peopleService;
251 // }
252 //
253 // public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) {
254 // this.systemWorkbenchService = systemWorkbenchService;
255 // }
256 }