Skip to content

Commit

Permalink
507595 Adding Sortable to Table Columns
Browse files Browse the repository at this point in the history
Change-Id: I80a5605e36b10daa0ec90c082c37c58d332f6501
Signed-off-by: Francesco Guidieri <francesco.guidieri@gmail.com>

https://bugs.eclipse.org/bugs/show_bug.cgi?id=507595

Change-Id: I80a5605e36b10daa0ec90c082c37c58d332f6501
  • Loading branch information
fraguid committed Nov 21, 2016
1 parent 374d78a commit ce908e0
Show file tree
Hide file tree
Showing 17 changed files with 1,115 additions and 7 deletions.
Expand Up @@ -28,6 +28,7 @@ Export-Package: org.eclipse.emf.parsley,
org.eclipse.emf.parsley.handlers,
org.eclipse.emf.parsley.internal.databinding;x-internal:=true,
org.eclipse.emf.parsley.internal.edit.ui.dnd,
org.eclipse.emf.parsley.internal.viewers;x-internal:=true,
org.eclipse.emf.parsley.listeners,
org.eclipse.emf.parsley.menus,
org.eclipse.emf.parsley.resource,
Expand Down
@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2016 RCP Vision (http://www.rcp-vision.com) and others.
* 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:
* Francesco Guidieri - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.parsley.internal.viewers;

import java.util.List;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.parsley.util.EmfParsleyUtil;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;

/**
* @since 1.1
* @author Francesco Guidieri
*/
public class GenericFeatureViewerComparator extends ViewerComparator {

private int propertyIndex;
private int direction;

private List<EStructuralFeature> features;

public GenericFeatureViewerComparator() {
this.propertyIndex = 0;
this.direction = SWT.NONE;
}

public void init(List<EStructuralFeature> features) {
this.features = features;
}

public int getDirection() {
return direction;
}

public int getPropertyIndex() {
return propertyIndex;
}

public void setPropertyIndex(int column) {
if (column == this.propertyIndex) {
// Same column as last sort; toggle the direction
switch (direction) {
case SWT.NONE:
direction = SWT.UP;
break;
case SWT.UP:
direction = SWT.DOWN;
break;
default:
direction = SWT.NONE;
}
} else {
// New column; do an ascending sort
propertyIndex = column;
direction = SWT.UP;
}
}

@Override
public int compare(Viewer viewer, Object e1, Object e2) {
EObject p1 = (EObject) e1;
EObject p2 = (EObject) e2;
// If none, no compare
if (direction == SWT.NONE) {
return 0;
}

EStructuralFeature feature = features.get(propertyIndex);
int rc = compareValue(p1, p2, feature);
// If descending order, flip the direction
if (direction == SWT.DOWN) {
rc = -rc;
}
return rc;
}

protected int compareValue(EObject p1, EObject p2, EStructuralFeature feature) {
Object value1 = p1.eGet(feature);
Object value2 = p2.eGet(feature);
return EmfParsleyUtil.compareValues(value1, value2);
}

}
Expand Up @@ -88,4 +88,21 @@ public static EObject getEObjectOrNull(Object o) {
}
return null;
}

