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