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