Bug 385893 - List and Table getSelectionIndex methods are not very
efficient

Change-Id: I37fb4ec2966094befc3152a74e87f073d56003f2
Signed-off-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java
index a25898c..5aeeef2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/DropTarget.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -783,10 +783,9 @@
 	}
 
 	// Get allowed transfer types
-	int length = OS.g_list_length(targets);
 	TransferData[] dataTypes = new TransferData[0];
-	for (int i = 0; i < length; i++) {
-		long /*int*/ pData = OS.g_list_nth_data(targets, i);
+	while (targets != 0) {
+		long /*int*/ pData = OS.g_list_data(targets);
 		TransferData data = new TransferData();
 		data.type = pData;
 		for (int j = 0; j < transferAgents.length; j++) {
@@ -799,6 +798,7 @@
 				break;
 			}
 		}
+		targets = OS.g_list_next (targets);
 	}
 	if (dataTypes.length == 0) return false;
 	long /*int*/ window;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
index 35b33d9..6e74364 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -97,6 +97,7 @@
 		long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, model);
 		if (list == 0) return null;
 		int count = Math.min(10, OS.g_list_length (list));
+		long /*int*/ originalList = list;
 
 		Display display = table.getDisplay();
 		if (count == 1) {
@@ -111,7 +112,7 @@
 			long /*int*/ [] icons = new long /*int*/ [count];
 			GdkRectangle rect = new GdkRectangle ();
 			for (int i=0; i<count; i++) {
-				long /*int*/ path = OS.g_list_nth_data (list, i);
+				long /*int*/ path = OS.g_list_data (list);
 				OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
 				icons[i] = OS.gtk_tree_view_create_row_drag_icon(handle, path);
 				if (OS.GTK3) {
@@ -126,6 +127,7 @@
 				height = rect.y + h[0] - yy[0];
 				yy[i] = rect.y;
 				hh[i] = h[0];
+				list = OS.g_list_next (list);
 				OS.gtk_tree_path_free (path);
 			}
 			if (OS.GTK3) {
@@ -163,7 +165,7 @@
 				dragSourceImage  = Image.gtk_new(display, SWT.ICON, source, mask);
 			}
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		return dragSourceImage;
 	}
 }
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
index 6d5fedd..ffd9f32 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -96,6 +96,7 @@
 		long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, model);
 		if (list == 0) return null;
 		int count = Math.min(10, OS.g_list_length (list));
