From 2fadbbc60560fe8562d7b6e652f8788c1d084d5f Mon Sep 17 00:00:00 2001 Message-Id: <2fadbbc60560fe8562d7b6e652f8788c1d084d5f.1714978423.git.mdw@distorted.org.uk> From: Mark Wooding Date: Fri, 13 Jun 2008 14:01:57 +0100 Subject: [PATCH 1/1] Move track sorting to its own function. Only choose_populate() uses it currently (and has some work left); the CGI will be modified to use it in due course. Organization: Straylight/Edgeware From: Richard Kettlewell --- cgi/actions.c | 1 + cgi/macros-disorder.c | 1 + disobedience/choose.c | 32 +++++++++++-------------- lib/Makefile.am | 1 + lib/trackname.h | 16 +++++++++++++ lib/tracksort.c | 54 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 lib/tracksort.c diff --git a/cgi/actions.c b/cgi/actions.c index e9995b9..449c5dc 100644 --- a/cgi/actions.c +++ b/cgi/actions.c @@ -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]; diff --git a/cgi/macros-disorder.c b/cgi/macros-disorder.c index d549e10..8e891d6 100644 --- a/cgi/macros-disorder.c +++ b/cgi/macros-disorder.c @@ -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]; diff --git a/disobedience/choose.c b/disobedience/choose.c index 88b7c62..781b415 100644 --- a/disobedience/choose.c +++ b/disobedience/choose.c @@ -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. */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 2c0d334..86886eb 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 \ diff --git a/lib/trackname.h b/lib/trackname.h index 129e1b5..943e866 100644 --- a/lib/trackname.h +++ b/lib/trackname.h @@ -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 index 0000000..ded4c84 --- /dev/null +++ b/lib/tracksort.c @@ -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: +*/ -- [mdw]