chiark / gitweb /
Move track sorting to its own function. Only choose_populate() uses
authorRichard Kettlewell <rjk@greenend.org.uk>
Fri, 13 Jun 2008 13:01:57 +0000 (14:01 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Fri, 13 Jun 2008 13:01:57 +0000 (14:01 +0100)
it currently (and has some work left); the CGI will be modified to use
it in due course.

cgi/actions.c
cgi/macros-disorder.c
disobedience/choose.c
lib/Makefile.am
lib/trackname.h
lib/tracksort.c [new file with mode: 0644]

index e9995b9..449c5dc 100644 (file)
@@ -248,6 +248,7 @@ static void act_play(void) {
     } else if((dir = cgi_get("dir"))) {
       if(disorder_files(dcgi_client, dir, 0, &tracks, &ntracks))
         ntracks = 0;
+      /* TODO use tracksort_init */
       e = xmalloc(ntracks * sizeof (struct dcgi_entry));
       for(n = 0; n < ntracks; ++n) {
         e[n].track = tracks[n];
index d549e10..8e891d6 100644 (file)
@@ -855,6 +855,7 @@ static int exp__files_dirs(int nargs,
   if(fn(dcgi_client, dir, re, &tracks, &ntracks))
     return 0;
   /* Sort it.  NB trackname_transform() does not go to the server. */
+  /* TODO use tracksort_init */
   e = xcalloc(ntracks, sizeof *e);
   for(n = 0; n < ntracks; ++n) {
     e[n].track = tracks[n];
index 88b7c62..781b415 100644 (file)
@@ -165,6 +165,7 @@ static void choose_set_state(const char attribute((unused)) *event,
 static void choose_populate(GtkTreeRowReference *parent_ref,
                             int nvec, char **vec,
                             int isfile) {
+  const char *type = isfile ? "track" : "dir";
   /* Compute parent_* */
   GtkTreeIter pit[1], *parent_it;
   GtkTreePath *parent_path;
@@ -175,17 +176,17 @@ static void choose_populate(GtkTreeRowReference *parent_ref,
                                             pit, parent_path);
     assert(pitv);
     /*fprintf(stderr, "choose_populate %s: parent path is [%s]\n",
-            choose_type_map[type],
+            type,
             gtk_tree_path_to_string(parent_path));*/
   } else {
     parent_path = 0;
     parent_it = 0;
     /*fprintf(stderr, "choose_populate %s: populating the root\n",
-            choose_type_map[type]);*/
+            type);*/
   }
   /* Remove unwanted nodes and find out which we must add */
-  //fprintf(stderr, " trimming unwanted %s nodes\n", choose_type_map[type]);
-  char *found = xmalloc(nvec);
+  //fprintf(stderr, " trimming unwanted %s nodes\n", type);
+  struct tracksort_data *td = tracksort_init(nvec, vec, type);
   GtkTreeIter it[1];
   gboolean itv = gtk_tree_model_iter_children(GTK_TREE_MODEL(choose_store),
                                               it,
@@ -200,13 +201,13 @@ static void choose_populate(GtkTreeRowReference *parent_ref,
       keep = 0;
     } else if(choose_is_file(it) == isfile) {
       /* This is the type we care about */
-      //fprintf(stderr, "  %s is a %s\n", track, isfile ? "file" : "dir");
+      //fprintf(stderr, "  %s is a %s\n", track, type);
       int n;
-      for(n = 0; n < nvec && strcmp(vec[n], track); ++n)
+      for(n = 0; n < nvec && strcmp(td[n].track, track); ++n)
         ;
       if(n < nvec) {
         //fprintf(stderr, "   ... and survives\n");
-        found[n] = 1;
+        td[n].extra = td;
         keep = 1;
       } else {
         //fprintf(stderr, "   ... and is to be removed\n");
@@ -224,21 +225,16 @@ static void choose_populate(GtkTreeRowReference *parent_ref,
   }
   /* Add nodes we don't have */
   int inserted = 0;
-  //fprintf(stderr, " inserting new %s nodes\n", isfile ? "track" : "dir");
-  const char *typename = isfile ? "track" : "dir";
+  //fprintf(stderr, " inserting new %s nodes\n", type);
   for(int n = 0; n < nvec; ++n) {
-    if(!found[n]) {
-      //fprintf(stderr, "  %s was not found\n", vec[n]);
+    if(!td[n].extra) {
+      //fprintf(stderr, "  %s was not found\n", td[n].track);
       gtk_tree_store_append(choose_store, it, parent_it);
       gtk_tree_store_set(choose_store, it,
-                         NAME_COLUMN, trackname_transform(typename,
-                                                          vec[n],
-                                                          "display"),
+                         NAME_COLUMN, td[n].display,
                          ISFILE_COLUMN, isfile,
-                         TRACK_COLUMN, vec[n],
-                         SORT_COLUMN, trackname_transform(typename,
-                                                          vec[n],
-                                                          "sort"),
+                         TRACK_COLUMN, td[n].track,
+                         SORT_COLUMN, td[n].sort,
                          -1);
       /* Update length and state; we expect this to kick off length lookups
        * rather than necessarily get the right value the first time round. */
index 2c0d334..86886eb 100644 (file)
@@ -80,6 +80,7 @@ libdisorder_a_SOURCES=charset.c charset.h             \
        timeval.h                                       \
        $(TRACKDB) trackdb.h trackdb-int.h              \
        trackname.c trackorder.c trackname.h            \
+       tracksort.c                                     \
        url.h url.c                                     \
        user.h user.c                                   \
        unicode.h unicode.c                             \
index 129e1b5..943e866 100644 (file)
@@ -57,6 +57,22 @@ static inline int compare_path(const char *ap, const char *bp) {
                          (const unsigned char *)bp, strlen(bp));
 }
 
+/** @brief Entry in a list of tracks or directories */
+struct tracksort_data {
+  /** @brief Track name */
+  const char *track;
+  /** @brief Sort key */
+  const char *sort;
+  /** @brief Display key */
+  const char *display;
+  /** @brief Extra data for callers */
+  void *extra;
+};
+
+struct tracksort_data *tracksort_init(int nvec,
+                                      char **vec,
+                                      const char *type);
+
 #endif /* TRACKNAME_H */
 
 /*
diff --git a/lib/tracksort.c b/lib/tracksort.c
new file mode 100644 (file)
index 0000000..ded4c84
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This file is part of DisOrder
+ * Copyright (C) 2008 Richard Kettlewell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include "common.h"
+
+#include "trackname.h"
+#include "mem.h"
+
+/** @brief Compare two @ref entry objects */
+static int tracksort_compare(const void *a, const void *b) {
+  const struct tracksort_data *ea = a, *eb = b;
+
+  return compare_tracks(ea->sort, eb->sort,
+                       ea->display, eb->display,
+                       ea->track, eb->track);
+}
+
+struct tracksort_data *tracksort_init(int ntracks,
+                                      char **tracks,
+                                      const char *type) {
+  struct tracksort_data *td = xcalloc(ntracks, sizeof *td);
+  for(int n = 0; n < ntracks; ++n) {
+    td[n].track = tracks[n];
+    td[n].sort = trackname_transform(type, tracks[n], "sort");
+    td[n].display = trackname_transform(type, tracks[n], "display");
+  }
+  qsort(td, ntracks, sizeof *td, tracksort_compare);
+  return td;
+}
+
+/*
+Local Variables:
+c-basic-offset:2
+comment-column:40
+fill-column:79
+indent-tabs-mode:nil
+End:
+*/