Render column order in protocol

Column order will be needed by the client for footer span
implementation.

Change-Id: I9c1b654bc633b0193e11e7a7dc29b08efafbf4dd
Signed-off-by: Ivan Furnadjiev <ivan@eclipsesource.com>
diff --git a/bundles/org.eclipse.rap.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA.java b/bundles/org.eclipse.rap.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA.java
index b40fbce..01466b2 100644
--- a/bundles/org.eclipse.rap.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA.java
+++ b/bundles/org.eclipse.rap.nebula.widgets.grid/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA.java
@@ -59,6 +59,7 @@
   private static final String PROP_ITEM_HEIGHT = "itemHeight";
   private static final String PROP_ITEM_METRICS = "itemMetrics";
   private static final String PROP_COLUMN_COUNT = "columnCount";
+  private static final String PROP_COLUMN_ORDER = "columnOrder";
   private static final String PROP_TREE_COLUMN = "treeColumn";
   private static final String PROP_HEADER_HEIGHT = "headerHeight";
   private static final String PROP_HEADER_VISIBLE = "headerVisible";
@@ -85,6 +86,7 @@
 
   private static final int ZERO = 0 ;
   private static final String[] DEFAULT_SELECTION = new String[ 0 ];
+  private static final String[] DEFAULT_COLUMN_ORDER = new String[ 0 ];
   private static final String DEFAULT_SORT_DIRECTION = "none";
 
   @Override
@@ -116,6 +118,7 @@
     preserveProperty( grid, PROP_ITEM_HEIGHT, grid.getItemHeight() );
     preserveProperty( grid, PROP_ITEM_METRICS, getItemMetrics( grid ) );
     preserveProperty( grid, PROP_COLUMN_COUNT, grid.getColumnCount() );
+    preserveProperty( grid, PROP_COLUMN_ORDER, getColumnOrder( grid ) );
     preserveProperty( grid, PROP_TREE_COLUMN, getTreeColumn( grid ) );
     preserveProperty( grid, PROP_HEADER_HEIGHT, grid.getHeaderHeight() );
     preserveProperty( grid, PROP_HEADER_VISIBLE, grid.getHeaderVisible() );
@@ -149,6 +152,7 @@
     renderProperty( grid, PROP_ITEM_HEIGHT, grid.getItemHeight(), ZERO );
     renderItemMetrics( grid );
     renderProperty( grid, PROP_COLUMN_COUNT, grid.getColumnCount(), ZERO );
+    renderProperty( grid, PROP_COLUMN_ORDER, getColumnOrder( grid ), DEFAULT_COLUMN_ORDER );
     renderProperty( grid, PROP_TREE_COLUMN, getTreeColumn( grid ), ZERO );
     renderProperty( grid, PROP_HEADER_HEIGHT, grid.getHeaderHeight(), ZERO );
     renderProperty( grid, PROP_HEADER_VISIBLE, grid.getHeaderVisible(), false );
@@ -249,6 +253,15 @@
     return result;
   }
 
+  private static String[] getColumnOrder( Grid grid ) {
+    int[] order = grid.getColumnOrder();
+    String[] result = new String[ order.length ];
+    for( int i = 0; i < result.length; i++ ) {
+      result[ i ] = getId( grid.getColumn( order[ i ] ) );
+    }
+    return result;
+  }
+
   @SuppressWarnings( "unused" )
   private static boolean hasExpandListener( Grid grid ) {
     // Always render listen for Expand and Collapse, currently required for scrollbar
diff --git a/tests/org.eclipse.rap.nebula.widgets.grid.test/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA_Test.java b/tests/org.eclipse.rap.nebula.widgets.grid.test/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA_Test.java
index f3ec7e3..d84ac5a 100644
--- a/tests/org.eclipse.rap.nebula.widgets.grid.test/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA_Test.java
+++ b/tests/org.eclipse.rap.nebula.widgets.grid.test/src/org/eclipse/nebula/widgets/grid/internal/gridkit/GridLCA_Test.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -46,7 +47,6 @@
 import org.eclipse.rap.rwt.testfixture.Fixture;
 import org.eclipse.rap.rwt.testfixture.TestMessage;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.internal.widgets.CellToolTipUtil;
@@ -54,6 +54,7 @@
 import org.eclipse.swt.internal.widgets.ICellToolTipProvider;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Listener;
 import org.eclipse.swt.widgets.ScrollBar;
 import org.eclipse.swt.widgets.Shell;
 import org.junit.After;
@@ -295,6 +296,44 @@
   }
 
   @Test
