char * rb_make_elapsed_time_string (guint elapsed, guint duration, gboolean show_remaining) { int seconds = 0, minutes = 0, hours = 0; int seconds2 = 0, minutes2 = 0, hours2 = 0; if (duration == 0) return rb_make_duration_string (elapsed); if (duration > 0) { hours2 = duration / (60 * 60); minutes2 = (duration - (hours2 * 60 * 60)) / 60; seconds2 = duration % 60; } if (elapsed > 0) { hours = elapsed / (60 * 60); minutes = (elapsed - (hours * 60 * 60)) / 60; seconds = elapsed % 60; } if (show_remaining) { int remaining = duration - elapsed; int remaining_hours = remaining / (60 * 60); int remaining_minutes = (remaining - (remaining_hours * 60 * 60)) / 60; /* remaining could conceivably be negative. This would * be a bug, but the elapsed time will display right * with the abs(). */ int remaining_seconds = abs (remaining % 60); if (hours2 == 0) return g_strdup_printf (_("%d:%02d of %d:%02d remaining"), remaining_minutes, remaining_seconds, minutes2, seconds2); else return g_strdup_printf (_("%d:%02d:%02d of %d:%02d:%02d remaining"), remaining_hours, remaining_minutes, remaining_seconds, hours2, minutes2, seconds2); } else { if (hours == 0 && hours2 == 0) return g_strdup_printf (_("%d:%02d of %d:%02d"), minutes, seconds, minutes2, seconds2); else return g_strdup_printf (_("%d:%02d:%02d of %d:%02d:%02d"), hours, minutes, seconds, hours2, minutes2, seconds2); } }
/* * Parse a filename pattern and replace markers with values from a TrackDetails * structure. * * Valid markers so far are: * %at -- album title * %aa -- album artist * %aA -- album artist (lowercase) * %as -- album artist sortname * %aS -- album artist sortname (lowercase) * %ay -- album year * %ag -- album genre * %aG -- album genre (lowercase) * %an -- album disc number * %aN -- album disc number, zero padded * %tn -- track number (i.e 8) * %tN -- track number, zero padded (i.e 08) * %tt -- track title * %ta -- track artist * %tA -- track artist (lowercase) * %ts -- track artist sortname * %tS -- track artist sortname (lowercase) * %td -- track duration * %te -- track elapsed time * %tb -- track bitrate * %st -- stream title */ static char * parse_pattern (const char *pattern, GHashTable *properties, guint elapsed) { /* p is the pattern iterator, i is a general purpose iterator */ const char *p; char *temp; GString *s; if (pattern == NULL || pattern[0] == 0) return g_strdup (" "); s = g_string_new (NULL); p = pattern; while (*p) { char *string = NULL; const GValue *value = NULL; /* If not a % marker, copy and continue */ if (*p != '%') { g_string_append_c (s, *p++); /* Explicit increment as we continue past the increment */ continue; } /* Is a % marker, go to next and see what to do */ switch (*++p) { case '%': /* * Literal % */ g_string_append_c (s, '%'); break; case 'a': /* * Album tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "album"); if (value) string = g_value_dup_string (value); break; case 'T': value = g_hash_table_lookup (properties, "album-folded"); if (value) string = g_value_dup_string (value); break; case 'a': value = g_hash_table_lookup (properties, "artist"); if (value) string = g_value_dup_string (value); break; case 'A': value = g_hash_table_lookup (properties, "artist-folded"); if (value) string = g_value_dup_string (value); break; case 's': value = g_hash_table_lookup (properties, "mb-artistsortname"); if (value) string = g_value_dup_string (value); break; case 'S': value = g_hash_table_lookup (properties, "mb-artistsortname"); if (value) string = g_utf8_strdown (g_value_get_string (value), -1); break; case 'y': /* Release year */ value = g_hash_table_lookup (properties, "year"); if (value) string = g_strdup_printf ("%u", g_value_get_uint (value)); break; /* Disc number */ case 'n': value = g_hash_table_lookup (properties, "disc-number"); if (value) string = g_strdup_printf ("%u", g_value_get_uint (value)); break; case 'N': value = g_hash_table_lookup (properties, "disc-number"); if (value) string = g_strdup_printf ("%02u", g_value_get_uint (value)); break; /* genre */ case 'g': value = g_hash_table_lookup (properties, "genre"); if (value) string = g_value_dup_string (value); break; case 'G': value = g_hash_table_lookup (properties, "genre-folded"); if (value) string = g_value_dup_string (value); break; default: string = g_strdup_printf ("%%a%c", *p); } break; case 't': /* * Track tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "title"); if (value) string = g_value_dup_string (value); break; case 'T': value = g_hash_table_lookup (properties, "title-folded"); if (value) string = g_value_dup_string (value); break; case 'a': value = g_hash_table_lookup (properties, "artist"); if (value) string = g_value_dup_string (value); break; case 'A': value = g_hash_table_lookup (properties, "artist-folded"); if (value) string = g_value_dup_string (value); break; case 's': value = g_hash_table_lookup (properties, "mb-artistsortname"); if (value) string = g_value_dup_string (value); break; case 'S': value = g_hash_table_lookup (properties, "mb-artistsortname"); if (value) string = g_utf8_strdown (g_value_get_string (value), -1); break; case 'n': /* Track number */ value = g_hash_table_lookup (properties, "track-number"); if (value) string = g_strdup_printf ("%u", g_value_get_uint (value)); break; case 'N': /* Track number, zero-padded */ value = g_hash_table_lookup (properties, "track-number"); if (value) string = g_strdup_printf ("%02u", g_value_get_uint (value)); break; case 'd': /* Track duration */ value = g_hash_table_lookup (properties, "duration"); if (value) string = rb_make_duration_string (g_value_get_uint (value)); break; case 'e': /* Track elapsed time */ string = rb_make_duration_string (elapsed); break; case 'b': /* Track bitrate */ value = g_hash_table_lookup (properties, "bitrate"); if (value) string = g_strdup_printf ("%u", g_value_get_uint (value)); break; default: string = g_strdup_printf ("%%t%c", *p); } break; case 's': /* * Stream tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "rb:stream-song-title"); if (value) string = g_value_dup_string (value); break; default: string = g_strdup_printf ("%%s%c", *p); } break; default: string = g_strdup_printf ("%%%c", *p); } if (string) g_string_append (s, string); g_free (string); ++p; } temp = s->str; g_string_free (s, FALSE); return temp; }
/* * Parse a filename pattern and replace markers with values from a TrackDetails * structure. * * Valid markers so far are: * %at -- album title * %aa -- album artist * %aA -- album artist (lowercase) * %as -- album artist sortname * %aS -- album artist sortname (lowercase) * %ay -- album year * %ag -- album genre * %aG -- album genre (lowercase) * %an -- album disc number * %aN -- album disc number, zero padded * %tn -- track number (i.e 8) * %tN -- track number, zero padded (i.e 08) * %tt -- track title * %ta -- track artist * %tA -- track artist (lowercase) * %ts -- track artist sortname * %tS -- track artist sortname (lowercase) * %td -- track duration * %te -- track elapsed time * %tb -- track bitrate * %st -- stream title */ static char * parse_pattern (const char *pattern, GHashTable *properties, gint64 elapsed) { /* p is the pattern iterator, i is a general purpose iterator */ const char *p; char *temp; GString *s; if (pattern == NULL || pattern[0] == 0) return g_strdup (" "); s = g_string_new (NULL); p = pattern; while (*p) { char *string = NULL; const char **strv = NULL; GVariant *value = NULL; /* If not a % marker, copy and continue */ if (*p != '%') { g_string_append_c (s, *p++); /* Explicit increment as we continue past the increment */ continue; } /* Is a % marker, go to next and see what to do */ switch (*++p) { case '%': /* * Literal % */ g_string_append_c (s, '%'); break; case 'a': /* * Album tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "xesam:album"); if (value) string = g_variant_dup_string (value, NULL); break; case 'T': value = g_hash_table_lookup (properties, "xesam:album"); if (value) string = g_utf8_strdown (g_variant_get_string (value, NULL), -1); break; case 'a': value = g_hash_table_lookup (properties, "xesam:artist"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_strdup (strv[0]); } break; case 'A': value = g_hash_table_lookup (properties, "xesam:artist"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_utf8_strdown (strv[0], -1); } break; case 's': value = g_hash_table_lookup (properties, "rhythmbox:albumArtistSortname"); if (value) string = g_variant_dup_string (value, NULL); break; case 'S': value = g_hash_table_lookup (properties, "rhythmbox:albumArtistSortname"); if (value) string = g_utf8_strdown (g_variant_get_string (value, NULL), -1); break; case 'y': /* Release year */ value = g_hash_table_lookup (properties, "xesam:contentCreated"); if (value) { const char *iso8601; GTimeVal tv; iso8601 = g_variant_get_string (value, NULL); if (g_time_val_from_iso8601 (iso8601, &tv)) { GDate d; g_date_set_time_val (&d, &tv); string = g_strdup_printf ("%u", g_date_get_year (&d)); } } break; /* Disc number */ case 'n': value = g_hash_table_lookup (properties, "xesam:discNumber"); if (value) string = g_strdup_printf ("%u", g_variant_get_int32 (value)); break; case 'N': value = g_hash_table_lookup (properties, "xesam:discNumber"); if (value) string = g_strdup_printf ("%02u", g_variant_get_int32 (value)); break; /* genre */ case 'g': value = g_hash_table_lookup (properties, "xesam:genre"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_strdup (strv[0]); } break; case 'G': value = g_hash_table_lookup (properties, "xesam:genre"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_utf8_strdown (strv[0], -1); } break; default: string = g_strdup_printf ("%%a%c", *p); } break; case 't': /* * Track tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "rhythmbox:streamTitle"); if (value == NULL) value = g_hash_table_lookup (properties, "xesam:title"); if (value) string = g_variant_dup_string (value, NULL); break; case 'T': value = g_hash_table_lookup (properties, "rhythmbox:streamTitle"); if (value == NULL) value = g_hash_table_lookup (properties, "xesam:title"); if (value) string = g_utf8_strdown (g_variant_get_string (value, NULL), -1); break; case 'a': value = g_hash_table_lookup (properties, "xesam:artist"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_strdup (strv[0]); } break; case 'A': value = g_hash_table_lookup (properties, "xesam:artist"); if (value) { strv = g_variant_get_strv (value, NULL); string = g_utf8_strdown (strv[0], -1); } break; case 's': value = g_hash_table_lookup (properties, "rhythmbox:artistSortname"); if (value) string = g_variant_dup_string (value, NULL); break; case 'S': value = g_hash_table_lookup (properties, "rhythmbox:artistSortname"); if (value) string = g_utf8_strdown (g_variant_get_string (value, NULL), -1); break; case 'n': /* Track number */ value = g_hash_table_lookup (properties, "xesam:trackNumber"); if (value) string = g_strdup_printf ("%u", g_variant_get_int32 (value)); break; case 'N': /* Track number, zero-padded */ value = g_hash_table_lookup (properties, "xesam:trackNumber"); if (value) string = g_strdup_printf ("%02u", g_variant_get_int32 (value)); break; case 'd': /* Track duration */ value = g_hash_table_lookup (properties, "mpris:length"); if (value) string = rb_make_duration_string (g_variant_get_int64 (value)); break; case 'e': /* Track elapsed time */ string = rb_make_duration_string (elapsed); break; case 'b': /* Track bitrate */ value = g_hash_table_lookup (properties, "xesam:audioBitrate"); if (value) string = g_strdup_printf ("%u", g_variant_get_int32 (value) / 1024); break; default: string = g_strdup_printf ("%%t%c", *p); } break; case 's': /* * Stream tag */ switch (*++p) { case 't': value = g_hash_table_lookup (properties, "rhythmbox:streamTitle"); if (value) { value = g_hash_table_lookup (properties, "xesam:title"); if (value) { string = g_variant_dup_string (value, NULL); } } break; default: string = g_strdup_printf ("%%s%c", *p); } break; default: string = g_strdup_printf ("%%%c", *p); } if (string) g_string_append (s, string); g_free (string); ++p; } temp = s->str; g_string_free (s, FALSE); return temp; }