+/**
+ * A tower that was accepted by a filter.
+ */
+typedef struct {
+ char *sortkey;
+ char *primarykey;
+ char *displayname;
+} FoundTower;
+
+static FoundTower *
+found_tower_new (tower *basis)
+{
+ FoundTower* result = g_new (FoundTower, 1);
+
+ switch (settings_value[SETTINGS_TOWERSORT])
+ {
+ case TOWERSORT_DISTANCE:
+ result->sortkey = g_strdup_printf ("%5d %s",
+ distance_to_tower (basis),
+ basis->fields[FieldPlace]);
+ break;
+ case TOWERSORT_PRACTICE:
+ result->sortkey = g_strdup_printf ("%d %s",
+ days_until_practice_night (basis),
+ basis->fields[FieldPlace]);
+ break;
+ case TOWERSORT_BELLS:
+ result->sortkey = g_strdup_printf ("%10s", basis->fields[FieldBells]);
+ break;
+ case TOWERSORT_WEIGHT:
+ result->sortkey = g_strdup_printf ("%10s", basis->fields[FieldWt]);
+ break;
+ case TOWERSORT_TOWN:
+ default:
+ result->sortkey = g_strdup (basis->fields[FieldPlace]);
+ }
+
+ result->primarykey = g_strdup (basis->fields[FieldPrimaryKey]);
+
+ if (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET)
+ {
+ gchar *distance = distance_to_tower_str (basis);
+ result->displayname = g_strdup_printf ("%s, %s (%s, %s) (%s)",
+ basis->fields[FieldDedication],
+ basis->fields[FieldPlace],
+ basis->fields[FieldBells],
+ basis->fields[FieldPracticeNight],
+ distance);
+ g_free (distance);
+ }
+ else
+ {
+ result->displayname = g_strdup_printf ("%s, %s (%s, %s)",
+ basis->fields[FieldDedication],
+ basis->fields[FieldPlace],
+ basis->fields[FieldBells],
+ basis->fields[FieldPracticeNight]);
+ }
+
+ return result;
+}
+
+static void
+found_tower_free (FoundTower *tower)
+{
+ g_free (tower->sortkey);
+ g_free (tower->primarykey);
+ g_free (tower->displayname);
+ g_free (tower);
+}
+
+/**
+ * Comparison function for FoundTower objects.
+ *
+ * \param a a FoundTower
+ * \param b another FoundTower
+ */
+gint found_tower_compare (gconstpointer a,
+ gconstpointer b)
+{
+ FoundTower *fta = (FoundTower *)a;
+ FoundTower *ftb = (FoundTower *)b;
+
+ return strcmp (fta->sortkey, ftb->sortkey);
+}
+
+/**
+ * Calls a given function once for each tower in the world.
+ * (The first call, however, is a header row.)
+ *
+ * \param callback The function to call.
+ * \param data Arbitrary data to pass to the callback.
+ * \param dialogue_title If non-NULL, a list will be displayed
+ * with the results. This is the title
+ * used for that dialogue. (The dialogue
+ * will automatically free filter_results.)
+ */