+  public void testRenderInitialColumnOrder() throws IOException {
+    lca.render( grid );
+
+    TestMessage message = Fixture.getProtocolMessage();
+    CreateOperation operation = message.findCreateOperation( grid );
+    assertTrue( operation.getProperties().names().indexOf( "columnOrder" ) == -1 );
+  }
+
+  @Test
+  public void testRenderColumnOrder() throws IOException {
+    GridColumn[] columns = createGridColumns( grid, 3, SWT.NONE );
+    grid.setColumnOrder( new int[] { 2, 0, 1 } );
+
+    lca.renderChanges( grid );
+
+    TestMessage message = Fixture.getProtocolMessage();
+    JsonArray expected = new JsonArray()
+      .add( getId( columns[ 2 ] ) )
+      .add( getId( columns[ 0 ] ) )
+      .add( getId( columns[ 1 ] ) );
+    assertEquals( expected, message.findSetProperty( grid, "columnOrder" ) );
+  }
+
+  @Test
+  public void testRenderColumnOrderUnchanged() throws IOException {
+    Fixture.markInitialized( display );
+    Fixture.markInitialized( grid );
+    createGridColumns( grid, 3, SWT.NONE );
+    grid.setColumnOrder( new int[] { 2, 0, 1 } );
+
+    Fixture.preserveWidgets();
+    lca.renderChanges( grid );
+
+    TestMessage message = Fixture.getProtocolMessage();
+    assertNull( message.findSetOperation( grid, "columnOrder" ) );
+  }
+
+  @Test
   public void testRenderInitialTreeColumn() throws IOException {
     createGridColumns( grid, 2, SWT.NONE );
 
@@ -774,7 +813,7 @@
     Fixture.markInitialized( hScroll );
     Fixture.preserveWidgets();
 
-    hScroll.addSelectionListener( new SelectionAdapter() { } );
+    hScroll.addListener( SWT.Selection, mock( Listener.class ) );
     lca.renderChanges( grid );
 
     TestMessage message = Fixture.getProtocolMessage();
@@ -784,14 +823,14 @@
   @Test
   public void testRenderRemoveScrollBarsSelectionListener_Horizontal() throws Exception {
     ScrollBar hScroll = grid.getHorizontalBar();
-    SelectionListener listener = new SelectionAdapter() { };
-    hScroll.addSelectionListener( listener );
+    Listener listener = mock( Listener.class );
+    hScroll.addListener( SWT.Selection, listener );
     Fixture.markInitialized( display );
     Fixture.markInitialized( grid );
     Fixture.markInitialized( hScroll );
     Fixture.preserveWidgets();
 
-    hScroll.removeSelectionListener( listener );
+    hScroll.removeListener( SWT.Selection, listener );
     lca.renderChanges( grid );
 
     TestMessage message = Fixture.getProtocolMessage();
@@ -806,7 +845,7 @@
     Fixture.markInitialized( hScroll );
     Fixture.preserveWidgets();
 
-    hScroll.addSelectionListener( new SelectionAdapter() { } );
+    hScroll.addListener( SWT.Selection, mock( Listener.class ) );
     Fixture.preserveWidgets();
     lca.renderChanges( grid );
 
@@ -822,7 +861,7 @@
     Fixture.markInitialized( vScroll );
     Fixture.preserveWidgets();
 
-    vScroll.addSelectionListener( new SelectionAdapter() { } );
+    vScroll.addListener( SWT.Selection, mock( Listener.class ) );
     lca.renderChanges( grid );
 
     TestMessage message = Fixture.getProtocolMessage();
@@ -832,14 +871,14 @@
   @Test
   public void testRenderRemoveScrollBarsSelectionListener_Vertical() throws Exception {
     ScrollBar vScroll = grid.getVerticalBar();
-    SelectionListener listener = new SelectionAdapter() { };
-    vScroll.addSelectionListener( listener );
+    Listener listener = mock( Listener.class );
+    vScroll.addListener( SWT.Selection, listener );
     Fixture.markInitialized( display );
     Fixture.markInitialized( grid );
     Fixture.markInitialized( vScroll );
     Fixture.preserveWidgets();
 
-    vScroll.removeSelectionListener( listener );
+    vScroll.removeListener( SWT.Selection, listener );
     lca.renderChanges( grid );
 
     TestMessage message = Fixture.getProtocolMessage();
@@ -854,7 +893,7 @@
     Fixture.markInitialized( vScroll );
     Fixture.preserveWidgets();
 
-    vScroll.addSelectionListener( new SelectionAdapter() { } );
+    vScroll.addListener( SWT.Selection, mock( Listener.class ) );
     Fixture.preserveWidgets();
     lca.renderChanges( grid );
 
@@ -868,7 +907,7 @@
     Fixture.markInitialized( grid );
     Fixture.preserveWidgets();
 
-    grid.addSelectionListener( new SelectionAdapter() { } );
+    grid.addSelectionListener( mock( SelectionListener.class ) );
     lca.renderChanges( grid );
 
     TestMessage message = Fixture.getProtocolMessage();
@@ -878,7 +917,7 @@
 
   @Test
   public void testRenderRemoveSelectionListener() throws Exception {
-    SelectionListener listener = new SelectionAdapter() { };
+    SelectionListener listener = mock( SelectionListener.class );
     grid.addSelectionListener( listener );
     Fixture.markInitialized( display );
     Fixture.markInitialized( grid );
@@ -898,7 +937,7 @@
     Fixture.markInitialized( grid );
     Fixture.preserveWidgets();
 
-    grid.addSelectionListener( new SelectionAdapter() { } );
+    grid.addSelectionListener( mock( SelectionListener.class ) );
     Fixture.preserveWidgets();
     lca.renderChanges( grid );