1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.view;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Date;
\r
16 import java.util.HashMap;
\r
17 import java.util.HashSet;
\r
18 import java.util.List;
\r
19 import java.util.Map;
\r
20 import java.util.Set;
\r
22 import org.eclipse.core.runtime.Assert;
\r
23 import org.eclipse.core.runtime.IProgressMonitor;
\r
24 import org.eclipse.core.runtime.IStatus;
\r
25 import org.eclipse.core.runtime.Status;
\r
26 import org.eclipse.core.runtime.SubMonitor;
\r
27 import org.eclipse.core.runtime.jobs.Job;
\r
28 import org.eclipse.jface.action.IStatusLineManager;
\r
29 import org.eclipse.jface.layout.GridDataFactory;
\r
30 import org.eclipse.jface.resource.ColorDescriptor;
\r
31 import org.eclipse.jface.resource.JFaceResources;
\r
32 import org.eclipse.jface.resource.LocalResourceManager;
\r
33 import org.eclipse.nebula.widgets.cdatetime.CDT;
\r
34 import org.eclipse.nebula.widgets.cdatetime.CDateTime;
\r
35 import org.eclipse.nebula.widgets.nattable.NatTable;
\r
36 import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
\r
37 import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
\r
38 import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
\r
39 import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
\r
40 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultBodyDataProvider;
\r
41 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
\r
42 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
\r
43 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
\r
44 import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
\r
45 import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
\r
46 import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
\r
47 import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
\r
48 import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
\r
49 import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
\r
50 import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
\r
51 import org.eclipse.nebula.widgets.nattable.layer.ILayer;
\r
52 import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer;
\r
53 import org.eclipse.nebula.widgets.nattable.resize.action.AutoResizeColumnAction;
\r
54 import org.eclipse.nebula.widgets.nattable.resize.action.ColumnResizeCursorAction;
\r
55 import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEventMatcher;
\r
56 import org.eclipse.nebula.widgets.nattable.resize.mode.ColumnResizeDragMode;
\r
57 import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
\r
58 import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionStyleConfiguration;
\r
59 import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
\r
60 import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
\r
61 import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum;
\r
62 import org.eclipse.nebula.widgets.nattable.ui.action.ClearCursorAction;
\r
63 import org.eclipse.nebula.widgets.nattable.ui.action.NoOpMouseAction;
\r
64 import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
\r
65 import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
\r
66 import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
\r
67 import org.eclipse.swt.SWT;
\r
68 import org.eclipse.swt.dnd.DND;
\r
69 import org.eclipse.swt.dnd.DropTarget;
\r
70 import org.eclipse.swt.dnd.DropTargetAdapter;
\r
71 import org.eclipse.swt.dnd.DropTargetEvent;
\r
72 import org.eclipse.swt.dnd.TextTransfer;
\r
73 import org.eclipse.swt.dnd.Transfer;
\r
74 import org.eclipse.swt.events.ModifyEvent;
\r
75 import org.eclipse.swt.events.ModifyListener;
\r
76 import org.eclipse.swt.events.SelectionEvent;
\r
77 import org.eclipse.swt.events.SelectionListener;
\r
78 import org.eclipse.swt.graphics.Color;
\r
79 import org.eclipse.swt.graphics.RGB;
\r
80 import org.eclipse.swt.layout.GridData;
\r
81 import org.eclipse.swt.layout.GridLayout;
\r
82 import org.eclipse.swt.widgets.Composite;
\r
83 import org.eclipse.swt.widgets.Display;
\r
84 import org.eclipse.swt.widgets.Group;
\r
85 import org.eclipse.swt.widgets.Label;
\r
86 import org.eclipse.swt.widgets.Text;
\r
87 import org.eclipse.ui.IWorkbenchSite;
\r
88 import org.simantics.DatabaseJob;
\r
89 import org.simantics.databoard.util.URIStringUtils;
\r
90 import org.simantics.db.ReadGraph;
\r
91 import org.simantics.db.Resource;
\r
92 import org.simantics.db.Session;
\r
93 import org.simantics.db.common.ResourceArray;
\r
94 import org.simantics.db.common.request.UniqueRead;
\r
95 import org.simantics.db.common.utils.Logger;
\r
96 import org.simantics.db.exception.DatabaseException;
\r
97 import org.simantics.db.layer0.request.PossibleURI;
\r
98 import org.simantics.db.service.SerialisationSupport;
\r
99 import org.simantics.layer0.Layer0;
\r
100 import org.simantics.modeling.ModelingResources;
\r
101 import org.simantics.modeling.adapters.ChangeInformation;
\r
102 import org.simantics.modeling.ui.Activator;
\r
103 import org.simantics.ui.dnd.LocalObjectTransfer;
\r
104 import org.simantics.ui.dnd.ResourceReferenceTransfer;
\r
105 import org.simantics.ui.dnd.ResourceTransferUtils;
\r
106 import org.simantics.ui.utils.ResourceAdaptionUtils;
\r
107 import org.simantics.utils.ui.ErrorLogger;
\r
108 import org.simantics.utils.ui.SWTUtils;
\r
109 import org.simantics.utils.ui.dialogs.ShowMessage;
\r
110 import org.simantics.utils.ui.workbench.WorkbenchUtils;
\r
113 public class ChangeInformationComposite extends Composite {
\r
115 private final LocalResourceManager resourceManager;
\r
117 private final ColorDescriptor green = ColorDescriptor.createFrom(new RGB(0x57, 0xbc, 0x95));
\r
120 * The Session used to access the graph. Received from outside of this
\r
121 * class and therefore it is not disposed here, just used.
\r
123 private final Session session;
\r
125 private Resource resource;
\r
127 private List<Bean> allContents = new ArrayList<Bean>();
\r
129 private List<Bean> contents = new ArrayList<Bean>();
\r
131 protected Layer0 L0;
\r
133 protected IWorkbenchSite site;
\r
135 private NatTable table;
\r
137 private IDataProvider bodyDataProvider;
\r
139 private CDateTime createdBefore;
\r
140 private CDateTime createdAfter;
\r
141 private CDateTime modifiedBefore;
\r
142 private CDateTime modifiedAfter;
\r
144 private Label dropLabel;
\r
146 private Text creatorText;
\r
147 private Text modifierText;
\r
148 private Text nameText;
\r
149 private Text pathText;
\r
150 private Text typesText;
\r
152 private BeanSortModel sortModel;
\r
158 * @param resource the initial resource to debug or <code>null</code> for
\r
159 * initially blank UI.
\r
161 public ChangeInformationComposite(Composite parent, int style, final Session session, Resource resource, IWorkbenchSite site) {
\r
162 super(parent, style);
\r
163 Assert.isNotNull(session, "session is null");
\r
164 this.session = session;
\r
165 this.resource = resource;
\r
166 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);
\r
171 * When given to setStatus, indicates that the message shouldn't be touched
\r
172 * since <code>null</code> has a different meaning.
\r
174 private static final String DONT_TOUCH = "DONT_TOUCH";
\r
176 protected void setStatus(String message, String error) {
\r
177 IStatusLineManager status = WorkbenchUtils.getStatusLine(site);
\r
178 if (status != null) {
\r
179 if (message != DONT_TOUCH)
\r
180 status.setMessage(message);
\r
181 if (error != DONT_TOUCH)
\r
182 status.setErrorMessage(error);
\r
186 public void defaultInitializeUI() {
\r
188 setLayout(new GridLayout(4, false));
\r
189 setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
\r
191 createDropLabel(this);
\r
192 createContents(this);
\r
196 public Label createDropLabel(Composite parent) {
\r
197 dropLabel = new Label(parent, SWT.BORDER);
\r
198 dropLabel.setAlignment(SWT.CENTER);
\r
199 dropLabel.setText("Drag a resource here");
\r
200 dropLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
\r
201 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, false).applyTo(dropLabel);
\r
203 // Add resource id drop support to the drop-area.
\r
204 DropTarget dropTarget = new DropTarget(dropLabel, DND.DROP_LINK | DND.DROP_COPY);
\r
205 dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() });
\r
206 dropTarget.addDropListener(new DropTargetAdapter() {
\r
208 public void dragEnter(DropTargetEvent event) {
\r
209 event.detail = DND.DROP_LINK;
\r
210 dropLabel.setBackground((Color) resourceManager.get(green));
\r
214 public void dragLeave(DropTargetEvent event) {
\r
215 dropLabel.setBackground(null);
\r
219 public void drop(DropTargetEvent event) {
\r
220 dropLabel.setBackground(null);
\r
221 ResourceArray[] data = parseEventData(event);
\r
222 if (data == null || data.length != 1) {
\r
223 event.detail = DND.DROP_NONE;
\r
226 final ResourceArray array = data[0];
\r
227 final Resource r = array.resources[array.resources.length - 1];
\r
232 private ResourceArray[] parseEventData(DropTargetEvent event) {
\r
233 //System.out.println("DATA: " + event.data);
\r
234 if (event.data instanceof String) {
\r
236 SerialisationSupport support = session.getService(SerialisationSupport.class);
\r
237 return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray();
\r
238 } catch (IllegalArgumentException e) {
\r
239 ErrorLogger.defaultLogError(e);
\r
240 } catch (DatabaseException e) {
\r
241 ErrorLogger.defaultLogError(e);
\r
244 ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data);
\r
245 if (ret.length > 0)
\r
254 public void createContents(Composite parent) {
\r
256 Group fieldGroup = new Group(parent, SWT.NONE);
\r
257 fieldGroup.setLayout(new GridLayout(2, false));
\r
258 fieldGroup.setText("Filter modifications by text in columns");
\r
259 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(fieldGroup);
\r
263 final Label label = new Label(fieldGroup, SWT.NONE);
\r
264 label.setAlignment(SWT.CENTER);
\r
265 label.setText("Created By:");
\r
266 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label);
\r
268 creatorText = new Text(fieldGroup, SWT.BORDER);
\r
269 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(creatorText);
\r
271 creatorText.addModifyListener(new ModifyListener() {
\r
274 public void modifyText(ModifyEvent e) {
\r
283 final Label label = new Label(fieldGroup, SWT.NONE);
\r
284 label.setAlignment(SWT.CENTER);
\r
285 label.setText("Modified By:");
\r
286 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label);
\r
288 modifierText = new Text(fieldGroup, SWT.BORDER);
\r
289 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifierText);
\r
291 modifierText.addModifyListener(new ModifyListener() {
\r
294 public void modifyText(ModifyEvent e) {
\r
303 final Label label = new Label(fieldGroup, SWT.NONE);
\r
304 label.setAlignment(SWT.CENTER);
\r
305 label.setText("Name:");
\r
306 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label);
\r
308 nameText = new Text(fieldGroup, SWT.BORDER);
\r
309 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(nameText);
\r
311 nameText.addModifyListener(new ModifyListener() {
\r
314 public void modifyText(ModifyEvent e) {
\r
323 final Label label = new Label(fieldGroup, SWT.NONE);
\r
324 label.setAlignment(SWT.CENTER);
\r
325 label.setText("Path:");
\r
326 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label);
\r
328 pathText = new Text(fieldGroup, SWT.BORDER);
\r
329 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(pathText);
\r
331 pathText.addModifyListener(new ModifyListener() {
\r
334 public void modifyText(ModifyEvent e) {
\r
343 final Label label = new Label(fieldGroup, SWT.NONE);
\r
344 label.setAlignment(SWT.CENTER);
\r
345 label.setText("Types:");
\r
346 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label);
\r
348 typesText = new Text(fieldGroup, SWT.BORDER);
\r
349 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(typesText);
\r
351 typesText.addModifyListener(new ModifyListener() {
\r
354 public void modifyText(ModifyEvent e) {
\r
362 SelectionListener selectionListener = new SelectionListener() {
\r
365 public void widgetSelected(SelectionEvent e) {
\r
366 widgetDefaultSelected(e);
\r
370 public void widgetDefaultSelected(SelectionEvent e) {
\r
375 Group timeGroup = new Group(parent, SWT.NONE);
\r
376 timeGroup.setLayout(new GridLayout(2, false));
\r
377 timeGroup.setText("Filter modifications by time");
\r
378 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(timeGroup);
\r
380 createdAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR);
\r
381 createdAfter.setPattern("'Created after 'd.M.yyy '@' H:mm");
\r
382 createdAfter.setNullText("<choose created after>");
\r
383 createdAfter.addSelectionListener(selectionListener);
\r
384 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdAfter);
\r
385 createdBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR);
\r
386 createdBefore.setPattern("'Created before 'd.M.yyy '@' H:mm");
\r
387 createdBefore.setNullText("<choose created before>");
\r
388 createdBefore.addSelectionListener(selectionListener);
\r
389 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdBefore);
\r
391 modifiedAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR);
\r
392 modifiedAfter.setPattern("'Modified after 'd.M.yyy '@' H:mm");
\r
393 modifiedAfter.setNullText("<choose modified after>");
\r
394 modifiedAfter.addSelectionListener(selectionListener);
\r
395 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedAfter);
\r
396 modifiedBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR);
\r
397 modifiedBefore.setPattern("'Modified before 'd.M.yyy '@' H:mm");
\r
398 modifiedBefore.setNullText("<choose modified before>");
\r
399 modifiedBefore.addSelectionListener(selectionListener);
\r
400 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedBefore);
\r
402 //property names of the Person class
\r
403 String[] propertyNames = {"name", "path", "types", "createdBy", "createdAt", "modifiedBy", "modifiedAt"};
\r
405 //mapping from property to label, needed for column header labels
\r
406 Map<String, String> propertyToLabelMap = new HashMap<String, String>();
\r
407 propertyToLabelMap.put("name", "Name");
\r
408 propertyToLabelMap.put("path", "Path");
\r
409 propertyToLabelMap.put("types", "Types");
\r
410 propertyToLabelMap.put("createdBy", "Created By");
\r
411 propertyToLabelMap.put("createdAt", "Created At");
\r
412 propertyToLabelMap.put("modifiedBy", "Last Modified By");
\r
413 propertyToLabelMap.put("modifiedAt", "Last Modified At");
\r
415 //build the body layer stack
\r
416 //Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
\r
417 //setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
\r
418 //directly as body layer is also working.
\r
419 bodyDataProvider = new DefaultBodyDataProvider<Bean>(contents, propertyNames);
\r
420 final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
\r
421 bodyDataLayer.setColumnWidthByPosition(0, 145);
\r
422 bodyDataLayer.setColumnWidthByPosition(1, 170);
\r
423 bodyDataLayer.setColumnWidthByPosition(2, 120);
\r
424 bodyDataLayer.setColumnWidthByPosition(3, 85);
\r
425 bodyDataLayer.setColumnWidthByPosition(4, 85);
\r
426 bodyDataLayer.setColumnWidthByPosition(5, 115);
\r
427 bodyDataLayer.setColumnWidthByPosition(6, 115);
\r
429 final RowReorderLayer rowReorderLayer = new RowReorderLayer(bodyDataLayer);
\r
430 final SelectionLayer selectionLayer = new SelectionLayer(rowReorderLayer);
\r
431 ViewportLayer viewportLayer = new ViewportLayer(selectionLayer);
\r
433 //build the column header layer
\r
434 IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap);
\r
435 DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
\r
436 ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer);
\r
438 sortModel = new BeanSortModel(allContents, contents);
\r
440 SortHeaderLayer<Bean> sortHeaderLayer = new SortHeaderLayer<Bean>(
\r
441 columnHeaderLayer, sortModel);
\r
443 //build the row header layer
\r
444 IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
\r
445 DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
\r
446 rowHeaderDataLayer.setColumnWidthByPosition(0, 90);
\r
448 RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer);
\r
450 //build the corner layer
\r
451 IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
\r
452 DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
\r
453 ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer);
\r
455 //build the grid layer
\r
456 GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer);
\r
458 table = new NatTable(parent, gridLayer, false);
\r
460 DefaultNatTableStyleConfiguration styleConfiguration = new DefaultNatTableStyleConfiguration();
\r
461 styleConfiguration.hAlign = HorizontalAlignmentEnum.LEFT;
\r
462 table.addConfiguration(styleConfiguration);
\r
463 // Change the default sort key bindings. Note that 'auto configure' was turned off
\r
464 table.addConfiguration(new SingleClickSortConfiguration());
\r
465 table.addConfiguration(new DefaultSelectionStyleConfiguration());
\r
468 table.addConfiguration(new AbstractUiBindingConfiguration() {
\r
471 public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
\r
472 // Mouse move - Show resize cursor
\r
473 uiBindingRegistry.registerFirstMouseMoveBinding(new ColumnResizeEventMatcher(SWT.NONE,
\r
474 GridRegion.ROW_HEADER, 0), new ColumnResizeCursorAction());
\r
475 uiBindingRegistry.registerMouseMoveBinding(new MouseEventMatcher(), new ClearCursorAction());
\r
478 uiBindingRegistry.registerFirstMouseDragMode(new ColumnResizeEventMatcher(SWT.NONE,
\r
479 GridRegion.ROW_HEADER, 1), new ColumnResizeDragMode());
\r
481 uiBindingRegistry.registerDoubleClickBinding(new ColumnResizeEventMatcher(SWT.NONE,
\r
482 GridRegion.ROW_HEADER, 1), new AutoResizeColumnAction());
\r
483 uiBindingRegistry.registerSingleClickBinding(new ColumnResizeEventMatcher(SWT.NONE,
\r
484 GridRegion.ROW_HEADER, 1), new NoOpMouseAction());
\r
490 GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, true).applyTo(table);
\r
494 public void changeLocation(Resource element) {
\r
496 resource = element;
\r
499 String uri = session.syncRequest(new PossibleURI(resource));
\r
501 uri = uri.replace("http://Projects/Development%20Project/", "");
\r
502 uri = URIStringUtils.unescape(uri);
\r
503 dropLabel.setText("Drag a resource here - searching at " + uri);
\r
505 } catch (DatabaseException e) {
\r
506 Logger.defaultLogError(e);
\r
513 public void refresh() {
\r
519 public void updateData(boolean sort) {
\r
523 if(sort) sortModel.sortCurrent();
\r
527 setStatus(DONT_TOUCH, null);
\r
531 private long getPossibleTime(CDateTime widget) {
\r
532 Date d = widget.getSelection();
\r
533 if(d == null) return 0;
\r
534 else return d.getTime();
\r
537 public void filter() {
\r
539 long createdAfterTime = getPossibleTime(createdAfter);
\r
540 long createdBeforeTime = getPossibleTime(createdBefore);
\r
541 long modifiedAfterTime = getPossibleTime(modifiedAfter);
\r
542 long modifiedBeforeTime = getPossibleTime(modifiedBefore);
\r
544 String creatorFilter = creatorText.getText().toLowerCase();
\r
545 if(creatorFilter.isEmpty()) creatorFilter = null;
\r
546 String modifierFilter = modifierText.getText().toLowerCase();
\r
547 if(modifierFilter.isEmpty()) modifierFilter = null;
\r
548 String[] nameFilter = null;
\r
549 if(!nameText.getText().isEmpty()) nameFilter = nameText.getText().toLowerCase().split(" ");
\r
550 String[] pathFilter = null;
\r
551 if(!pathText.getText().isEmpty()) pathFilter = pathText.getText().toLowerCase().split(" ");
\r
552 String[] typesFilter = null;
\r
553 if(!typesText.getText().isEmpty()) typesFilter = typesText.getText().toLowerCase().split(" ");
\r
556 for(Bean b : allContents) {
\r
558 if(createdAfterTime > 0 && b.createdAt < createdAfterTime) continue;
\r
559 if(createdBeforeTime > 0 && b.createdAt > createdBeforeTime) continue;
\r
560 if(modifiedAfterTime > 0 && b.modifiedAt < modifiedAfterTime) continue;
\r
561 if(modifiedBeforeTime > 0 && b.modifiedAt > modifiedBeforeTime) continue;
\r
563 if(creatorFilter != null && !b.getCreatedBy().toLowerCase().contains(creatorFilter)) continue;
\r
564 if(modifierFilter != null && !b.getModifiedBy().toLowerCase().contains(modifierFilter)) continue;
\r
565 if(nameFilter!= null) {
\r
566 String name = b.getName().toLowerCase();
\r
567 boolean ok = false;
\r
568 for(String t : nameFilter) {
\r
569 if(name.contains(t)) {
\r
576 if(pathFilter!= null) {
\r
577 String name = b.getPath().toLowerCase();
\r
578 boolean ok = false;
\r
579 for(String t : pathFilter) {
\r
580 if(name.contains(t)) {
\r
587 if(typesFilter != null) {
\r
588 String types = b.getTypes().toLowerCase();
\r
589 boolean ok = false;
\r
590 for(String t : typesFilter) {
\r
591 if(types.contains(t)) {
\r
603 public void searchAndUpdate() {
\r
605 final Display display = WorkbenchUtils.getActiveWorkbenchWindowShell().getDisplay();
\r
606 Job job = new DatabaseJob("Processing change information") {
\r
608 protected IStatus run(final IProgressMonitor monitor) {
\r
612 allContents.clear();
\r
613 allContents.addAll(session.syncRequest(new UniqueRead<List<Bean>>() {
\r
615 private void browse(ReadGraph graph, Layer0 L0, Resource r, Set<Resource> visited) throws DatabaseException {
\r
617 if(!visited.add(r)) return;
\r
619 for(Resource object : graph.getObjects(r, L0.DependsOn))
\r
620 browse(graph, L0, object, visited);
\r
625 public List<Bean> perform(ReadGraph graph) throws DatabaseException {
\r
627 SubMonitor sub = SubMonitor.convert(monitor, "Readying change information", 100);
\r
629 sub.setTaskName("Searching for change records");
\r
631 ArrayList<Bean> result = new ArrayList<Bean>();
\r
632 if(resource == null) return result;
\r
634 HashSet<Resource> visited = new HashSet<Resource>();
\r
636 Layer0 L0 = Layer0.getInstance(graph);
\r
637 ModelingResources MOD = ModelingResources.getInstance(graph);
\r
639 browse(graph, L0, resource, visited);
\r
643 sub.setTaskName("Processing " + visited.size() + " change records");
\r
644 sub.setWorkRemaining(visited.size());
\r
646 String baseURI = graph.getPossibleURI(resource);
\r
648 for(Resource r : visited) {
\r
649 ChangeInformation ci = graph.getPossibleRelatedValue(r, MOD.changeInformation, ChangeInformation.BINDING);
\r
650 if(ci != null) result.add(new Bean(graph, r, ci, baseURI));
\r
659 return Status.OK_STATUS;
\r
660 } catch (final DatabaseException e) {
\r
661 showMessage(display, e.getMessage());
\r
662 // WARNING, because we don't want the job system to pop up it's own error dialog
\r
663 // which would happen if ERROR was used.
\r
664 return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Errors while reading change information.", e);
\r
668 SWTUtils.asyncExec(display, new Runnable() {
\r
670 public void run() {
\r
679 private void showMessage(Display display, final String message) {
\r
680 SWTUtils.asyncExec(display, new Runnable() {
\r
682 public void run() {
\r
683 ShowMessage.showError("Problems while reading change information", message);
\r