/**
* @since 1.1
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static int compareValues(Object value1, Object value2) {
if (value1 instanceof Comparable && value2 instanceof Comparable) {
return ((Comparable) value1).compareTo(value2);
} else if (value1 != null && value2 != null) {
return value1.toString().compareTo(value2.toString());
} else if (value1 != null) {
return 1;
} else if (value2 != null) {
return -1;
}
return 0;
}
}
Expand Up @@ -17,11 +17,14 @@
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.parsley.EmfParsleyConstants;
import org.eclipse.emf.parsley.internal.viewers.GenericFeatureViewerComparator;
import org.eclipse.emf.parsley.ui.provider.FeatureCaptionProvider;
import org.eclipse.emf.parsley.ui.provider.TableFeaturesProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.TableColumn;

Expand Down Expand Up @@ -58,6 +61,9 @@ public class TableViewerColumnBuilder {
@Inject
private LayoutHelper layoutHelper;

@Inject
private GenericFeatureViewerComparator viewerComparator;

/**
* Setups the columns of the given tableViewer using the features of the
* given eClass; the features are retrieved using an injected
Expand All @@ -71,16 +77,18 @@ public void buildTableViewer(TableViewer tableViewer, EClass eClass) {
Layout layout = layoutHelper.adjustForTableLayout(tableViewer);
List<EStructuralFeature> typeFeatures = featuresProvider.getFeatures(eClass);
int i = 0;
tableViewer.setComparator(viewerComparator);
viewerComparator.init(typeFeatures);
for (EStructuralFeature eStructuralFeature : typeFeatures) {
int weight = defaultWeight;
if (weights.size() > i) {
weight = weights.get(i++);
}

buildTableViewerColumn(tableViewer, layout, eClass, eStructuralFeature, weight);
buildTableViewerColumn(tableViewer, layout, eClass, eStructuralFeature, weight, i);
}
}

protected TableViewerColumn buildTableViewerColumn(TableViewer tableViewer, Layout layout, EClass eClass,
EStructuralFeature eStructuralFeature, int weight) {
TableViewerColumn viewerColumn = createTableViewerColumn(tableViewer, eStructuralFeature);
Expand All @@ -92,6 +100,17 @@ protected TableViewerColumn buildTableViewerColumn(TableViewer tableViewer, Layo
return viewerColumn;
}

/**
* @since 1.1
*/
protected TableViewerColumn buildTableViewerColumn(TableViewer tableViewer, Layout layout, EClass eClass,
EStructuralFeature eStructuralFeature, int weight, int colNumber) {
TableViewerColumn viewerColumn = buildTableViewerColumn(tableViewer, layout, eClass, eStructuralFeature, weight);
TableColumn objectColumn = viewerColumn.getColumn();
objectColumn.addSelectionListener(getSelectionAdapter(tableViewer, objectColumn, colNumber));
return viewerColumn;
}

protected TableViewerColumn createTableViewerColumn(
TableViewer tableViewer, EStructuralFeature eStructuralFeature) {
TableViewerColumn tableViewerColumn = new TableViewerColumn(
Expand All @@ -100,4 +119,20 @@ protected TableViewerColumn createTableViewerColumn(
.createColumnLabelProvider(eStructuralFeature));
return tableViewerColumn;
}

private SelectionAdapter getSelectionAdapter(final TableViewer viewer, final TableColumn column,
final int index) {
SelectionAdapter selectionAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
GenericFeatureViewerComparator comparator = (GenericFeatureViewerComparator) viewer.getComparator();
comparator.setPropertyIndex(index);
int dir = comparator.getDirection();
viewer.getTable().setSortDirection(dir);
viewer.getTable().setSortColumn(column);
viewer.refresh();
}
};
return selectionAdapter;
}
}
Expand Up @@ -139,4 +139,10 @@
<eStructuralFeatures xsi:type="ecore:EReference" name="notNullReference" lowerBound="1"
eType="#//ClassWithName"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="ClassForCompare">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="stringAttribute" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="intAttribute" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="bigDecimalAttribute" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="dateAttribute" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EDate"/>
</eClassifiers>
</ecore:EPackage>
@@ -0,0 +1,133 @@
/**
*/
package org.eclipse.emf.parsley.tests.models.testmodels;

import java.math.BigDecimal;
import java.util.Date;
import org.eclipse.emf.ecore.EObject;

