X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fview%2FChangeInformationComposite.java;h=16d208c437c4c85bc4fef6b621c9f373897d9254;hp=d9fab88e843bf791665c97385f112fa7f16e2eeb;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/view/ChangeInformationComposite.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/view/ChangeInformationComposite.java index d9fab88e8..16d208c43 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/view/ChangeInformationComposite.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/view/ChangeInformationComposite.java @@ -1,693 +1,693 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.modeling.ui.view; - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.SubMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.action.IStatusLineManager; -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.resource.ColorDescriptor; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.nebula.widgets.cdatetime.CDT; -import org.eclipse.nebula.widgets.cdatetime.CDateTime; -import org.eclipse.nebula.widgets.nattable.NatTable; -import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration; -import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration; -import org.eclipse.nebula.widgets.nattable.data.IDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.GridRegion; -import org.eclipse.nebula.widgets.nattable.grid.data.DefaultBodyDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; -import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; -import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; -import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer; -import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer; -import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; -import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; -import org.eclipse.nebula.widgets.nattable.layer.DataLayer; -import org.eclipse.nebula.widgets.nattable.layer.ILayer; -import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer; -import org.eclipse.nebula.widgets.nattable.resize.action.AutoResizeColumnAction; -import org.eclipse.nebula.widgets.nattable.resize.action.ColumnResizeCursorAction; -import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEventMatcher; -import org.eclipse.nebula.widgets.nattable.resize.mode.ColumnResizeDragMode; -import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; -import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionStyleConfiguration; -import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer; -import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration; -import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum; -import org.eclipse.nebula.widgets.nattable.ui.action.ClearCursorAction; -import org.eclipse.nebula.widgets.nattable.ui.action.NoOpMouseAction; -import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; -import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher; -import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer; -import org.eclipse.swt.SWT; -import org.eclipse.swt.dnd.DND; -import org.eclipse.swt.dnd.DropTarget; -import org.eclipse.swt.dnd.DropTargetAdapter; -import org.eclipse.swt.dnd.DropTargetEvent; -import org.eclipse.swt.dnd.TextTransfer; -import org.eclipse.swt.dnd.Transfer; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.RGB; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.ui.IWorkbenchSite; -import org.simantics.DatabaseJob; -import org.simantics.databoard.util.URIStringUtils; -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.common.ResourceArray; -import org.simantics.db.common.request.UniqueRead; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.request.PossibleURI; -import org.simantics.db.service.SerialisationSupport; -import org.simantics.layer0.Layer0; -import org.simantics.modeling.ModelingResources; -import org.simantics.modeling.adapters.ChangeInformation; -import org.simantics.modeling.ui.Activator; -import org.simantics.ui.dnd.LocalObjectTransfer; -import org.simantics.ui.dnd.ResourceReferenceTransfer; -import org.simantics.ui.dnd.ResourceTransferUtils; -import org.simantics.ui.utils.ResourceAdaptionUtils; -import org.simantics.utils.ui.ErrorLogger; -import org.simantics.utils.ui.SWTUtils; -import org.simantics.utils.ui.dialogs.ShowMessage; -import org.simantics.utils.ui.workbench.WorkbenchUtils; - - -public class ChangeInformationComposite extends Composite { - - private final LocalResourceManager resourceManager; - - private final ColorDescriptor green = ColorDescriptor.createFrom(new RGB(0x57, 0xbc, 0x95)); - - /** - * The Session used to access the graph. Received from outside of this - * class and therefore it is not disposed here, just used. - */ - private final Session session; - - private Resource resource; - - private List allContents = new ArrayList(); - - private List contents = new ArrayList(); - - protected Layer0 L0; - - protected IWorkbenchSite site; - - private NatTable table; - - private IDataProvider bodyDataProvider; - - private CDateTime createdBefore; - private CDateTime createdAfter; - private CDateTime modifiedBefore; - private CDateTime modifiedAfter; - - private Label dropLabel; - - private Text creatorText; - private Text modifierText; - private Text nameText; - private Text pathText; - private Text typesText; - - private BeanSortModel sortModel; - - /** - * @param parent - * @param style - * @param session - * @param resource the initial resource to debug or null for - * initially blank UI. - */ - public ChangeInformationComposite(Composite parent, int style, final Session session, Resource resource, IWorkbenchSite site) { - super(parent, style); - Assert.isNotNull(session, "session is null"); - this.session = session; - this.resource = resource; - this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent); - this.site = site; - } - - /** - * When given to setStatus, indicates that the message shouldn't be touched - * since null has a different meaning. - */ - private static final String DONT_TOUCH = "DONT_TOUCH"; - - protected void setStatus(String message, String error) { - IStatusLineManager status = WorkbenchUtils.getStatusLine(site); - if (status != null) { - if (message != DONT_TOUCH) - status.setMessage(message); - if (error != DONT_TOUCH) - status.setErrorMessage(error); - } - } - - public void defaultInitializeUI() { - - setLayout(new GridLayout(4, false)); - setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - createDropLabel(this); - createContents(this); - - } - - public Label createDropLabel(Composite parent) { - dropLabel = new Label(parent, SWT.BORDER); - dropLabel.setAlignment(SWT.CENTER); - dropLabel.setText("Drag a resource here"); - dropLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, false).applyTo(dropLabel); - - // Add resource id drop support to the drop-area. - DropTarget dropTarget = new DropTarget(dropLabel, DND.DROP_LINK | DND.DROP_COPY); - dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() }); - dropTarget.addDropListener(new DropTargetAdapter() { - @Override - public void dragEnter(DropTargetEvent event) { - event.detail = DND.DROP_LINK; - dropLabel.setBackground((Color) resourceManager.get(green)); - return; - } - @Override - public void dragLeave(DropTargetEvent event) { - dropLabel.setBackground(null); - } - - @Override - public void drop(DropTargetEvent event) { - dropLabel.setBackground(null); - ResourceArray[] data = parseEventData(event); - if (data == null || data.length != 1) { - event.detail = DND.DROP_NONE; - return; - } - final ResourceArray array = data[0]; - final Resource r = array.resources[array.resources.length - 1]; - - changeLocation(r); - } - - private ResourceArray[] parseEventData(DropTargetEvent event) { - //System.out.println("DATA: " + event.data); - if (event.data instanceof String) { - try { - SerialisationSupport support = session.getService(SerialisationSupport.class); - return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray(); - } catch (IllegalArgumentException e) { - ErrorLogger.defaultLogError(e); - } catch (DatabaseException e) { - ErrorLogger.defaultLogError(e); - } - } - ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data); - if (ret.length > 0) - return ret; - return null; - } - }); - - return dropLabel; - } - - public void createContents(Composite parent) { - - Group fieldGroup = new Group(parent, SWT.NONE); - fieldGroup.setLayout(new GridLayout(2, false)); - fieldGroup.setText("Filter modifications by text in columns"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(fieldGroup); - - { - - final Label label = new Label(fieldGroup, SWT.NONE); - label.setAlignment(SWT.CENTER); - label.setText("Created By:"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); - - creatorText = new Text(fieldGroup, SWT.BORDER); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(creatorText); - - creatorText.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - updateData(false); - } - }); - - } - - { - - final Label label = new Label(fieldGroup, SWT.NONE); - label.setAlignment(SWT.CENTER); - label.setText("Modified By:"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); - - modifierText = new Text(fieldGroup, SWT.BORDER); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifierText); - - modifierText.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - updateData(false); - } - }); - - } - - { - - final Label label = new Label(fieldGroup, SWT.NONE); - label.setAlignment(SWT.CENTER); - label.setText("Name:"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); - - nameText = new Text(fieldGroup, SWT.BORDER); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(nameText); - - nameText.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - updateData(false); - } - }); - - } - - { - - final Label label = new Label(fieldGroup, SWT.NONE); - label.setAlignment(SWT.CENTER); - label.setText("Path:"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); - - pathText = new Text(fieldGroup, SWT.BORDER); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(pathText); - - pathText.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - updateData(false); - } - }); - - } - - { - - final Label label = new Label(fieldGroup, SWT.NONE); - label.setAlignment(SWT.CENTER); - label.setText("Types:"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); - - typesText = new Text(fieldGroup, SWT.BORDER); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(typesText); - - typesText.addModifyListener(new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - updateData(false); - } - }); - - } - - - SelectionListener selectionListener = new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - widgetDefaultSelected(e); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - updateData(false); - } - }; - - Group timeGroup = new Group(parent, SWT.NONE); - timeGroup.setLayout(new GridLayout(2, false)); - timeGroup.setText("Filter modifications by time"); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(timeGroup); - - createdAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); - createdAfter.setPattern("'Created after 'd.M.yyy '@' H:mm"); - createdAfter.setNullText(""); - createdAfter.addSelectionListener(selectionListener); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdAfter); - createdBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); - createdBefore.setPattern("'Created before 'd.M.yyy '@' H:mm"); - createdBefore.setNullText(""); - createdBefore.addSelectionListener(selectionListener); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdBefore); - - modifiedAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); - modifiedAfter.setPattern("'Modified after 'd.M.yyy '@' H:mm"); - modifiedAfter.setNullText(""); - modifiedAfter.addSelectionListener(selectionListener); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedAfter); - modifiedBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); - modifiedBefore.setPattern("'Modified before 'd.M.yyy '@' H:mm"); - modifiedBefore.setNullText(""); - modifiedBefore.addSelectionListener(selectionListener); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedBefore); - - //property names of the Person class - String[] propertyNames = {"name", "path", "types", "createdBy", "createdAt", "modifiedBy", "modifiedAt"}; - - //mapping from property to label, needed for column header labels - Map propertyToLabelMap = new HashMap(); - propertyToLabelMap.put("name", "Name"); - propertyToLabelMap.put("path", "Path"); - propertyToLabelMap.put("types", "Types"); - propertyToLabelMap.put("createdBy", "Created By"); - propertyToLabelMap.put("createdAt", "Created At"); - propertyToLabelMap.put("modifiedBy", "Last Modified By"); - propertyToLabelMap.put("modifiedAt", "Last Modified At"); - - //build the body layer stack - //Usually you would create a new layer stack by extending AbstractIndexLayerTransform and - //setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer - //directly as body layer is also working. - bodyDataProvider = new DefaultBodyDataProvider(contents, propertyNames); - final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); - bodyDataLayer.setColumnWidthByPosition(0, 145); - bodyDataLayer.setColumnWidthByPosition(1, 170); - bodyDataLayer.setColumnWidthByPosition(2, 120); - bodyDataLayer.setColumnWidthByPosition(3, 85); - bodyDataLayer.setColumnWidthByPosition(4, 85); - bodyDataLayer.setColumnWidthByPosition(5, 115); - bodyDataLayer.setColumnWidthByPosition(6, 115); - - final RowReorderLayer rowReorderLayer = new RowReorderLayer(bodyDataLayer); - final SelectionLayer selectionLayer = new SelectionLayer(rowReorderLayer); - ViewportLayer viewportLayer = new ViewportLayer(selectionLayer); - - //build the column header layer - IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap); - DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider); - ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer); - - sortModel = new BeanSortModel(allContents, contents); - - SortHeaderLayer sortHeaderLayer = new SortHeaderLayer( - columnHeaderLayer, sortModel); - - //build the row header layer - IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider); - DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider); - rowHeaderDataLayer.setColumnWidthByPosition(0, 90); - - RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer); - - //build the corner layer - IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider); - DataLayer cornerDataLayer = new DataLayer(cornerDataProvider); - ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer); - - //build the grid layer - GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer); - - table = new NatTable(parent, gridLayer, false); - - DefaultNatTableStyleConfiguration styleConfiguration = new DefaultNatTableStyleConfiguration(); - styleConfiguration.hAlign = HorizontalAlignmentEnum.LEFT; - table.addConfiguration(styleConfiguration); - // Change the default sort key bindings. Note that 'auto configure' was turned off - table.addConfiguration(new SingleClickSortConfiguration()); - table.addConfiguration(new DefaultSelectionStyleConfiguration()); - - - table.addConfiguration(new AbstractUiBindingConfiguration() { - - @Override - public void configureUiBindings(UiBindingRegistry uiBindingRegistry) { - // Mouse move - Show resize cursor - uiBindingRegistry.registerFirstMouseMoveBinding(new ColumnResizeEventMatcher(SWT.NONE, - GridRegion.ROW_HEADER, 0), new ColumnResizeCursorAction()); - uiBindingRegistry.registerMouseMoveBinding(new MouseEventMatcher(), new ClearCursorAction()); - - // Column resize - uiBindingRegistry.registerFirstMouseDragMode(new ColumnResizeEventMatcher(SWT.NONE, - GridRegion.ROW_HEADER, 1), new ColumnResizeDragMode()); - - uiBindingRegistry.registerDoubleClickBinding(new ColumnResizeEventMatcher(SWT.NONE, - GridRegion.ROW_HEADER, 1), new AutoResizeColumnAction()); - uiBindingRegistry.registerSingleClickBinding(new ColumnResizeEventMatcher(SWT.NONE, - GridRegion.ROW_HEADER, 1), new NoOpMouseAction()); - } - }); - - table.configure(); - - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, true).applyTo(table); - - } - - public void changeLocation(Resource element) { - - resource = element; - - try { - String uri = session.syncRequest(new PossibleURI(resource)); - if(uri != null) { - uri = uri.replace("http://Projects/Development%20Project/", ""); - uri = URIStringUtils.unescape(uri); - dropLabel.setText("Drag a resource here - searching at " + uri); - } - } catch (DatabaseException e) { - Logger.defaultLogError(e); - } - - refresh(); - - } - - public void refresh() { - - searchAndUpdate(); - - } - - public void updateData(boolean sort) { - - filter(); - - if(sort) sortModel.sortCurrent(); - - table.refresh(); - - setStatus(DONT_TOUCH, null); - - } - - private long getPossibleTime(CDateTime widget) { - Date d = widget.getSelection(); - if(d == null) return 0; - else return d.getTime(); - } - - public void filter() { - - long createdAfterTime = getPossibleTime(createdAfter); - long createdBeforeTime = getPossibleTime(createdBefore); - long modifiedAfterTime = getPossibleTime(modifiedAfter); - long modifiedBeforeTime = getPossibleTime(modifiedBefore); - - String creatorFilter = creatorText.getText().toLowerCase(); - if(creatorFilter.isEmpty()) creatorFilter = null; - String modifierFilter = modifierText.getText().toLowerCase(); - if(modifierFilter.isEmpty()) modifierFilter = null; - String[] nameFilter = null; - if(!nameText.getText().isEmpty()) nameFilter = nameText.getText().toLowerCase().split(" "); - String[] pathFilter = null; - if(!pathText.getText().isEmpty()) pathFilter = pathText.getText().toLowerCase().split(" "); - String[] typesFilter = null; - if(!typesText.getText().isEmpty()) typesFilter = typesText.getText().toLowerCase().split(" "); - - contents.clear(); - for(Bean b : allContents) { - - if(createdAfterTime > 0 && b.createdAt < createdAfterTime) continue; - if(createdBeforeTime > 0 && b.createdAt > createdBeforeTime) continue; - if(modifiedAfterTime > 0 && b.modifiedAt < modifiedAfterTime) continue; - if(modifiedBeforeTime > 0 && b.modifiedAt > modifiedBeforeTime) continue; - - if(creatorFilter != null && !b.getCreatedBy().toLowerCase().contains(creatorFilter)) continue; - if(modifierFilter != null && !b.getModifiedBy().toLowerCase().contains(modifierFilter)) continue; - if(nameFilter!= null) { - String name = b.getName().toLowerCase(); - boolean ok = false; - for(String t : nameFilter) { - if(name.contains(t)) { - ok=true; - break; - } - } - if(!ok) continue; - } - if(pathFilter!= null) { - String name = b.getPath().toLowerCase(); - boolean ok = false; - for(String t : pathFilter) { - if(name.contains(t)) { - ok=true; - break; - } - } - if(!ok) continue; - } - if(typesFilter != null) { - String types = b.getTypes().toLowerCase(); - boolean ok = false; - for(String t : typesFilter) { - if(types.contains(t)) { - ok=true; - break; - } - } - if(!ok) continue; - } - contents.add(b); - } - - } - - public void searchAndUpdate() { - - final Display display = WorkbenchUtils.getActiveWorkbenchWindowShell().getDisplay(); - Job job = new DatabaseJob("Processing change information") { - @Override - protected IStatus run(final IProgressMonitor monitor) { - - try { - - allContents.clear(); - allContents.addAll(session.syncRequest(new UniqueRead>() { - - private void browse(ReadGraph graph, Layer0 L0, Resource r, Set visited) throws DatabaseException { - - if(!visited.add(r)) return; - - for(Resource object : graph.getObjects(r, L0.DependsOn)) - browse(graph, L0, object, visited); - - } - - @Override - public List perform(ReadGraph graph) throws DatabaseException { - - SubMonitor sub = SubMonitor.convert(monitor, "Readying change information", 100); - - sub.setTaskName("Searching for change records"); - - ArrayList result = new ArrayList(); - if(resource == null) return result; - - HashSet visited = new HashSet(); - - Layer0 L0 = Layer0.getInstance(graph); - ModelingResources MOD = ModelingResources.getInstance(graph); - - browse(graph, L0, resource, visited); - - sub.worked(30); - - sub.setTaskName("Processing " + visited.size() + " change records"); - sub.setWorkRemaining(visited.size()); - - String baseURI = graph.getPossibleURI(resource); - - for(Resource r : visited) { - ChangeInformation ci = graph.getPossibleRelatedValue(r, MOD.changeInformation, ChangeInformation.BINDING); - if(ci != null) result.add(new Bean(graph, r, ci, baseURI)); - sub.worked(1); - } - - return result; - - } - - })); - return Status.OK_STATUS; - } catch (final DatabaseException e) { - showMessage(display, e.getMessage()); - // WARNING, because we don't want the job system to pop up it's own error dialog - // which would happen if ERROR was used. - return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Errors while reading change information.", e); - } finally { - monitor.done(); - - SWTUtils.asyncExec(display, new Runnable() { - @Override - public void run() { - updateData(true); - } - }); - - } - - } - - private void showMessage(Display display, final String message) { - SWTUtils.asyncExec(display, new Runnable() { - @Override - public void run() { - ShowMessage.showError("Problems while reading change information", message); - } - }); - } - - }; - job.setUser(true); - job.schedule(); - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.ui.view; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.resource.ColorDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.nebula.widgets.cdatetime.CDT; +import org.eclipse.nebula.widgets.cdatetime.CDateTime; +import org.eclipse.nebula.widgets.nattable.NatTable; +import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration; +import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration; +import org.eclipse.nebula.widgets.nattable.data.IDataProvider; +import org.eclipse.nebula.widgets.nattable.grid.GridRegion; +import org.eclipse.nebula.widgets.nattable.grid.data.DefaultBodyDataProvider; +import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider; +import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider; +import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider; +import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer; +import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer; +import org.eclipse.nebula.widgets.nattable.layer.DataLayer; +import org.eclipse.nebula.widgets.nattable.layer.ILayer; +import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer; +import org.eclipse.nebula.widgets.nattable.resize.action.AutoResizeColumnAction; +import org.eclipse.nebula.widgets.nattable.resize.action.ColumnResizeCursorAction; +import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEventMatcher; +import org.eclipse.nebula.widgets.nattable.resize.mode.ColumnResizeDragMode; +import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer; +import org.eclipse.nebula.widgets.nattable.selection.config.DefaultSelectionStyleConfiguration; +import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer; +import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration; +import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum; +import org.eclipse.nebula.widgets.nattable.ui.action.ClearCursorAction; +import org.eclipse.nebula.widgets.nattable.ui.action.NoOpMouseAction; +import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry; +import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher; +import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.DatabaseJob; +import org.simantics.databoard.util.URIStringUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.common.ResourceArray; +import org.simantics.db.common.request.UniqueRead; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.request.PossibleURI; +import org.simantics.db.service.SerialisationSupport; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.adapters.ChangeInformation; +import org.simantics.modeling.ui.Activator; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.ui.dnd.ResourceReferenceTransfer; +import org.simantics.ui.dnd.ResourceTransferUtils; +import org.simantics.ui.utils.ResourceAdaptionUtils; +import org.simantics.utils.ui.ErrorLogger; +import org.simantics.utils.ui.SWTUtils; +import org.simantics.utils.ui.dialogs.ShowMessage; +import org.simantics.utils.ui.workbench.WorkbenchUtils; + + +public class ChangeInformationComposite extends Composite { + + private final LocalResourceManager resourceManager; + + private final ColorDescriptor green = ColorDescriptor.createFrom(new RGB(0x57, 0xbc, 0x95)); + + /** + * The Session used to access the graph. Received from outside of this + * class and therefore it is not disposed here, just used. + */ + private final Session session; + + private Resource resource; + + private List allContents = new ArrayList(); + + private List contents = new ArrayList(); + + protected Layer0 L0; + + protected IWorkbenchSite site; + + private NatTable table; + + private IDataProvider bodyDataProvider; + + private CDateTime createdBefore; + private CDateTime createdAfter; + private CDateTime modifiedBefore; + private CDateTime modifiedAfter; + + private Label dropLabel; + + private Text creatorText; + private Text modifierText; + private Text nameText; + private Text pathText; + private Text typesText; + + private BeanSortModel sortModel; + + /** + * @param parent + * @param style + * @param session + * @param resource the initial resource to debug or null for + * initially blank UI. + */ + public ChangeInformationComposite(Composite parent, int style, final Session session, Resource resource, IWorkbenchSite site) { + super(parent, style); + Assert.isNotNull(session, "session is null"); + this.session = session; + this.resource = resource; + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent); + this.site = site; + } + + /** + * When given to setStatus, indicates that the message shouldn't be touched + * since null has a different meaning. + */ + private static final String DONT_TOUCH = "DONT_TOUCH"; + + protected void setStatus(String message, String error) { + IStatusLineManager status = WorkbenchUtils.getStatusLine(site); + if (status != null) { + if (message != DONT_TOUCH) + status.setMessage(message); + if (error != DONT_TOUCH) + status.setErrorMessage(error); + } + } + + public void defaultInitializeUI() { + + setLayout(new GridLayout(4, false)); + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + createDropLabel(this); + createContents(this); + + } + + public Label createDropLabel(Composite parent) { + dropLabel = new Label(parent, SWT.BORDER); + dropLabel.setAlignment(SWT.CENTER); + dropLabel.setText("Drag a resource here"); + dropLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY)); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, false).applyTo(dropLabel); + + // Add resource id drop support to the drop-area. + DropTarget dropTarget = new DropTarget(dropLabel, DND.DROP_LINK | DND.DROP_COPY); + dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(), ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() }); + dropTarget.addDropListener(new DropTargetAdapter() { + @Override + public void dragEnter(DropTargetEvent event) { + event.detail = DND.DROP_LINK; + dropLabel.setBackground((Color) resourceManager.get(green)); + return; + } + @Override + public void dragLeave(DropTargetEvent event) { + dropLabel.setBackground(null); + } + + @Override + public void drop(DropTargetEvent event) { + dropLabel.setBackground(null); + ResourceArray[] data = parseEventData(event); + if (data == null || data.length != 1) { + event.detail = DND.DROP_NONE; + return; + } + final ResourceArray array = data[0]; + final Resource r = array.resources[array.resources.length - 1]; + + changeLocation(r); + } + + private ResourceArray[] parseEventData(DropTargetEvent event) { + //System.out.println("DATA: " + event.data); + if (event.data instanceof String) { + try { + SerialisationSupport support = session.getService(SerialisationSupport.class); + return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray(); + } catch (IllegalArgumentException e) { + ErrorLogger.defaultLogError(e); + } catch (DatabaseException e) { + ErrorLogger.defaultLogError(e); + } + } + ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data); + if (ret.length > 0) + return ret; + return null; + } + }); + + return dropLabel; + } + + public void createContents(Composite parent) { + + Group fieldGroup = new Group(parent, SWT.NONE); + fieldGroup.setLayout(new GridLayout(2, false)); + fieldGroup.setText("Filter modifications by text in columns"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(fieldGroup); + + { + + final Label label = new Label(fieldGroup, SWT.NONE); + label.setAlignment(SWT.CENTER); + label.setText("Created By:"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); + + creatorText = new Text(fieldGroup, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(creatorText); + + creatorText.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateData(false); + } + }); + + } + + { + + final Label label = new Label(fieldGroup, SWT.NONE); + label.setAlignment(SWT.CENTER); + label.setText("Modified By:"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); + + modifierText = new Text(fieldGroup, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifierText); + + modifierText.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateData(false); + } + }); + + } + + { + + final Label label = new Label(fieldGroup, SWT.NONE); + label.setAlignment(SWT.CENTER); + label.setText("Name:"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); + + nameText = new Text(fieldGroup, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(nameText); + + nameText.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateData(false); + } + }); + + } + + { + + final Label label = new Label(fieldGroup, SWT.NONE); + label.setAlignment(SWT.CENTER); + label.setText("Path:"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); + + pathText = new Text(fieldGroup, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(pathText); + + pathText.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateData(false); + } + }); + + } + + { + + final Label label = new Label(fieldGroup, SWT.NONE); + label.setAlignment(SWT.CENTER); + label.setText("Types:"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(false, false).applyTo(label); + + typesText = new Text(fieldGroup, SWT.BORDER); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(typesText); + + typesText.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + updateData(false); + } + }); + + } + + + SelectionListener selectionListener = new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + widgetDefaultSelected(e); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + updateData(false); + } + }; + + Group timeGroup = new Group(parent, SWT.NONE); + timeGroup.setLayout(new GridLayout(2, false)); + timeGroup.setText("Filter modifications by time"); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(4, 1).grab(true, false).applyTo(timeGroup); + + createdAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); + createdAfter.setPattern("'Created after 'd.M.yyy '@' H:mm"); + createdAfter.setNullText(""); + createdAfter.addSelectionListener(selectionListener); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdAfter); + createdBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); + createdBefore.setPattern("'Created before 'd.M.yyy '@' H:mm"); + createdBefore.setNullText(""); + createdBefore.addSelectionListener(selectionListener); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(createdBefore); + + modifiedAfter = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); + modifiedAfter.setPattern("'Modified after 'd.M.yyy '@' H:mm"); + modifiedAfter.setNullText(""); + modifiedAfter.addSelectionListener(selectionListener); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedAfter); + modifiedBefore = new CDateTime(timeGroup, CDT.BORDER | CDT.DROP_DOWN | CDT.CLOCK_12_HOUR); + modifiedBefore.setPattern("'Modified before 'd.M.yyy '@' H:mm"); + modifiedBefore.setNullText(""); + modifiedBefore.addSelectionListener(selectionListener); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(1, 1).grab(true, false).applyTo(modifiedBefore); + + //property names of the Person class + String[] propertyNames = {"name", "path", "types", "createdBy", "createdAt", "modifiedBy", "modifiedAt"}; + + //mapping from property to label, needed for column header labels + Map propertyToLabelMap = new HashMap(); + propertyToLabelMap.put("name", "Name"); + propertyToLabelMap.put("path", "Path"); + propertyToLabelMap.put("types", "Types"); + propertyToLabelMap.put("createdBy", "Created By"); + propertyToLabelMap.put("createdAt", "Created At"); + propertyToLabelMap.put("modifiedBy", "Last Modified By"); + propertyToLabelMap.put("modifiedAt", "Last Modified At"); + + //build the body layer stack + //Usually you would create a new layer stack by extending AbstractIndexLayerTransform and + //setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer + //directly as body layer is also working. + bodyDataProvider = new DefaultBodyDataProvider(contents, propertyNames); + final DataLayer bodyDataLayer = new DataLayer(bodyDataProvider); + bodyDataLayer.setColumnWidthByPosition(0, 145); + bodyDataLayer.setColumnWidthByPosition(1, 170); + bodyDataLayer.setColumnWidthByPosition(2, 120); + bodyDataLayer.setColumnWidthByPosition(3, 85); + bodyDataLayer.setColumnWidthByPosition(4, 85); + bodyDataLayer.setColumnWidthByPosition(5, 115); + bodyDataLayer.setColumnWidthByPosition(6, 115); + + final RowReorderLayer rowReorderLayer = new RowReorderLayer(bodyDataLayer); + final SelectionLayer selectionLayer = new SelectionLayer(rowReorderLayer); + ViewportLayer viewportLayer = new ViewportLayer(selectionLayer); + + //build the column header layer + IDataProvider columnHeaderDataProvider = new DefaultColumnHeaderDataProvider(propertyNames, propertyToLabelMap); + DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider); + ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, viewportLayer, selectionLayer); + + sortModel = new BeanSortModel(allContents, contents); + + SortHeaderLayer sortHeaderLayer = new SortHeaderLayer( + columnHeaderLayer, sortModel); + + //build the row header layer + IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider); + DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider); + rowHeaderDataLayer.setColumnWidthByPosition(0, 90); + + RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, viewportLayer, selectionLayer); + + //build the corner layer + IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider); + DataLayer cornerDataLayer = new DataLayer(cornerDataProvider); + ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer); + + //build the grid layer + GridLayer gridLayer = new GridLayer(viewportLayer, sortHeaderLayer, rowHeaderLayer, cornerLayer); + + table = new NatTable(parent, gridLayer, false); + + DefaultNatTableStyleConfiguration styleConfiguration = new DefaultNatTableStyleConfiguration(); + styleConfiguration.hAlign = HorizontalAlignmentEnum.LEFT; + table.addConfiguration(styleConfiguration); + // Change the default sort key bindings. Note that 'auto configure' was turned off + table.addConfiguration(new SingleClickSortConfiguration()); + table.addConfiguration(new DefaultSelectionStyleConfiguration()); + + + table.addConfiguration(new AbstractUiBindingConfiguration() { + + @Override + public void configureUiBindings(UiBindingRegistry uiBindingRegistry) { + // Mouse move - Show resize cursor + uiBindingRegistry.registerFirstMouseMoveBinding(new ColumnResizeEventMatcher(SWT.NONE, + GridRegion.ROW_HEADER, 0), new ColumnResizeCursorAction()); + uiBindingRegistry.registerMouseMoveBinding(new MouseEventMatcher(), new ClearCursorAction()); + + // Column resize + uiBindingRegistry.registerFirstMouseDragMode(new ColumnResizeEventMatcher(SWT.NONE, + GridRegion.ROW_HEADER, 1), new ColumnResizeDragMode()); + + uiBindingRegistry.registerDoubleClickBinding(new ColumnResizeEventMatcher(SWT.NONE, + GridRegion.ROW_HEADER, 1), new AutoResizeColumnAction()); + uiBindingRegistry.registerSingleClickBinding(new ColumnResizeEventMatcher(SWT.NONE, + GridRegion.ROW_HEADER, 1), new NoOpMouseAction()); + } + }); + + table.configure(); + + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).hint(SWT.DEFAULT, 20).span(4, 1).grab(true, true).applyTo(table); + + } + + public void changeLocation(Resource element) { + + resource = element; + + try { + String uri = session.syncRequest(new PossibleURI(resource)); + if(uri != null) { + uri = uri.replace("http://Projects/Development%20Project/", ""); + uri = URIStringUtils.unescape(uri); + dropLabel.setText("Drag a resource here - searching at " + uri); + } + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + + refresh(); + + } + + public void refresh() { + + searchAndUpdate(); + + } + + public void updateData(boolean sort) { + + filter(); + + if(sort) sortModel.sortCurrent(); + + table.refresh(); + + setStatus(DONT_TOUCH, null); + + } + + private long getPossibleTime(CDateTime widget) { + Date d = widget.getSelection(); + if(d == null) return 0; + else return d.getTime(); + } + + public void filter() { + + long createdAfterTime = getPossibleTime(createdAfter); + long createdBeforeTime = getPossibleTime(createdBefore); + long modifiedAfterTime = getPossibleTime(modifiedAfter); + long modifiedBeforeTime = getPossibleTime(modifiedBefore); + + String creatorFilter = creatorText.getText().toLowerCase(); + if(creatorFilter.isEmpty()) creatorFilter = null; + String modifierFilter = modifierText.getText().toLowerCase(); + if(modifierFilter.isEmpty()) modifierFilter = null; + String[] nameFilter = null; + if(!nameText.getText().isEmpty()) nameFilter = nameText.getText().toLowerCase().split(" "); + String[] pathFilter = null; + if(!pathText.getText().isEmpty()) pathFilter = pathText.getText().toLowerCase().split(" "); + String[] typesFilter = null; + if(!typesText.getText().isEmpty()) typesFilter = typesText.getText().toLowerCase().split(" "); + + contents.clear(); + for(Bean b : allContents) { + + if(createdAfterTime > 0 && b.createdAt < createdAfterTime) continue; + if(createdBeforeTime > 0 && b.createdAt > createdBeforeTime) continue; + if(modifiedAfterTime > 0 && b.modifiedAt < modifiedAfterTime) continue; + if(modifiedBeforeTime > 0 && b.modifiedAt > modifiedBeforeTime) continue; + + if(creatorFilter != null && !b.getCreatedBy().toLowerCase().contains(creatorFilter)) continue; + if(modifierFilter != null && !b.getModifiedBy().toLowerCase().contains(modifierFilter)) continue; + if(nameFilter!= null) { + String name = b.getName().toLowerCase(); + boolean ok = false; + for(String t : nameFilter) { + if(name.contains(t)) { + ok=true; + break; + } + } + if(!ok) continue; + } + if(pathFilter!= null) { + String name = b.getPath().toLowerCase(); + boolean ok = false; + for(String t : pathFilter) { + if(name.contains(t)) { + ok=true; + break; + } + } + if(!ok) continue; + } + if(typesFilter != null) { + String types = b.getTypes().toLowerCase(); + boolean ok = false; + for(String t : typesFilter) { + if(types.contains(t)) { + ok=true; + break; + } + } + if(!ok) continue; + } + contents.add(b); + } + + } + + public void searchAndUpdate() { + + final Display display = WorkbenchUtils.getActiveWorkbenchWindowShell().getDisplay(); + Job job = new DatabaseJob("Processing change information") { + @Override + protected IStatus run(final IProgressMonitor monitor) { + + try { + + allContents.clear(); + allContents.addAll(session.syncRequest(new UniqueRead>() { + + private void browse(ReadGraph graph, Layer0 L0, Resource r, Set visited) throws DatabaseException { + + if(!visited.add(r)) return; + + for(Resource object : graph.getObjects(r, L0.DependsOn)) + browse(graph, L0, object, visited); + + } + + @Override + public List perform(ReadGraph graph) throws DatabaseException { + + SubMonitor sub = SubMonitor.convert(monitor, "Readying change information", 100); + + sub.setTaskName("Searching for change records"); + + ArrayList result = new ArrayList(); + if(resource == null) return result; + + HashSet visited = new HashSet(); + + Layer0 L0 = Layer0.getInstance(graph); + ModelingResources MOD = ModelingResources.getInstance(graph); + + browse(graph, L0, resource, visited); + + sub.worked(30); + + sub.setTaskName("Processing " + visited.size() + " change records"); + sub.setWorkRemaining(visited.size()); + + String baseURI = graph.getPossibleURI(resource); + + for(Resource r : visited) { + ChangeInformation ci = graph.getPossibleRelatedValue(r, MOD.changeInformation, ChangeInformation.BINDING); + if(ci != null) result.add(new Bean(graph, r, ci, baseURI)); + sub.worked(1); + } + + return result; + + } + + })); + return Status.OK_STATUS; + } catch (final DatabaseException e) { + showMessage(display, e.getMessage()); + // WARNING, because we don't want the job system to pop up it's own error dialog + // which would happen if ERROR was used. + return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Errors while reading change information.", e); + } finally { + monitor.done(); + + SWTUtils.asyncExec(display, new Runnable() { + @Override + public void run() { + updateData(true); + } + }); + + } + + } + + private void showMessage(Display display, final String message) { + SWTUtils.asyncExec(display, new Runnable() { + @Override + public void run() { + ShowMessage.showError("Problems while reading change information", message); + } + }); + } + + }; + job.setUser(true); + job.schedule(); + } + +}