Bug 127132 - [GTK] TableColumn#pack does not work for virtual table

Added padding for calculating TableColumn width. Modified pack method
for TableColumn to calculate size based on what is displayed for virtual
tables.

All tests in AllNonBrowserTests passed.

Change-Id: I45a3e7b993e83cff6afe4abfe4a11c91a93128e9
Signed-off-by: Xi Yan <xixiyan@redhat.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index f532ca6..354719a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -346,7 +346,10 @@
 	if (GTK.GTK3) {
 		int [] width = new int [1];
 		GTK.gtk_tree_view_column_cell_get_size (column, null, null, null, width, null);
-		return width [0];
+		long /*int*/ textRenderer = getTextRenderer (column);
+		int [] xpad = new int[1];
+		if (textRenderer != 0) GTK.gtk_cell_renderer_get_padding(textRenderer, xpad, null);
+		return width [0] + xpad [0]*2;
 	} else {
 		int width = 0;
 		int [] w = new int [1];
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
index 5c407cc..bb5ac91 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TableColumn.java
@@ -451,9 +451,25 @@
 		width = requisition.width;
 	}
 	if ((parent.style & SWT.VIRTUAL) != 0) {
+		boolean calcWidth = false;
+		Rectangle itemBounds = null;
+		int tableHeight = 0;
+		if (parent.isVisible()) {
+			Rectangle tableBounds = parent.getBounds();
+			tableHeight = tableBounds.height - parent.getHeaderHeight();
+		} else {
+			calcWidth = true;
+		}
 		for (int i=0; i<parent.items.length; i++) {
 			TableItem item = parent.items [i];
-			if (item != null && item.cached) {
+			if (itemBounds == null) itemBounds = item.getBounds();
+			boolean isVisible = false;
+			if (!calcWidth) {
+				int itemTopBound = itemBounds.y + itemBounds.height * i + i;
+				int itemBottomBound = itemTopBound + itemBounds.height;
+				isVisible = (itemTopBound > 0 && itemBottomBound < tableHeight);
+			}
+			if (item != null && item.cached && (isVisible || calcWidth)) {
 				width = Math.max (width, parent.calculateWidth (handle, item.handle));
 			}
 		}
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug127132_TableColumnPackVirtual.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug127132_TableColumnPackVirtual.java
index cf60163..5b626db 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug127132_TableColumnPackVirtual.java
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug127132_TableColumnPackVirtual.java
@@ -12,8 +12,6 @@
 
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -39,20 +37,27 @@
 			Shell shell = new Shell(display);
 			shell.setLayout(new GridLayout());
 
-
-
 			final Table table = new Table(shell, SWT.BORDER | SWT.MULTI | SWT.VIRTUAL);
 			table.setLayoutData(new GridData(GridData.FILL_BOTH));
 			column1 = new TableColumn(table, SWT.NONE);
 			column1.setText("A");
 			column2 = new TableColumn(table, SWT.NONE);
-			column1.setText("B");
+			column2.setText("B");
 			column3 = new TableColumn(table, SWT.NONE);
-			column1.setText("C");
+			column3.setText("C");
+
+			table.setLinesVisible (true);
+			table.setHeaderVisible (true);
 
 			for (int i = 0; i < 500; i++) {
 				TableItem item = new TableItem(table, SWT.NONE);
-				item.setText(new String[] { "cell "+i+" 0", "cell "+i+" 1", "cell "+i+" 2"});
+				if (i < 200) {
+					item.setText(new String[] { "cell "+i+" 0", "medium cell "+i+" 1", "cell "+i+" 2"});
+				} else if (i < 300) {
+					item.setText(new String[] { "medium cell "+i+" 0", "medium cell "+i+" 1", "medium cell "+i+" 2"});
+				} else {
+					item.setText(new String[] { "this is a long cell "+i+" 0", "this is a long cell "+i+" 1", "this is a long cell "+i+" 2"});
+				}
 			}
 
 			// These have no effects on Linux GTK?
@@ -62,21 +67,11 @@
 
 			Button action = new Button(shell, SWT.PUSH);
 			action.setText("Pack Columns");
-			action.addSelectionListener(new SelectionListener() {
-
-				@Override
-				public void widgetSelected(SelectionEvent e) {
-					// These have no effects on Linux GTK?
-					column1.pack();
-					column2.pack();
-					column3.pack();
-				}
-
-				@Override
-				public void widgetDefaultSelected(SelectionEvent e) {
-
-
-				}});
+			action.addListener(SWT.Selection,  e -> {
+				column1.pack();
+				column2.pack();
+				column3.pack();
+			});
 
 			shell.open();
 			while (!shell.isDisposed()) {