+		long /*int*/ originalList = list;
 
 		Display display = tree.getDisplay();
 		if (count == 1) {
@@ -110,7 +111,7 @@
 			long /*int*/ [] icons = new long /*int*/ [count];
 			GdkRectangle rect = new GdkRectangle ();
 			for (int i=0; i<count; i++) {
-				long /*int*/ path = OS.g_list_nth_data (list, i);
+				long /*int*/ path = OS.g_list_data (list);
 				OS.gtk_tree_view_get_cell_area (handle, path, 0, rect);
 				icons[i] = OS.gtk_tree_view_create_row_drag_icon(handle, path);
 				if (OS.GTK3) {
@@ -125,6 +126,7 @@
 				height = rect.y + h[0] - yy[0];
 				yy[i] = rect.y;
 				hh[i] = h[0];
+				list = OS.g_list_next (list);
 				OS.gtk_tree_path_free (path);
 			}
 			if (OS.GTK3) {
@@ -162,7 +164,7 @@
 				dragSourceImage  = Image.gtk_new(display, SWT.ICON, source, mask);
 			}
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		return dragSourceImage;
 	}
 }
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
index 00a6a0d..5e702d9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/List.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -616,23 +616,23 @@
 	checkWidget();
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
+	long /*int*/ originalList = list;
 	if (list != 0) {
-		int count = OS.g_list_length (list);
 		int [] index = new int [1];
-		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
-			long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
-			if (indices != 0) {
-				OS.memmove (index, indices, 4);
-				for (int j = i; j < count; j++) {
-					data = OS.g_list_nth_data (list, j);
-					OS.gtk_tree_path_free (data);
+		boolean foundIndex = false;
+		while (list != 0) {
+			long /*int*/ data = OS.g_list_data (list);
+			if (foundIndex == false) {
+				long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
+				if (indices !=0) {
+					OS.memmove (index, indices, 4);
+					foundIndex = true;
 				}
-				break;
 			}
+			list = OS.g_list_next (list);
 			OS.gtk_tree_path_free (data);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		return index [0];
 	}
 	return -1;
@@ -658,12 +658,13 @@
 	checkWidget();
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
+	long /*int*/ originalList = list;
 	if (list != 0) {
 		int count = OS.g_list_length (list);
 		int [] treeSelection = new int [count];
 		int length = 0;
 		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
+			long /*int*/ data = OS.g_list_data (list);
 			long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
 			if (indices != 0) {
 				int [] index = new int [1];
@@ -672,8 +673,9 @@
 				length++;
 			}
 			OS.gtk_tree_path_free (data);
+			list = OS.g_list_next (list);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		int [] result = new int [length];
 		System.arraycopy (treeSelection, 0, result, 0, length);
 		return result;
@@ -689,18 +691,17 @@
 		list = OS.gtk_tree_view_column_get_cell_renderers (column);
 	}
 	if (list == 0) return 0;
-	int count = OS.g_list_length (list);
+	long /*int*/ originalList = list;
 	long /*int*/ textRenderer = 0;
-	int i = 0;
-	while (i < count) {
-		long /*int*/ renderer = OS.g_list_nth_data (list, i);
-		 if (OS.GTK_IS_CELL_RENDERER_TEXT (renderer)) {
+	while (list != 0) {
+		long /*int*/ renderer = OS.g_list_data (list);
+		if (OS.GTK_IS_CELL_RENDERER_TEXT (renderer)) {
 			textRenderer = renderer;
 			break;
 		}
-		i++;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	return textRenderer;
 }
 
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
index caeace7..275737b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Menu.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -492,20 +492,22 @@
 	checkWidget();
 	long /*int*/ list = OS.gtk_container_get_children (handle);
 	if (list == 0) return new MenuItem [0];
+	long /*int*/ originalList = list;
 	int count = OS.g_list_length (list);
 	if (imSeparator != 0) count--;
 	if (imItem != 0) count--;
 	MenuItem [] items = new MenuItem [count];
 	int index = 0;
 	for (int i=0; i<count; i++) {
-		long /*int*/ data = OS.g_list_nth_data (list, i);
+		long /*int*/ data = OS.g_list_data (list);
 		MenuItem item = (MenuItem) display.getWidget (data);
-		if (item != null) items [index++] = item; 
+		if (item != null) items [index++] = item;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	if (index != items.length) {
-		MenuItem [] newItems = new MenuItem[index];
-		System.arraycopy(items, 0, newItems, 0, index);
+		MenuItem [] newItems = new MenuItem [index];
+		System.arraycopy (items, 0, newItems, 0, index);
 		items = newItems;
 	}
 	return items;
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 2558fd1..c1c5a32 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
@@ -1610,18 +1610,17 @@
 	}
 	
 	if (list == 0) return 0;
-	int count = OS.g_list_length (list);
+	long /*int*/ originalList = list;
 	long /*int*/ pixbufRenderer = 0;
-	int i = 0;
-	while (i < count) {
-		long /*int*/ renderer = OS.g_list_nth_data (list, i);
-		 if (OS.GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
+	while (list != 0) {
+		long /*int*/ renderer = OS.g_list_data (list);
+		if (OS.GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
 			pixbufRenderer = renderer;
 			break;
 		}
-		i++;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	return pixbufRenderer;
 }
 
@@ -1645,12 +1644,13 @@
 	checkWidget();
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
+	long /*int*/ originalList = list;
 	if (list != 0) {
 		int count = OS.g_list_length (list);
 		int [] treeSelection = new int [count];
 		int length = 0;
 		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
+			long /*int*/ data = OS.g_list_data (list);
 			long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
 			if (indices != 0) {
 				int [] index = new int [1];
@@ -1659,8 +1659,9 @@
 				length++;
 			}
 			OS.gtk_tree_path_free (data);
+			list = OS.g_list_next (list);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		TableItem [] result = new TableItem [length];
 		for (int i=0; i<result.length; i++) result [i] = _getItem (treeSelection [i]);
 		return result;
@@ -1699,23 +1700,23 @@
 	checkWidget();
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
+	long /*int*/ originalList = list;
 	if (list != 0) {
-		int count = OS.g_list_length (list);
 		int [] index = new int [1];
-		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
-			long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
-			if (indices != 0) {
-				OS.memmove (index, indices, 4);
-				for (int j = i; j < count; j++) {
-					data = OS.g_list_nth_data (list, j);
-					OS.gtk_tree_path_free (data);
+		boolean foundIndex = false;
+		while (list != 0) {
+			long /*int*/ data = OS.g_list_data (list);
+			if (foundIndex == false) {
+				long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
+				if (indices != 0) {
+					OS.memmove (index, indices, 4);
+					foundIndex = true;
 				}
-				break;
 			}
+			list = OS.g_list_next (list);
 			OS.gtk_tree_path_free (data);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		return index [0];
 	}
 	return -1;
@@ -1741,12 +1742,13 @@
 	checkWidget();
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
+	long /*int*/ originalList = list;
 	if (list != 0) {
 		int count = OS.g_list_length (list);
 		int [] treeSelection = new int [count];
 		int length = 0;
 		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
+			long /*int*/ data = OS.g_list_data (list);
 			long /*int*/ indices = OS.gtk_tree_path_get_indices (data);
 			if (indices != 0) {
 				int [] index = new int [1];
@@ -1754,9 +1756,10 @@
 				treeSelection [length] = index [0];
 				length++;
 			}
+			list = OS.g_list_next (list);
 			OS.gtk_tree_path_free (data);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		int [] result = new int [length];
 		System.arraycopy (treeSelection, 0, result, 0, length);
 		return result;
@@ -1814,18 +1817,17 @@
 		list = OS.gtk_tree_view_column_get_cell_renderers (column);
 	}
 	if (list == 0) return 0;
-	int count = OS.g_list_length (list);
+	long /*int*/ originalList = list;
 	long /*int*/ textRenderer = 0;
-	int i = 0;
-	while (i < count) {
-		long /*int*/ renderer = OS.g_list_nth_data (list, i);
+	while (list != 0) {
+		long /*int*/ renderer = OS.g_list_data (list);
 		 if (OS.GTK_IS_CELL_RENDERER_TEXT (renderer)) {
 			textRenderer = renderer;
 			break;
 		}
-		i++;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	return textRenderer;
 }
 
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java
index fe6cabf..e215d6e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolBar.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -362,13 +362,15 @@
 	if (list == 0) return new ToolItem [0];
 	int count = OS.g_list_length (list);
 	ToolItem [] items = new ToolItem [count];
+	long /*int*/ originalList = list;
 	int index = 0;
 	for (int i=0; i<count; i++) {
-		long /*int*/ data = OS.g_list_nth_data (list, i);
+		long /*int*/ data = OS.g_list_data (list);
 		Widget widget = display.getWidget (data);
 		if (widget != null) items [index++] = (ToolItem) widget;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	if (index != items.length) {
 		ToolItem [] newItems = new ToolItem [index];
 		System.arraycopy (items, 0, newItems, 0, index);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index 4603cff..ebb2b4d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation 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
@@ -1659,18 +1659,17 @@
 		list = OS.gtk_tree_view_column_get_cell_renderers (column);
 	}
 	if (list == 0) return 0;
-	int count = OS.g_list_length (list);
+	long /*int*/ originalList = list;
 	long /*int*/ pixbufRenderer = 0;
-	int i = 0;
-	while (i < count) {
-		long /*int*/ renderer = OS.g_list_nth_data (list, i);
-		 if (OS.GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
+	while (list != 0) {
+		long /*int*/ renderer = OS.g_list_data (list);
+		if (OS.GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
 			pixbufRenderer = renderer;
 			break;
 		}
-		i++;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	return pixbufRenderer;
 }
 
@@ -1695,20 +1694,22 @@
 	long /*int*/ selection = OS.gtk_tree_view_get_selection (handle);
 	long /*int*/ list = OS.gtk_tree_selection_get_selected_rows (selection, null);
 	if (list != 0) {
+		long /*int*/ originalList = list;
 		int count = OS.g_list_length (list);
 		TreeItem [] treeSelection = new TreeItem [count];
 		int length = 0;
 		for (int i=0; i<count; i++) {
-			long /*int*/ data = OS.g_list_nth_data (list, i);
+			long /*int*/ data = OS.g_list_data (list);
 			long /*int*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof ());
 			if (OS.gtk_tree_model_get_iter (modelHandle, iter, data)) {
 				treeSelection [length] = _getItem (iter);
 				length++;
 			}
+			list = OS.g_list_next (list);
 			OS.g_free (iter);
 			OS.gtk_tree_path_free (data);
 		}
-		OS.g_list_free (list);
+		OS.g_list_free (originalList);
 		if (length < count) {
 			TreeItem [] temp = new TreeItem [length];
 			System.arraycopy(treeSelection, 0, temp, 0, length);
@@ -1785,18 +1786,17 @@
 		list = OS.gtk_tree_view_column_get_cell_renderers (column);
 	}
 	if (list == 0) return 0;
-	int count = OS.g_list_length (list);
+	long /*int*/ originalList = list;
 	long /*int*/ textRenderer = 0;
-	int i = 0;
-	while (i < count) {
-		long /*int*/ renderer = OS.g_list_nth_data (list, i);
-		 if (OS.GTK_IS_CELL_RENDERER_TEXT (renderer)) {
+	while (list != 0) {
+		long /*int*/ renderer = OS.g_list_data (list);
+		if (OS.GTK_IS_CELL_RENDERER_TEXT (renderer)) {
 			textRenderer = renderer;
 			break;
 		}
-		i++;
+		list = OS.g_list_next (list);
 	}
-	OS.g_list_free (list);
+	OS.g_list_free (originalList);
 	return textRenderer;
 }