summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}