/**
* <!-- begin-user-doc -->
* A representation of the model object '<em><b>Class For Compare</b></em>'.
* <!-- end-user-doc -->
*
* <p>
* The following features are supported:
* </p>
* <ul>
* <li>{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getStringAttribute <em>String Attribute</em>}</li>
* <li>{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getIntAttribute <em>Int Attribute</em>}</li>
* <li>{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getBigDecimalAttribute <em>Big Decimal Attribute</em>}</li>
* <li>{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getDateAttribute <em>Date Attribute</em>}</li>
* </ul>
*
* @see org.eclipse.emf.parsley.tests.models.testmodels.TestmodelsPackage#getClassForCompare()
* @model
* @generated
*/
public interface ClassForCompare extends EObject {
/**
* Returns the value of the '<em><b>String Attribute</b></em>' attribute.
* <!-- begin-user-doc -->
* <p>
* If the meaning of the '<em>String Attribute</em>' attribute isn't clear,
* there really should be more of a description here...
* </p>
* <!-- end-user-doc -->
* @return the value of the '<em>String Attribute</em>' attribute.
* @see #setStringAttribute(String)
* @see org.eclipse.emf.parsley.tests.models.testmodels.TestmodelsPackage#getClassForCompare_StringAttribute()
* @model
* @generated
*/
String getStringAttribute();

/**
* Sets the value of the '{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getStringAttribute <em>String Attribute</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param value the new value of the '<em>String Attribute</em>' attribute.
* @see #getStringAttribute()
* @generated
*/
void setStringAttribute(String value);

/**
* Returns the value of the '<em><b>Int Attribute</b></em>' attribute.
* <!-- begin-user-doc -->
* <p>
* If the meaning of the '<em>Int Attribute</em>' attribute isn't clear,
* there really should be more of a description here...
* </p>
* <!-- end-user-doc -->
* @return the value of the '<em>Int Attribute</em>' attribute.
* @see #setIntAttribute(int)
* @see org.eclipse.emf.parsley.tests.models.testmodels.TestmodelsPackage#getClassForCompare_IntAttribute()
* @model
* @generated
*/
int getIntAttribute();

/**
* Sets the value of the '{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getIntAttribute <em>Int Attribute</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param value the new value of the '<em>Int Attribute</em>' attribute.
* @see #getIntAttribute()
* @generated
*/
void setIntAttribute(int value);

/**
* Returns the value of the '<em><b>Big Decimal Attribute</b></em>' attribute.
* <!-- begin-user-doc -->
* <p>
* If the meaning of the '<em>Big Decimal Attribute</em>' attribute isn't clear,
* there really should be more of a description here...
* </p>
* <!-- end-user-doc -->
* @return the value of the '<em>Big Decimal Attribute</em>' attribute.
* @see #setBigDecimalAttribute(BigDecimal)
* @see org.eclipse.emf.parsley.tests.models.testmodels.TestmodelsPackage#getClassForCompare_BigDecimalAttribute()
* @model
* @generated
*/
BigDecimal getBigDecimalAttribute();

/**
* Sets the value of the '{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getBigDecimalAttribute <em>Big Decimal Attribute</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param value the new value of the '<em>Big Decimal Attribute</em>' attribute.
* @see #getBigDecimalAttribute()
* @generated
*/
void setBigDecimalAttribute(BigDecimal value);

/**
* Returns the value of the '<em><b>Date Attribute</b></em>' attribute.
* <!-- begin-user-doc -->
* <p>
* If the meaning of the '<em>Date Attribute</em>' attribute isn't clear,
* there really should be more of a description here...
* </p>
* <!-- end-user-doc -->
* @return the value of the '<em>Date Attribute</em>' attribute.
* @see #setDateAttribute(Date)
* @see org.eclipse.emf.parsley.tests.models.testmodels.TestmodelsPackage#getClassForCompare_DateAttribute()
* @model
* @generated
*/
Date getDateAttribute();

/**
* Sets the value of the '{@link org.eclipse.emf.parsley.tests.models.testmodels.ClassForCompare#getDateAttribute <em>Date Attribute</em>}' attribute.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param value the new value of the '<em>Date Attribute</em>' attribute.
* @see #getDateAttribute()
* @generated
*/
void setDateAttribute(Date value);

} // ClassForCompare
Expand Up @@ -163,6 +163,15 @@ public interface TestmodelsFactory extends EFactory {
*/
ClassForDefaultValidation createClassForDefaultValidation();

/**
* Returns a new object of class '<em>Class For Compare</em>'.
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @return a new object of class '<em>Class For Compare</em>'.
* @generated
*/
ClassForCompare createClassForCompare();

/**
* Returns a new object of class '<em>Test Container</em>'.
* <!-- begin-user-doc -->
Expand Down

0 comments on commit ce908e0

Please sign in to comment.