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