summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorg Schuler <jcsjcs@users.sourceforge.net>2007-04-28 08:55:49 +0000
committerJorg Schuler <jcsjcs@users.sourceforge.net>2007-04-28 08:55:49 +0000
commit2d34a240529a7774e4b74a6eb3b351af9ced0ce9 (patch)
tree09357cf8ef3a1857b82deffa17dd13d94eb03158
parent448cbda6e8a40e8707c5ac056f6fe06564907c0a (diff)
downloadlibgpod-2d34a240529a7774e4b74a6eb3b351af9ced0ce9.tar.gz
libgpod-2d34a240529a7774e4b74a6eb3b351af9ced0ce9.tar.xz
libgpod-2d34a240529a7774e4b74a6eb3b351af9ced0ce9.zip
* docs/reference/tmpl/track.sgml
src/itdb.h src/itdb_itunesdb.c src/itdb_track.c: Added the following fields to Itdb_Track: sort_artist sort_title sort_album sort_albumartist sort_composer sort_tvshow These fields can (theoretically) be used to force a certain sort order on the iPod when displaying by artist, album... Even though these fields are present in the iTunesDB, they are discarded when reading the iTunesDB and applications must always set them before writing the iTunesDB again. This is to avoid that the fields 'artist' and 'sort_artist' accidentially get out of sync. libgpod will automatically create a sort_artist key for you if artist is of the type 'The Artist' and sort_artist is not set. The sort key used in that case is 'Artist, The' (followed by five time 0x01), even though sort_artist itself will not be touched. git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1421 f01d2545-417e-4e96-918e-98f8d0dbbcb6
-rw-r--r--ChangeLog28
-rw-r--r--docs/reference/tmpl/track.sgml11
-rw-r--r--src/itdb.h119
-rw-r--r--src/itdb_itunesdb.c255
-rw-r--r--src/itdb_track.c25
5 files changed, 341 insertions, 97 deletions
diff --git a/ChangeLog b/ChangeLog
index f0a03bd..98a0dd3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,34 @@
2007-04-28 Jorg Schuler <jcsjcs at users.sourceforge.net>
* src/itdb.h: added padding to exported structures so new entries
- can be added without loosing backward run-time compatibility.
+ can be added without loosing backward run-time compatibility.
+ * docs/reference/tmpl/track.sgml
+ src/itdb.h
+ src/itdb_itunesdb.c
+ src/itdb_track.c: Added the following fields to Itdb_Track:
+
+ sort_artist
+ sort_title
+ sort_album
+ sort_albumartist
+ sort_composer
+ sort_tvshow
+
+ These fields can (theoretically) be used to force a certain sort
+ order on the iPod when displaying by artist, album...
+
+ Even though these fields are present in the iTunesDB, they are
+ discarded when reading the iTunesDB and applications must always
+ set them before writing the iTunesDB again. This is to avoid
+ that the fields 'artist' and 'sort_artist' accidentially get out
+ of sync.
+
+ libgpod will automatically create a sort_artist key for you if
+ artist is of the type 'The Artist' and sort_artist is not
+ set. The sort key used in that case is 'Artist, The' (followed
+ by five time 0x01), even though sort_artist itself will not be
+ touched.
2007-04-27 Jorg Schuler <jcsjcs at users.sourceforge.net>
diff --git a/docs/reference/tmpl/track.sgml b/docs/reference/tmpl/track.sgml
index ffc0028..9f4be02 100644
--- a/docs/reference/tmpl/track.sgml
+++ b/docs/reference/tmpl/track.sgml
@@ -44,7 +44,12 @@ information about an iPod track.
@tvnetwork:
@albumartist:
@keywords:
-@reserved:
+@sort_artist:
+@sort_title:
+@sort_album:
+@sort_albumartist:
+@sort_composer:
+@sort_tvshow:
@id:
@size:
@tracklen:
@@ -132,6 +137,10 @@ information about an iPod track.
@reserved_int6:
@reserved1:
@reserved2:
+@reserved3:
+@reserved4:
+@reserved5:
+@reserved6:
@usertype:
@userdata:
@userdata_duplicate:
diff --git a/src/itdb.h b/src/itdb.h
index 42adf86..6bb6c45 100644
--- a/src/itdb.h
+++ b/src/itdb.h
@@ -53,7 +53,9 @@ G_BEGIN_DECLS
typedef void (* ItdbUserDataDestroyFunc) (gpointer userdata);
typedef gpointer (* ItdbUserDataDuplicateFunc) (gpointer userdata);
+/* public structures */
typedef struct _Itdb_Device Itdb_Device;
+typedef struct _Itdb_IpodInfo Itdb_IpodInfo;
typedef struct _Itdb_Artwork Itdb_Artwork;
typedef struct _Itdb_Thumb Itdb_Thumb;
typedef struct _Itdb_SPLPref Itdb_SPLPref;
@@ -64,7 +66,6 @@ typedef struct _Itdb_PhotoDB Itdb_PhotoDB;
typedef struct _Itdb_Playlist Itdb_Playlist;
typedef struct _Itdb_PhotoAlbum Itdb_PhotoAlbum;
typedef struct _Itdb_Track Itdb_Track;
-typedef struct _Itdb_IpodInfo Itdb_IpodInfo;
/* ------------------------------------------------------------ *\
@@ -124,8 +125,8 @@ struct _Itdb_IpodInfo {
iPod from scratch. */
const guint musicdirs;
/* reserved for future use */
- const gint reserved_int1;
- const gint reserved_int2;
+ const gint32 reserved_int1;
+ const gint32 reserved_int2;
gconstpointer reserved1;
gconstpointer reserved2;
};
@@ -698,18 +699,18 @@ typedef enum
about the iTunesDB and related files. */
struct _Itdb_Track
{
- Itdb_iTunesDB *itdb; /* pointer to iTunesDB (for convenience) */
- gchar *title; /* title (utf8) */
- gchar *ipod_path; /* name of file on iPod: uses ":"
- instead of "/" */
- gchar *album; /* album (utf8) */
- gchar *artist; /* artist (utf8) */
- gchar *genre; /* genre (utf8) */
- gchar *filetype; /* eg. "MP3-File"...(utf8)*/
- gchar *comment; /* comment (utf8) */
- gchar *category; /* Category for podcast */
- gchar *composer; /* Composer (utf8) */
- gchar *grouping; /* ? (utf8) */
+ Itdb_iTunesDB *itdb; /* pointer to iTunesDB (for convenience) */
+ gchar *title; /* title (utf8) */
+ gchar *ipod_path; /* name of file on iPod: uses ":" instead
+ of "/" and is relative to mountpoint */
+ gchar *album; /* album (utf8) */
+ gchar *artist; /* artist (utf8) */
+ gchar *genre; /* genre (utf8) */
+ gchar *filetype; /* eg. "MP3-File"...(utf8) */
+ gchar *comment; /* comment (utf8) */
+ gchar *category; /* Category for podcast */
+ gchar *composer; /* Composer (utf8) */
+ gchar *grouping; /* ? (utf8) */
gchar *description; /* see note for MHOD_ID in itdb_itunesdb.c */
gchar *podcasturl; /* see note for MHOD_ID in itdb_itunesdb.c */
gchar *podcastrss; /* see note for MHOD_ID in itdb_itunesdb.c */
@@ -721,55 +722,75 @@ struct _Itdb_Track
gchar *tvnetwork; /* see note for MHOD_ID in itdb_itunesdb.c */
gchar *albumartist; /* see note for MHOD_ID in itdb_itunesdb.c */
gchar *keywords; /* see note for MHOD_ID in itdb_itunesdb.c */
- gchar *reserved; /* will probably be used for artistthe */
+/* the following 6 are new in libgpod 0.5.0... */
+ /* You can set these strings to override the standard sortorder
+ suggested by libgpod. When set they take precedence over the
+ default 'artist', 'album'... fields.
+
+ When reading the iTunesDB these fields are discarded, so you will
+ have to set them again before writing the iTunesDB.
+
+ libgpod will automatically create an entry in the iTunesDB (but
+ not below) for sort_artist if 'artist' is something like "The
+ Artist" and sort_artist wasn't set by the application. In that
+ case 'Artist, The' followed by five 0x01 characters is used for
+ sorting and written to the iTunesDB. Why five 0x01 characters are
+ added is not completely understood, but analogous to what iTunes
+ does. libgpod will _not_ change the six fields below, however. */
+ gchar *sort_artist; /* artist name (for sorting) */
+ gchar *sort_title; /* title (for sorting) */
+ gchar *sort_album; /* album (for sorting) */
+ gchar *sort_albumartist; /* album artist (for sorting) */
+ gchar *sort_composer; /* composer (for sorting) */
+ gchar *sort_tvshow; /* tv show (for sorting) */
/* ... to here */
- guint32 id; /* unique ID of track */
- gint32 size; /* size of file in bytes */
- gint32 tracklen; /* Length of track in ms */
- gint32 cd_nr; /* CD number */
- gint32 cds; /* number of CDs */
- gint32 track_nr; /* track number */
- gint32 tracks; /* number of tracks */
- gint32 bitrate; /* bitrate */
- guint16 samplerate; /* samplerate (CD: 44100) */
+ guint32 id; /* unique ID of track */
+ gint32 size; /* size of file in bytes */
+ gint32 tracklen; /* Length of track in ms */
+ gint32 cd_nr; /* CD number */
+ gint32 cds; /* number of CDs */
+ gint32 track_nr; /* track number */
+ gint32 tracks; /* number of tracks */
+ gint32 bitrate; /* bitrate */
+ guint16 samplerate; /* samplerate (CD: 44100) */
guint16 samplerate_low; /* in the iTunesDB the samplerate is
multiplied by 0x10000 -- these are the
- lower 16 bit, which are usually 0 */
- gint32 year; /* year */
- gint32 volume; /* volume adjustment */
- guint32 soundcheck; /* volume adjustment "soundcheck" */
- time_t time_added; /* time when added (Mac type) */
- time_t time_modified; /* time of last modification (Mac type)*/
- time_t time_played; /* time of last play (Mac type) */
- guint32 bookmark_time; /* bookmark set for (AudioBook) in ms */
- guint32 rating; /* star rating (stars * RATING_STEP (20)) */
- guint32 playcount; /* number of times track was played */
+ lower 16 bit, which are usually 0 */
+ gint32 year; /* year */
+ gint32 volume; /* volume adjustment */
+ guint32 soundcheck; /* volume adjustment "soundcheck" */
+ time_t time_added; /* time when added (Mac type) */
+ time_t time_modified; /* time of last modification (Mac type) */
+ time_t time_played; /* time of last play (Mac type) */
+ guint32 bookmark_time; /* bookmark set for (AudioBook) in ms */
+ guint32 rating; /* star rating (stars * RATING_STEP (20)) */
+ guint32 playcount; /* number of times track was played */
guint32 playcount2; /* Also stores the play count of the
song. Don't know if it ever differs
from the above value. During sync itdb
sets playcount2 to the same value as
- playcount. */
- guint32 recent_playcount; /* times track was played since last sync */
- gboolean transferred; /* has file been transferred to iPod? */
- gint16 BPM; /* supposed to vary the playback speed */
+ playcount. */
+ guint32 recent_playcount; /* times track was played since last sync */
+ gboolean transferred; /* has file been transferred to iPod? */
+ gint16 BPM; /* supposed to vary the playback speed */
guint8 app_rating; /* star rating set by appl. (not
* iPod). If the rating set on the iPod
and the rating field above differ, the
original rating is copied here and the
new rating is stored above. */
guint8 type1; /* CBR MP3s and AAC are 0x00, VBR MP3s are
- 0x01 */
- guint8 type2; /* MP3s are 0x01, AAC are 0x00 */
+ 0x01 */
+ guint8 type2; /* MP3s are 0x01, AAC are 0x00 */
guint8 compilation;
guint32 starttime;
guint32 stoptime;
guint8 checked; /* 0x0: checkmark on track is set 0x1: not set */
- guint64 dbid; /* unique database ID */
+ guint64 dbid; /* unique database ID */
guint32 drm_userid; /* Apple Store/Audible User ID (for DRM'ed
- files only, set to 0 otherwise). */
+ files only, set to 0 otherwise). */
guint32 visible; /* If this value is 1, the song is visible
on the iPod. All other values cause
- the file to be hidden. */
+ the file to be hidden. */
guint32 filetype_marker; /* This appears to always be 0 on hard
drive based iPods, but for the
iTunesDB that is written to an iPod
@@ -779,7 +800,7 @@ struct _Itdb_Track
0x4d503320 -> 0x4d = 'M', 0x50 = 'P',
0x33 = '3', 0x20 = <space>. (set to
the filename extension by itdb when
- copying track to iPod)*/
+ copying track to iPod) */
guint16 artwork_count; /* The number of album artwork items
associated with this song. libgpod
updates this value when syncing */
@@ -788,12 +809,12 @@ struct _Itdb_Track
converted to JPEG format. Observed in
iPodDB version 0x0b and with an iPod
Photo. libgpod updates this value when
- syncing */
+ syncing */
float samplerate2; /* The sample rate of the song expressed
as an IEEE 32 bit floating point
number. It's uncertain why this is
here. itdb will set this when adding
- a track */
+ a track */
guint16 unk126; /* unknown, but always seems to be 0xffff for
MP3/AAC songs, 0x0 for uncompressed songs
@@ -924,6 +945,10 @@ struct _Itdb_Track
gint32 reserved_int6;
gpointer reserved1;
gpointer reserved2;
+ gpointer reserved3;
+ gpointer reserved4;
+ gpointer reserved5;
+ gpointer reserved6;
/* below is for use by application */
guint64 usertype;
diff --git a/src/itdb_itunesdb.c b/src/itdb_itunesdb.c
index 248f3e0..9742bf2 100644
--- a/src/itdb_itunesdb.c
+++ b/src/itdb_itunesdb.c
@@ -168,46 +168,50 @@ enum MHOD_ID {
MHOD_ID_FILETYPE = 6,
/* MHOD_ID_EQSETTING = 7, */
MHOD_ID_COMMENT = 8,
-/* Category - This is the category ("Technology", "Music", etc.) where
- the podcast was located. Introduced in db version 0x0d. */
+ /* Category - This is the category ("Technology", "Music", etc.) where
+ the podcast was located. Introduced in db version 0x0d. */
MHOD_ID_CATEGORY = 9,
MHOD_ID_COMPOSER = 12,
MHOD_ID_GROUPING = 13,
-/* Description text (such as podcast show notes). Accessible by
- wselecting the center button on the iPod, where this string is
- displayed along with the song title, date, and
- timestamp. Introduced in db version 0x0d. */
+ /* Description text (such as podcast show notes). Accessible by
+ wselecting the center button on the iPod, where this string is
+ displayed along with the song title, date, and
+ timestamp. Introduced in db version 0x0d. */
MHOD_ID_DESCRIPTION = 14,
-/* Podcast Enclosure URL. Note: this is either a UTF-8 or ASCII
- encoded string (NOT UTF-16). Also, there is no mhod::length value
- for this type. Introduced in db version 0x0d. */
+ /* Podcast Enclosure URL. Note: this is either a UTF-8 or ASCII
+ encoded string (NOT UTF-16). Also, there is no mhod::length value
+ for this type. Introduced in db version 0x0d. */
MHOD_ID_PODCASTURL = 15,
-/* Podcast RSS URL. Note: this is either a UTF-8 or ASCII encoded
- string (NOT UTF-16). Also, there is no mhod::length value for this
- type. Introduced in db version 0x0d. */
+ /* Podcast RSS URL. Note: this is either a UTF-8 or ASCII encoded
+ string (NOT UTF-16). Also, there is no mhod::length value for this
+ type. Introduced in db version 0x0d. */
MHOD_ID_PODCASTRSS = 16,
-/* Chapter data. This is a m4a-style entry that is used to display
- subsongs within a mhit. Introduced in db version 0x0d. */
+ /* Chapter data. This is a m4a-style entry that is used to display
+ subsongs within a mhit. Introduced in db version 0x0d. */
MHOD_ID_CHAPTERDATA = 17,
-/* Subtitle (usually the same as Description). Introduced in db
- version 0x0d. */
+ /* Subtitle (usually the same as Description). Introduced in db
+ version 0x0d. */
MHOD_ID_SUBTITLE = 18,
-/* Show (for TV Shows only). Introduced in db version 0x0d? */
+ /* Show (for TV Shows only). Introduced in db version 0x0d? */
MHOD_ID_TVSHOW = 19,
-/* Episode # (for TV Shows only). Introduced in db version 0x0d? */
+ /* Episode # (for TV Shows only). Introduced in db version 0x0d? */
MHOD_ID_TVEPISODE = 20,
-/* TV Network (for TV Shows only). Introduced in db version 0x0d? */
+ /* TV Network (for TV Shows only). Introduced in db version 0x0d? */
MHOD_ID_TVNETWORK = 21,
-/* Album Artist. Introduced in db version 0x13? */
+ /* Album Artist. Introduced in db version 0x13? */
MHOD_ID_ALBUMARTIST = 22,
-/* This only seems to appear if the Artist has "The" in front of it
- (like "The Monkies") in which case it will be in the format "Artist,
- The" and is followed by 5 0x01 UTF-16 characters. Introduced in db
- version 0x13? */
-/* MHOD_ID_ARTISTTHE = 23, later */
-/* Appears to be a list of keywords pertaining to a track. Introduced
- in db version 0x13? */
+ /* Sort key for artist. */
+ MHOD_ID_SORT_ARTIST = 23,
+ /* Appears to be a list of keywords pertaining to a track. Introduced
+ in db version 0x13? */
MHOD_ID_KEYWORDS = 24,
+ /* more sort keys, taking precedence over the standard entries if
+ present */
+ MHOD_ID_SORT_TITLE = 27,
+ MHOD_ID_SORT_ALBUM = 28,
+ MHOD_ID_SORT_ALBUMARTIST = 29,
+ MHOD_ID_SORT_COMPOSER = 30,
+ MHOD_ID_SORT_TVSHOW = 31,
MHOD_ID_SPLPREF = 50, /* settings for smart playlist */
MHOD_ID_SPLRULES = 51, /* rules for smart playlist */
MHOD_ID_LIBPLAYLISTINDEX = 52, /* Library Playlist Index */
@@ -1364,6 +1368,12 @@ static MHODData get_mhod (FImport *fimp, glong mhod_seek, guint32 *ml)
case MHOD_ID_TVNETWORK:
case MHOD_ID_ALBUMARTIST:
case MHOD_ID_KEYWORDS:
+ case MHOD_ID_SORT_ARTIST:
+ case MHOD_ID_SORT_TITLE:
+ case MHOD_ID_SORT_ALBUM:
+ case MHOD_ID_SORT_ALBUMARTIST:
+ case MHOD_ID_SORT_COMPOSER:
+ case MHOD_ID_SORT_TVSHOW:
/* type of string: 0x02: UTF8, 0x01 or 0x00: UTF16 LE */
string_type = get32lint (cts, seek);
xl = get32lint (cts, seek+4); /* length of string */
@@ -1596,6 +1606,12 @@ static gchar *get_mhod_string (FImport *fimp, glong seek, guint32 *ml, gint32 *m
case MHOD_ID_TVNETWORK:
case MHOD_ID_ALBUMARTIST:
case MHOD_ID_KEYWORDS:
+ case MHOD_ID_SORT_ARTIST:
+ case MHOD_ID_SORT_TITLE:
+ case MHOD_ID_SORT_ALBUM:
+ case MHOD_ID_SORT_ALBUMARTIST:
+ case MHOD_ID_SORT_COMPOSER:
+ case MHOD_ID_SORT_TVSHOW:
mhoddata = get_mhod (fimp, seek, ml);
if ((*ml != -1) && mhoddata.valid)
return mhoddata.data.string;
@@ -2061,6 +2077,12 @@ static glong get_playlist (FImport *fimp, glong mhyp_seek)
case MHOD_ID_ALBUMARTIST:
case MHOD_ID_KEYWORDS:
case MHOD_ID_CHAPTERDATA:
+ case MHOD_ID_SORT_ARTIST:
+ case MHOD_ID_SORT_TITLE:
+ case MHOD_ID_SORT_ALBUM:
+ case MHOD_ID_SORT_ALBUMARTIST:
+ case MHOD_ID_SORT_COMPOSER:
+ case MHOD_ID_SORT_TVSHOW:
/* these are not expected here */
break;
case MHOD_ID_LIBPLAYLISTINDEX:
@@ -2348,6 +2370,17 @@ static glong get_mhit (FImport *fimp, glong mhit_seek)
case MHOD_ID_KEYWORDS:
track->keywords = entry_utf8;
break;
+ case MHOD_ID_SORT_ARTIST:
+ case MHOD_ID_SORT_TITLE:
+ case MHOD_ID_SORT_ALBUM:
+ case MHOD_ID_SORT_ALBUMARTIST:
+ case MHOD_ID_SORT_COMPOSER:
+ case MHOD_ID_SORT_TVSHOW:
+ /* we don't read those -- the application has to set
+ them before each export / libgpod will create the
+ sort_artist field before each export if not set */
+ g_free (entry_utf8);
+ break;
case MHOD_ID_SPLPREF:
case MHOD_ID_SPLRULES:
case MHOD_ID_LIBPLAYLISTINDEX:
@@ -3543,6 +3576,45 @@ static void fix_mhit (WContents *cts, gulong mhit_seek, guint32 mhod_num)
put32lint_seek (cts, mhod_num, mhit_seek+12);
}
+/* Returns:
+ - track->sort_artist if track->sort_artist is not NULL
+
+ - 'Artist, The' if track->sort_artist is NULL and track->artist of
+ of type 'The Artist'.
+
+ - NULL if track->sort_artist is NULL and track->artist is not of
+ type 'The Artist'.
+
+ You must g_free() the returned string */
+static gchar *get_sort_artist (Itdb_Track *track)
+{
+ g_return_val_if_fail (track, NULL);
+
+ if (track->sort_artist && *track->sort_artist)
+ {
+ return g_strdup (track->sort_artist);
+ }
+
+ if (!(track->artist && *track->artist))
+ {
+ return NULL;
+ }
+
+ /* check if artist is of type 'The Artist' */
+ if (g_ascii_strncasecmp ("The ", track->artist, 4) == 0)
+ { /* return 'Artist, The', followed by five 0x01 chars
+ (analogous to iTunes) */
+ return g_strdup_printf ("%s, The%c%c%c%c%c",
+ track->artist+4,
+ 0x01, 0x01, 0x01, 0x01, 0x01);
+ }
+
+ return NULL;
+}
+
+
+
+
static gint mhod52_sort_title (const struct mhod52track *a, const struct mhod52track *b)
{
return strcmp (a->title, b->title);
@@ -3619,6 +3691,7 @@ static GList *mhod52_make_collate_keys (GList *tracks)
for (gl=tracks; gl; gl=gl->next)
{
+ gchar *str;
struct mhod52track *ct;
Itdb_Track *tr = gl->data;
g_return_val_if_fail (tr, NULL);
@@ -3626,26 +3699,74 @@ static GList *mhod52_make_collate_keys (GList *tracks)
ct = g_new0 (struct mhod52track, 1);
coltracks = g_list_prepend (coltracks, ct);
- if (tr->album)
+ /* album */
+ if (tr->sort_album)
+ {
+ ct->album = g_utf8_collate_key (tr->sort_album, -1);
+ }
+ else if (tr->album)
+ {
ct->album = g_utf8_collate_key (tr->album, -1);
+ }
else
+ {
ct->album = g_strdup ("");
- if (tr->title)
+ }
+
+ /* title */
+ if (tr->sort_title)
+ {
+ ct->title = g_utf8_collate_key (tr->sort_title, -1);
+ }
+ else if (tr->title)
+ {
ct->title = g_utf8_collate_key (tr->title, -1);
+ }
else
+ {
ct->title = g_strdup ("");
- if (tr->artist)
+ }
+
+ /* artist */
+ str = get_sort_artist (tr);
+ if (str)
+ {
+ ct->artist = g_utf8_collate_key (str, -1);
+ g_free (str);
+ }
+ else if (tr->artist)
+ {
ct->artist = g_utf8_collate_key (tr->artist, -1);
+ }
else
+ {
ct->artist = g_strdup ("");
+ }
+
+ /* genre */
if (tr->genre)
+ {
ct->genre = g_utf8_collate_key (tr->genre, -1);
+ }
else
+ {
ct->genre = g_strdup ("");
- if (tr->composer)
+ }
+
+ /* composer */
+ if (tr->sort_composer)
+ {
+ ct->composer = g_utf8_collate_key (tr->sort_composer, -1);
+ }
+ else if (tr->composer)
+ {
ct->composer = g_utf8_collate_key (tr->composer, -1);
+ }
else
+ {
ct->composer = g_strdup ("");
+ }
+
ct->track_nr = tr->track_nr;
ct->cd_nr = tr->cd_nr;
ct->numtracks = numtracks;
@@ -3707,6 +3828,12 @@ static void mk_mhod (FExport *fexp, MHODData *mhod)
case MHOD_ID_TVNETWORK:
case MHOD_ID_ALBUMARTIST:
case MHOD_ID_KEYWORDS:
+ case MHOD_ID_SORT_ARTIST:
+ case MHOD_ID_SORT_TITLE:
+ case MHOD_ID_SORT_ALBUM:
+ case MHOD_ID_SORT_ALBUMARTIST:
+ case MHOD_ID_SORT_COMPOSER:
+ case MHOD_ID_SORT_TVSHOW:
g_return_if_fail (mhod->data.string);
/* normal iTunesDBs seem to take utf16 strings), endian-inversed
iTunesDBs seem to take utf8 strings */
@@ -4084,6 +4211,7 @@ static gboolean write_mhsd_tracks (FExport *fexp)
guint32 mhod_num = 0;
gulong mhit_seek = cts->pos;
MHODData mhod;
+ gchar *str;
g_return_val_if_fail (track, FALSE);
@@ -4223,6 +4351,50 @@ static gboolean write_mhsd_tracks (FExport *fexp)
mk_mhod (fexp, &mhod);
++mhod_num;
}
+ str = get_sort_artist (track);
+ if (str)
+ {
+ mhod.type = MHOD_ID_SORT_ARTIST;
+ mhod.data.string = str;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ g_free (str);
+ }
+ if (track->sort_title && *track->sort_title)
+ {
+ mhod.type = MHOD_ID_SORT_TITLE;
+ mhod.data.string = track->sort_title;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ }
+ if (track->sort_album && *track->sort_album)
+ {
+ mhod.type = MHOD_ID_SORT_ALBUM;
+ mhod.data.string = track->sort_album;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ }
+ if (track->sort_albumartist && *track->sort_albumartist)
+ {
+ mhod.type = MHOD_ID_SORT_ALBUMARTIST;
+ mhod.data.string = track->sort_albumartist;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ }
+ if (track->sort_composer && *track->sort_composer)
+ {
+ mhod.type = MHOD_ID_SORT_COMPOSER;
+ mhod.data.string = track->sort_composer;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ }
+ if (track->sort_tvshow && *track->sort_tvshow)
+ {
+ mhod.type = MHOD_ID_SORT_TVSHOW;
+ mhod.data.string = track->sort_tvshow;
+ mk_mhod (fexp, &mhod);
+ ++mhod_num;
+ }
if (track->chapterdata_raw && track->chapterdata_raw_length)
{
mhod.type = MHOD_ID_CHAPTERDATA;
@@ -4617,9 +4789,10 @@ static void wcontents_free (WContents *cts)
}
-/* reassign the iPod IDs and make sure the itdb->tracks are in the
- same order as the mpl */
-static void reassign_ids (FExport *fexp)
+/* - reassign the iPod IDs
+ - make sure the itdb->tracks are in the same order as the mpl
+*/
+static void prepare_itdb_for_write (FExport *fexp)
{
GList *gl;
Itdb_iTunesDB *itdb;
@@ -4639,18 +4812,20 @@ static void reassign_ids (FExport *fexp)
for (gl=g_list_last(mpl->members); gl; gl=gl->prev)
{
+ GList *link;
Itdb_Track *track = gl->data;
g_return_if_fail (track);
- g_return_if_fail (g_list_find (itdb->tracks, track));
+ link = g_list_find (itdb->tracks, track);
+ g_return_if_fail (link);
/* move this track to the beginning of itdb_tracks */
- itdb->tracks = g_list_remove (itdb->tracks, track);
+ itdb->tracks = g_list_delete_link (itdb->tracks, link);
itdb->tracks = g_list_prepend (itdb->tracks, track);
}
fexp->next_id = FIRST_IPOD_ID;
- /* assign unique IDs */
+ /* assign unique IDs and create sort keys */
for (gl=itdb->tracks; gl; gl=gl->next)
{
Itdb_Track *track = gl->data;
@@ -4706,8 +4881,8 @@ gboolean itdb_write_file (Itdb_iTunesDB *itdb, const gchar *filename,
cts->reversed = (itdb->device->byte_order == G_BIG_ENDIAN);
- reassign_ids (fexp);
-
+ prepare_itdb_for_write (fexp);
+
mk_mhbd (fexp, 3); /* three mhsds */
/* write tracklist */
if (write_mhsd_tracks (fexp))
@@ -5009,7 +5184,7 @@ gboolean itdb_shuffle_write_file (Itdb_iTunesDB *itdb,
fexp->wcontents = wcontents_new (filename);
cts = fexp->wcontents;
- reassign_ids (fexp);
+ prepare_itdb_for_write (fexp);
put24bint (cts, itdb_tracks_number (itdb));
put24bint (cts, 0x010600);
diff --git a/src/itdb_track.c b/src/itdb_track.c
index d7e7933..23cae60 100644
--- a/src/itdb_track.c
+++ b/src/itdb_track.c
@@ -1,5 +1,5 @@
/*
-| Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
+| Copyright (C) 2002-2007 Jorg Schuler <jcsjcs at users sourceforge net>
| Part of the gtkpod project.
|
| URL: http://www.gtkpod.org/
@@ -247,14 +247,15 @@ void itdb_track_free (Itdb_Track *track)
g_return_if_fail (track);
g_free (track->title);
- g_free (track->artist);
+ g_free (track->ipod_path);
g_free (track->album);
+ g_free (track->artist);
g_free (track->genre);
- g_free (track->composer);
- g_free (track->comment);
g_free (track->filetype);
- g_free (track->grouping);
+ g_free (track->comment);
g_free (track->category);
+ g_free (track->composer);
+ g_free (track->grouping);
g_free (track->description);
g_free (track->podcasturl);
g_free (track->podcastrss);
@@ -264,12 +265,20 @@ void itdb_track_free (Itdb_Track *track)
g_free (track->tvnetwork);
g_free (track->albumartist);
g_free (track->keywords);
- g_free (track->ipod_path);
+ g_free (track->sort_artist);
+ g_free (track->sort_title);
+ g_free (track->sort_album);
+ g_free (track->sort_albumartist);
+ g_free (track->sort_composer);
+ g_free (track->sort_tvshow);
+
g_free (track->chapterdata_raw);
- itdb_artwork_remove_thumbnails (track->artwork);
- g_free (track->artwork);
+
+ itdb_artwork_free (track->artwork);
+
if (track->userdata && track->userdata_destroy)
(*track->userdata_destroy) (track->userdata);
+
g_free (track);
}