Hi all,
I had some time on my hands the other day and wrote a sort routine into
the fileselector code in ewl.  It's pretty dang fast, it uses qsort to
speed things up.  The ls command also uses qsort, so it's just about as
fast as ls.
It does use a bit more memory but only while it's doing the sort.  It
eventually frees it all.

So here it is for your comments/suggestions.  I've always had a bit of
trouble keeping track of my mallocs and frees, so someone might want to
make sure i'm freeing everything so that I don't have any dangling
pointers.
diff -ur ewl.current/src/lib/ewl_fileselector.c ewl/src/lib/ewl_fileselector.c
--- ewl.current/src/lib/ewl_fileselector.c	2005-05-06 13:50:07.337808238 -0400
+++ ewl/src/lib/ewl_fileselector.c	2005-05-06 13:50:18.555739879 -0400
@@ -32,7 +32,7 @@
 					void *ev_data, void *user_data);
 static void ewl_fileselector_file_data_cleanup_cb(Ewl_Widget *entry, 
 					void *ev_data, void *user_data);
-
+static void _ewl_fileselector_sort_lists(Ecore_List *files, Ecore_List *dirs);
 /**
  * @return Returns NULL on failure, or the new fileselector on success.
  * @brief Create a new fileselector
@@ -510,6 +510,9 @@
 		regfree(&dreg);
 	free(path2);
 
+  /* call the sort function */
+  _ewl_fileselector_sort_lists(flist, dlist);
+
 	return;
 }
 
@@ -800,3 +803,86 @@
 	v = ewl_widget_data_get(w, "FILESELECTOR_DIR");
 	IF_FREE(v);
 }
+static int _ewl_fileselector_comp_cb(const void *a, const void *b)
+{
+  struct list_element {
+            int idx;
+            char *name;
+       };
+
+  struct list_element *ia = (struct list_element *)a;
+  struct list_element *ib = (struct list_element *)b;
+  return strcmp(ia->name, ib->name);
+}
+
+static int _ewl_fileselector_sort_list(Ecore_List *list)
+{
+
+  /* Ok, this is gonna look a bit ugly, but it should be 
+   * just about as fast as ls and the sort it does
+   * WARNING: only use for Ewl_Fileselector_Data structs in Ecore_Lists
+   */
+
+  /* first, dump the file names into an array of strings */
+  int array_idx=0;
+  Ewl_Fileselector_Data *current=NULL, *tmp=NULL;
+  
+  /* only sort the list if there is more than 1 element */
+  if(!ecore_list_is_empty(list) && ecore_list_nodes(list) > 1){
+    /* go to the beginning of the list */
+    ecore_list_goto_first(list);
+
+    /* the struct we are going to use. */
+    struct list_element {
+              int idx;
+              char *name;
+         };
+    struct list_element *array_tmp;
+    /* create our temp string array */
+    
+    array_tmp=(struct list_element *)malloc((sizeof(struct list_element)*ecore_list_nodes(list))+1);
+    /* walk the list and insert the names of the files into the array */
+    int i=0;
+    for(i=0; i<ecore_list_nodes(list); i++) //while(files->current->next)
+    {
+      current=(Ewl_Fileselector_Data *)list->current->data;
+      array_tmp[array_idx].name = (char *)malloc(strlen(current->name)+1);
+      strcpy(array_tmp[array_idx].name, current->name);
+      array_tmp[array_idx].idx = ecore_list_index(list);
+      ecore_list_next(list);
+      array_idx++;
+    }
+    /* call qsort with the strcoll function to sort the array */
+    qsort(array_tmp, array_idx, sizeof(struct list_element), _ewl_fileselector_comp_cb);
+    /* insert a null record for a place holder. */
+    for(i=0; i<array_idx; i++){
+      /* jump to the record we are moving */
+      ecore_list_goto_index(list, array_tmp[i].idx);
+      /* remove the item and grab the data */
+      tmp = ecore_list_remove(list);    
+      /* jump to the placeholder */
+      ecore_list_goto_index(list, i);
+      /* re-insert the record at the end of the sorted data */
+      ecore_list_insert(list, tmp);
+      /* adjust the ids for the remaining elements */
+      int j=i+1;
+      for(j=i+1; j<array_idx; j++){
+        if(array_tmp[j].idx < array_tmp[i].idx)
+          array_tmp[j].idx++;
+      }
+      IF_FREE(array_tmp[i].name);
+    } 
+    IF_FREE(array_tmp);
+        
+}
+  return;
+  
+
+}
+static void _ewl_fileselector_sort_lists(Ecore_List *files, Ecore_List *dirs)
+{
+
+  _ewl_fileselector_sort_list(files);
+  _ewl_fileselector_sort_list(dirs);
+
+}

Reply via email to