[easytag/wip/et_core-refactor: 5/9] Split off File_Tag to a separate file



commit 86f79e4b7093ef221eb30786366cf79896af486f
Author: David King <amigadave amigadave com>
Date:   Sun Dec 28 19:34:55 2014 +0000

    Split off File_Tag to a separate file
    
    Move most of the prototypes for functions that deal with File_Tag to a
    separate file_tag.h header, and keep the remaining ones in et_core.h.

 Makefile.am    |    2 +
 src/et_core.c  |  634 +-------------------------------------------------------
 src/et_core.h  |   59 +-----
 src/file_tag.c |  641 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/file_tag.h |  103 +++++++++
 5 files changed, 755 insertions(+), 684 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index f77f013..4807ca9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ easytag_SOURCES = \
        src/enums.c \
        src/et_core.c \
        src/file_area.c \
+       src/file_tag.c \
        src/load_files_dialog.c \
        src/log.c \
        src/main.c \
@@ -105,6 +106,7 @@ easytag_headers = \
        src/easytag.h \
        src/et_core.h \
        src/file_area.h \
+       src/file_tag.h \
        src/genres.h \
        src/load_files_dialog.h \
        src/log.h \
diff --git a/src/et_core.c b/src/et_core.c
index f6462e4..82d992e 100644
--- a/src/et_core.c
+++ b/src/et_core.c
@@ -31,6 +31,7 @@
 
 #include "application_window.h"
 #include "easytag.h"
+#include "file_tag.h"
 #include "mpeg_header.h"
 #include "monkeyaudio_header.h"
 #include "musepack_header.h"
@@ -133,17 +134,14 @@ static gboolean ET_Free_File_List                 (void);
 static gboolean ET_Free_File_Name_List            (GList *FileNameList);
 static gboolean ET_Free_File_Tag_List (GList *FileTagList);
 static void ET_Free_File_Name_Item (File_Name *FileName);
-static gboolean ET_Free_File_Tag_Item_Other_Field (File_Tag *FileTag);
 static gboolean ET_Free_File_Info_Item (ET_File_Info *ETFileInfo);
 static gboolean ET_Free_History_File_List (void);
 static gboolean ET_Free_Displayed_File_List (void);
 static gboolean ET_Free_Artist_Album_File_List (void);
 
-static void ET_Initialize_File_Tag_Item (File_Tag *FileTag);
 static void ET_Initialize_File_Name_Item (File_Name *FileName);
 
 static guint ET_File_Key_New (void);
-static guint ET_Undo_Key_New (void);
 
 static gboolean ET_Remove_File_From_Artist_Album_List (ET_File *ETFile);
 
@@ -326,21 +324,6 @@ File_Name *ET_File_Name_Item_New (void)
     return FileName;
 }
 
-
-/*
- * Create a new File_Tag structure
- */
-File_Tag *ET_File_Tag_Item_New (void)
-{
-    File_Tag *FileTag;
-
-    FileTag = g_slice_new (File_Tag);
-    ET_Initialize_File_Tag_Item (FileTag);
-
-    return FileTag;
-}
-
-
 /*
  * Create a new File_Info structure
  */
@@ -382,35 +365,6 @@ ET_Initialize_File_Name_Item (File_Name *FileName)
 }
 
 
-static void
-ET_Initialize_File_Tag_Item (File_Tag *FileTag)
-{
-    if (FileTag)
-    {
-        FileTag->key         = ET_Undo_Key_New();
-        FileTag->saved       = FALSE;
-        FileTag->title       = NULL;
-        FileTag->artist      = NULL;
-        FileTag->album_artist= NULL;
-        FileTag->album       = NULL;
-        FileTag->disc_number = NULL;
-        FileTag->disc_total = NULL;
-        FileTag->track       = NULL;
-        FileTag->track_total = NULL;
-        FileTag->year        = NULL;
-        FileTag->genre       = NULL;
-        FileTag->comment     = NULL;
-        FileTag->composer    = NULL;
-        FileTag->orig_artist = NULL;
-        FileTag->copyright   = NULL;
-        FileTag->url         = NULL;
-        FileTag->encoded_by  = NULL;
-        FileTag->picture     = NULL;
-        FileTag->other       = NULL;
-    }
-}
-
-
 /* Key for each item of ETFileList */
 static guint
 ET_File_Key_New (void)
@@ -420,7 +374,7 @@ ET_File_Key_New (void)
 }
 
 /* Key for Undo */
-static guint
+guint
 ET_Undo_Key_New (void)
 {
     static guint ETUndoKey = 0;
@@ -2388,50 +2342,6 @@ ET_Free_File_Tag_List (GList *FileTagList)
 
 
 /*
- * Frees the list of 'other' field in a File_Tag item (contains attached gchar data).
- */
-static gboolean
-ET_Free_File_Tag_Item_Other_Field (File_Tag *FileTag)
-{
-    g_list_free_full (FileTag->other, g_free);
-
-    return TRUE;
-}
-
-
-/*
- * Frees a File_Tag item.
- */
-gboolean ET_Free_File_Tag_Item (File_Tag *FileTag)
-{
-    g_return_val_if_fail (FileTag != NULL, FALSE);
-
-    g_free(FileTag->title);
-    g_free(FileTag->artist);
-    g_free(FileTag->album_artist);
-    g_free(FileTag->album);
-    g_free(FileTag->disc_number);
-    g_free (FileTag->disc_total);
-    g_free(FileTag->year);
-    g_free(FileTag->track);
-    g_free(FileTag->track_total);
-    g_free(FileTag->genre);
-    g_free(FileTag->comment);
-    g_free(FileTag->composer);
-    g_free(FileTag->orig_artist);
-    g_free(FileTag->copyright);
-    g_free(FileTag->url);
-    g_free(FileTag->encoded_by);
-    et_file_tag_set_picture (FileTag, NULL);
-    // Free list of other fields
-    ET_Free_File_Tag_Item_Other_Field(FileTag);
-
-    g_slice_free (File_Tag, FileTag);
-    return TRUE;
-}
-
-
-/*
  * Frees a File_Info item.
  */
 static gboolean
@@ -2534,205 +2444,6 @@ ET_Free_Artist_Album_File_List (void)
  *********************/
 
 /*
- * Duplicate the 'other' list
- */
-static void
-ET_Copy_File_Tag_Item_Other_Field (const ET_File *ETFile,
-                                   File_Tag *FileTag)
-{
-    const File_Tag *FileTagCur;
-    GList *l;
-
-    FileTagCur = (File_Tag *)(ETFile->FileTag)->data;
-
-    for (l = FileTagCur->other; l != NULL; l = g_list_next (l))
-    {
-        FileTag->other = g_list_prepend (FileTag->other,
-                                         g_strdup ((gchar *)l->data));
-    }
-
-    FileTag->other = g_list_reverse (FileTag->other);
-}
-
-
-/*
- * Copy data of the File_Tag structure (of ETFile) to the FileTag item.
- * Reallocate data if not null.
- */
-gboolean
-ET_Copy_File_Tag_Item (const ET_File *ETFile, File_Tag *FileTag)
-{
-    const File_Tag *FileTagCur;
-
-    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL &&
-                          (File_Tag *)(ETFile->FileTag)->data != NULL, FALSE);
-    g_return_val_if_fail (FileTag != NULL, FALSE);
-
-    /* The data to duplicate to FileTag */
-    FileTagCur = (File_Tag *)(ETFile->FileTag)->data;
-    // Key for the item, may be overwritten
-    FileTag->key = ET_Undo_Key_New();
-
-    if (FileTagCur->title)
-    {
-        FileTag->title = g_strdup(FileTagCur->title);
-    }else
-    {
-        g_free(FileTag->title);
-        FileTag->title = NULL;
-    }
-
-    if (FileTagCur->artist)
-    {
-        FileTag->artist = g_strdup(FileTagCur->artist);
-    }else
-    {
-        g_free(FileTag->artist);
-        FileTag->artist = NULL;
-    }
-
-    if (FileTagCur->album_artist)
-    {
-        FileTag->album_artist = g_strdup(FileTagCur->album_artist);
-    }else
-    {
-        g_free(FileTag->album_artist);
-        FileTag->album_artist = NULL;
-    }
-
-    if (FileTagCur->album)
-    {
-        FileTag->album = g_strdup(FileTagCur->album);
-    }else
-    {
-        g_free(FileTag->album);
-        FileTag->album = NULL;
-    }
-
-    if (FileTagCur->disc_number)
-    {
-        FileTag->disc_number = g_strdup(FileTagCur->disc_number);
-    }else
-    {
-        g_free(FileTag->disc_number);
-        FileTag->disc_number = NULL;
-    }
-
-    if (FileTagCur->disc_total)
-    {
-        FileTag->disc_total = g_strdup (FileTagCur->disc_total);
-    }
-    else
-    {
-        g_free (FileTag->disc_total);
-        FileTag->disc_total = NULL;
-    }
-
-    if (FileTagCur->year)
-    {
-        FileTag->year = g_strdup(FileTagCur->year);
-    }else
-    {
-        g_free(FileTag->year);
-        FileTag->year = NULL;
-    }
-
-    if (FileTagCur->track)
-    {
-        FileTag->track = g_strdup(FileTagCur->track);
-    }else
-    {
-        g_free(FileTag->track);
-        FileTag->track = NULL;
-    }
-
-    if (FileTagCur->track_total)
-    {
-        FileTag->track_total = g_strdup(FileTagCur->track_total);
-    }else
-    {
-        g_free(FileTag->track_total);
-        FileTag->track_total = NULL;
-    }
-
-    if (FileTagCur->genre)
-    {
-        FileTag->genre = g_strdup(FileTagCur->genre);
-    }else
-    {
-        g_free(FileTag->genre);
-        FileTag->genre = NULL;
-    }
-
-    if (FileTagCur->comment)
-    {
-        FileTag->comment = g_strdup(FileTagCur->comment);
-    }else
-    {
-        g_free(FileTag->comment);
-        FileTag->comment = NULL;
-    }
-
-    if (FileTagCur->composer)
-    {
-        FileTag->composer = g_strdup(FileTagCur->composer);
-    }else
-    {
-        g_free(FileTag->composer);
-        FileTag->composer = NULL;
-    }
-
-    if (FileTagCur->orig_artist)
-    {
-        FileTag->orig_artist = g_strdup(FileTagCur->orig_artist);
-    }else
-    {
-        g_free(FileTag->orig_artist);
-        FileTag->orig_artist = NULL;
-    }
-
-    if (FileTagCur->copyright)
-    {
-        FileTag->copyright = g_strdup(FileTagCur->copyright);
-    }else
-    {
-        g_free(FileTag->copyright);
-        FileTag->copyright = NULL;
-    }
-
-    if (FileTagCur->url)
-    {
-        FileTag->url = g_strdup(FileTagCur->url);
-    }else
-    {
-        g_free(FileTag->url);
-        FileTag->url = NULL;
-    }
-
-    if (FileTagCur->encoded_by)
-    {
-        FileTag->encoded_by = g_strdup(FileTagCur->encoded_by);
-    }else
-    {
-        g_free(FileTag->encoded_by);
-        FileTag->encoded_by = NULL;
-    }
-
-    et_file_tag_set_picture (FileTag, FileTagCur->picture);
-
-    if (FileTagCur->other)
-    {
-        ET_Copy_File_Tag_Item_Other_Field(ETFile,FileTag);
-    }else
-    {
-        ET_Free_File_Tag_Item_Other_Field (FileTag);
-    }
-
-    return TRUE;
-}
-
-
-/*
  * Fill content of a FileName item according to the filename passed in argument (UTF-8 filename or not)
  * Calculate also the collate key.
  * It treats numbers intelligently so that "file1" "file10" "file5" is sorted as "file1" "file5" "file10"
@@ -2767,203 +2478,6 @@ ET_Set_Filename_File_Name_Item (File_Name *FileName,
     return TRUE;
 }
 
-
-/*
- * Set the value of a field of a FileTag item (for ex, value of FileTag->title)
- * Must be used only for the 'gchar *' components
- */
-static void
-ET_Set_Field_File_Tag_Item (gchar **FileTagField,
-                            const gchar *value)
-{
-    g_return_if_fail (FileTagField != NULL);
-
-    if (*FileTagField != NULL)
-    {
-        g_free (*FileTagField);
-        *FileTagField = NULL;
-    }
-
-    if (value != NULL)
-    {
-        if (*value != '\0')
-        {
-            *FileTagField = g_strdup (value);
-        }
-    }
-}
-
-void
-et_file_tag_set_title (File_Tag *file_tag,
-                       const gchar *title)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->title, title);
-}
-
-void
-et_file_tag_set_artist (File_Tag *file_tag,
-                        const gchar *artist)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->artist, artist);
-}
-
-void
-et_file_tag_set_album_artist (File_Tag *file_tag,
-                              const gchar *album_artist)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->album_artist, album_artist);
-}
-
-void
-et_file_tag_set_album (File_Tag *file_tag,
-                       const gchar *album)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->album, album);
-}
-
-void
-et_file_tag_set_disc_number (File_Tag *file_tag,
-                             const gchar *disc_number)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->disc_number, disc_number);
-}
-
-void
-et_file_tag_set_disc_total (File_Tag *file_tag,
-                            const gchar *disc_total)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->disc_total, disc_total);
-}
-
-void
-et_file_tag_set_year (File_Tag *file_tag,
-                      const gchar *year)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->year, year);
-}
-
-void
-et_file_tag_set_track_number (File_Tag *file_tag,
-                              const gchar *track_number)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->track, track_number);
-}
-
-void
-et_file_tag_set_track_total (File_Tag *file_tag,
-                             const gchar *track_total)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->track_total, track_total);
-}
-
-void
-et_file_tag_set_genre (File_Tag *file_tag,
-                       const gchar *genre)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->genre, genre);
-}
-
-void
-et_file_tag_set_comment (File_Tag *file_tag,
-                         const gchar *comment)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->comment, comment);
-}
-
-void
-et_file_tag_set_composer (File_Tag *file_tag,
-                          const gchar *composer)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->composer, composer);
-}
-
-void
-et_file_tag_set_orig_artist (File_Tag *file_tag,
-                             const gchar *orig_artist)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->orig_artist, orig_artist);
-}
-
-void
-et_file_tag_set_copyright (File_Tag *file_tag,
-                           const gchar *copyright)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->copyright, copyright);
-}
-
-void
-et_file_tag_set_url (File_Tag *file_tag,
-                     const gchar *url)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->url, url);
-}
-
-void
-et_file_tag_set_encoded_by (File_Tag *file_tag,
-                            const gchar *encoded_by)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    ET_Set_Field_File_Tag_Item (&file_tag->encoded_by, encoded_by);
-}
-
-/*
- * et_file_tag_set_picture:
- * @file_tag: the #File_Tag on which to set the image
- * @pic: the image to set
- *
- * Set the images inside @file_tag to be @pic, freeing existing images as
- * necessary. Copies @pic with et_picture_copy_all().
- */
-void
-et_file_tag_set_picture (File_Tag *file_tag,
-                         const EtPicture *pic)
-{
-    g_return_if_fail (file_tag != NULL);
-
-    if (file_tag->picture != NULL)
-    {
-        et_picture_free (file_tag->picture);
-        file_tag->picture = NULL;
-    }
-
-    if (pic)
-    {
-        file_tag->picture = et_picture_copy_all (pic);
-    }
-}
-
-
 /************************
  * Displaying functions *
  ************************/
@@ -3893,150 +3407,6 @@ ET_Detect_Changes_Of_File_Name (const File_Name *FileName1,
 }
 
 /*
- * Compares two File_Tag items and returns TRUE if there aren't the same.
- * Notes:
- *  - if field is '' or NULL => will be removed
- */
-gboolean
-ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1,
-                               const File_Tag *FileTag2)
-{
-    const EtPicture *pic1;
-    const EtPicture *pic2;
-
-    g_return_val_if_fail (FileTag1 != NULL && FileTag2 != NULL, FALSE);
-
-    if ( ( FileTag1 && !FileTag2)
-      || (!FileTag1 &&  FileTag2) )
-        return TRUE;
-
-    /* Title */
-    if ( FileTag1->title && !FileTag2->title && g_utf8_strlen(FileTag1->title, -1)>0 ) return TRUE;
-    if (!FileTag1->title &&  FileTag2->title && g_utf8_strlen(FileTag2->title, -1)>0 ) return TRUE;
-    if ( FileTag1->title &&  FileTag2->title && g_utf8_collate(FileTag1->title,FileTag2->title)!=0 ) return 
TRUE;
-
-    /* Artist */
-    if ( FileTag1->artist && !FileTag2->artist && g_utf8_strlen(FileTag1->artist, -1)>0 ) return TRUE;
-    if (!FileTag1->artist &&  FileTag2->artist && g_utf8_strlen(FileTag2->artist, -1)>0 ) return TRUE;
-    if ( FileTag1->artist &&  FileTag2->artist && g_utf8_collate(FileTag1->artist,FileTag2->artist)!=0 ) 
return TRUE;
-
-       /* Album Artist */
-    if ( FileTag1->album_artist && !FileTag2->album_artist && g_utf8_strlen(FileTag1->album_artist, -1)>0 ) 
return TRUE;
-    if (!FileTag1->album_artist &&  FileTag2->album_artist && g_utf8_strlen(FileTag2->album_artist, -1)>0 ) 
return TRUE;
-    if ( FileTag1->album_artist &&  FileTag2->album_artist && 
g_utf8_collate(FileTag1->album_artist,FileTag2->album_artist)!=0 ) return TRUE;
-
-    /* Album */
-    if ( FileTag1->album && !FileTag2->album && g_utf8_strlen(FileTag1->album, -1)>0 ) return TRUE;
-    if (!FileTag1->album &&  FileTag2->album && g_utf8_strlen(FileTag2->album, -1)>0 ) return TRUE;
-    if ( FileTag1->album &&  FileTag2->album && g_utf8_collate(FileTag1->album,FileTag2->album)!=0 ) return 
TRUE;
-
-    /* Disc Number */
-    if ( FileTag1->disc_number && !FileTag2->disc_number && g_utf8_strlen(FileTag1->disc_number, -1)>0 ) 
return TRUE;
-    if (!FileTag1->disc_number &&  FileTag2->disc_number && g_utf8_strlen(FileTag2->disc_number, -1)>0 ) 
return TRUE;
-    if ( FileTag1->disc_number &&  FileTag2->disc_number && 
g_utf8_collate(FileTag1->disc_number,FileTag2->disc_number)!=0 ) return TRUE;
-
-    /* Discs Total */
-    if (FileTag1->disc_total && !FileTag2->disc_total
-        && g_utf8_strlen (FileTag1->disc_total, -1) > 0)
-    {
-        return TRUE;
-    }
-
-    if (!FileTag1->disc_total &&  FileTag2->disc_total
-        && g_utf8_strlen (FileTag2->disc_total, -1) > 0)
-    {
-        return TRUE;
-    }
-
-    if (FileTag1->disc_total &&  FileTag2->disc_total
-        && g_utf8_collate (FileTag1->disc_total, FileTag2->disc_total) != 0)
-    {
-        return TRUE;
-    }
-
-    /* Year */
-    if ( FileTag1->year && !FileTag2->year && g_utf8_strlen(FileTag1->year, -1)>0 ) return TRUE;
-    if (!FileTag1->year &&  FileTag2->year && g_utf8_strlen(FileTag2->year, -1)>0 ) return TRUE;
-    if ( FileTag1->year &&  FileTag2->year && g_utf8_collate(FileTag1->year,FileTag2->year)!=0 ) return TRUE;
-
-    /* Track */
-    if ( FileTag1->track && !FileTag2->track && g_utf8_strlen(FileTag1->track, -1)>0 ) return TRUE;
-    if (!FileTag1->track &&  FileTag2->track && g_utf8_strlen(FileTag2->track, -1)>0 ) return TRUE;
-    if ( FileTag1->track &&  FileTag2->track && g_utf8_collate(FileTag1->track,FileTag2->track)!=0 ) return 
TRUE;
-
-    /* Track Total */
-    if ( FileTag1->track_total && !FileTag2->track_total && g_utf8_strlen(FileTag1->track_total, -1)>0 ) 
return TRUE;
-    if (!FileTag1->track_total &&  FileTag2->track_total && g_utf8_strlen(FileTag2->track_total, -1)>0 ) 
return TRUE;
-    if ( FileTag1->track_total &&  FileTag2->track_total && 
g_utf8_collate(FileTag1->track_total,FileTag2->track_total)!=0 ) return TRUE;
-
-    /* Genre */
-    if ( FileTag1->genre && !FileTag2->genre && g_utf8_strlen(FileTag1->genre, -1)>0 ) return TRUE;
-    if (!FileTag1->genre &&  FileTag2->genre && g_utf8_strlen(FileTag2->genre, -1)>0 ) return TRUE;
-    if ( FileTag1->genre &&  FileTag2->genre && g_utf8_collate(FileTag1->genre,FileTag2->genre)!=0 ) return 
TRUE;
-
-    /* Comment */
-    if ( FileTag1->comment && !FileTag2->comment && g_utf8_strlen(FileTag1->comment, -1)>0 ) return TRUE;
-    if (!FileTag1->comment &&  FileTag2->comment && g_utf8_strlen(FileTag2->comment, -1)>0 ) return TRUE;
-    if ( FileTag1->comment &&  FileTag2->comment && g_utf8_collate(FileTag1->comment,FileTag2->comment)!=0 ) 
return TRUE;
-
-    /* Composer */
-    if ( FileTag1->composer && !FileTag2->composer && g_utf8_strlen(FileTag1->composer, -1)>0 ) return TRUE;
-    if (!FileTag1->composer &&  FileTag2->composer && g_utf8_strlen(FileTag2->composer, -1)>0 ) return TRUE;
-    if ( FileTag1->composer &&  FileTag2->composer && 
g_utf8_collate(FileTag1->composer,FileTag2->composer)!=0 ) return TRUE;
-
-    /* Original artist */
-    if ( FileTag1->orig_artist && !FileTag2->orig_artist && g_utf8_strlen(FileTag1->orig_artist, -1)>0 ) 
return TRUE;
-    if (!FileTag1->orig_artist &&  FileTag2->orig_artist && g_utf8_strlen(FileTag2->orig_artist, -1)>0 ) 
return TRUE;
-    if ( FileTag1->orig_artist &&  FileTag2->orig_artist && 
g_utf8_collate(FileTag1->orig_artist,FileTag2->orig_artist)!=0 ) return TRUE;
-
-    /* Copyright */
-    if ( FileTag1->copyright && !FileTag2->copyright && g_utf8_strlen(FileTag1->copyright, -1)>0 ) return 
TRUE;
-    if (!FileTag1->copyright &&  FileTag2->copyright && g_utf8_strlen(FileTag2->copyright, -1)>0 ) return 
TRUE;
-    if ( FileTag1->copyright &&  FileTag2->copyright && 
g_utf8_collate(FileTag1->copyright,FileTag2->copyright)!=0 ) return TRUE;
-
-    /* URL */
-    if ( FileTag1->url && !FileTag2->url && g_utf8_strlen(FileTag1->url, -1)>0 ) return TRUE;
-    if (!FileTag1->url &&  FileTag2->url && g_utf8_strlen(FileTag2->url, -1)>0 ) return TRUE;
-    if ( FileTag1->url &&  FileTag2->url && g_utf8_collate(FileTag1->url,FileTag2->url)!=0 ) return TRUE;
-
-    /* Encoded by */
-    if ( FileTag1->encoded_by && !FileTag2->encoded_by && g_utf8_strlen(FileTag1->encoded_by, -1)>0 ) return 
TRUE;
-    if (!FileTag1->encoded_by &&  FileTag2->encoded_by && g_utf8_strlen(FileTag2->encoded_by, -1)>0 ) return 
TRUE;
-    if ( FileTag1->encoded_by &&  FileTag2->encoded_by && 
g_utf8_collate(FileTag1->encoded_by,FileTag2->encoded_by)!=0 ) return TRUE;
-
-    /* Picture */
-    for (pic1 = FileTag1->picture, pic2 = FileTag2->picture; ;
-         pic1 = pic1->next, pic2 = pic2->next)
-    {
-        if( (pic1 && !pic2) || (!pic1 && pic2) )
-            return TRUE;
-        if (!pic1 || !pic2)
-            break; // => no changes
-        //if (!pic1->data || !pic2->data)
-        //    break; // => no changes
-
-        if (!g_bytes_equal (pic1->bytes, pic2->bytes))
-        {
-            return TRUE;
-        }
-        if (pic1->type != pic2->type)
-            return TRUE;
-        if (pic1->description && !pic2->description
-        &&  g_utf8_strlen(pic1->description, -1)>0 )
-            return TRUE;
-        if (!pic1->description && pic2->description
-        &&  g_utf8_strlen(pic2->description, -1)>0 )
-            return TRUE;
-        if (pic1->description && pic2->description
-        &&  g_utf8_collate(pic1->description, pic2->description)!=0 )
-            return TRUE;
-    }
-
-    return FALSE; /* No changes */
-}
-
-
-/*
  * Add a FileName item to the history list of ETFile
  */
 static gboolean
diff --git a/src/et_core.h b/src/et_core.h
index 5b683a9..e8677bd 100644
--- a/src/et_core.h
+++ b/src/et_core.h
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
 #include <gdk/gdk.h>
 
 #include "core_types.h"
+#include "file_tag.h"
 #include "picture.h"
 
 /*
@@ -49,36 +50,6 @@ struct _File_Name
 };
 
 /*
- * Description of each item of the TagList list
- */
-typedef struct _File_Tag File_Tag;
-struct _File_Tag
-{
-    guint key;             /* Incremented value */
-    gboolean saved;        /* Set to TRUE if this tag had been saved */
-
-    gchar *title;          /* Title of track */
-    gchar *artist;         /* Artist name */
-    gchar *album_artist;   /* Album Artist */
-    gchar *album;          /* Album name */
-    gchar *disc_number;    /* Disc number */
-    gchar *disc_total; /* The total number of discs of the album (ex: 1/2). */
-    gchar *year;           /* Year of track */
-    gchar *track;          /* Position of track in the album */
-    gchar *track_total;    /* The number of tracks for the album (ex: 12/20) */
-    gchar *genre;          /* Genre of song */
-    gchar *comment;        /* Comment */
-    gchar *composer;       /* Composer */
-    gchar *orig_artist;    /* Original artist / Performer */
-    gchar *copyright;      /* Copyright */
-    gchar *url;            /* URL */
-    gchar *encoded_by;     /* Encoded by */
-    EtPicture *picture; /* Picture */
-    GList *other;          /* List of unsupported fields (used for ogg only) */
-};
-
-
-/*
  * Structure containing informations of the header of file
  * Nota: This struct was copied from an "MP3 structure", and will change later.
  */
@@ -241,30 +212,14 @@ gboolean ET_Check_If_All_Files_Are_Saved (void);
 
 ET_File      *ET_File_Item_New       (void);
 File_Name    *ET_File_Name_Item_New  (void);
-File_Tag     *ET_File_Tag_Item_New   (void);
-gboolean      ET_Free_File_Tag_Item  (File_Tag *FileTag);
 void      ET_Free_File_List_Item (ET_File *ETFile);
 
-gboolean ET_Copy_File_Tag_Item (const ET_File *ETFile, File_Tag *FileTag);
 gboolean ET_Set_Field_File_Name_Item    (gchar **FileNameField, gchar *value);
 gboolean ET_Set_Filename_File_Name_Item (File_Name *FileName, const gchar *filename_utf8, const gchar 
*filename);
-void et_file_tag_set_title (File_Tag *file_tag, const gchar *title);
-void et_file_tag_set_artist (File_Tag *file_tag, const gchar *artist);
-void et_file_tag_set_album_artist (File_Tag *file_tag, const gchar *album_artist);
-void et_file_tag_set_album (File_Tag *file_tag, const gchar *album);
-void et_file_tag_set_disc_number (File_Tag *file_tag, const gchar *disc_number);
-void et_file_tag_set_disc_total (File_Tag *file_tag, const gchar *disc_total);
-void et_file_tag_set_year (File_Tag *file_tag, const gchar *year);
-void et_file_tag_set_track_number (File_Tag *file_tag, const gchar *track_number);
-void et_file_tag_set_track_total (File_Tag *file_tag, const gchar *track_total);
-void et_file_tag_set_genre (File_Tag *file_tag, const gchar *genre);
-void et_file_tag_set_comment (File_Tag *file_tag, const gchar *comment);
-void et_file_tag_set_composer (File_Tag *file_tag, const gchar *composer);
-void et_file_tag_set_orig_artist (File_Tag *file_tag, const gchar *orig_artist);
-void et_file_tag_set_copyright (File_Tag *file_tag, const gchar *copyright);
-void et_file_tag_set_url (File_Tag *file_tag, const gchar *url);
-void et_file_tag_set_encoded_by (File_Tag *file_tag, const gchar *encoded_by);
-void et_file_tag_set_picture (File_Tag *file_tag, const EtPicture *pic);
+
+/* FIXME: Move to file_tag.h. */
+gboolean ET_Copy_File_Tag_Item (const ET_File *ETFile, File_Tag *FileTag);
+void ET_Copy_File_Tag_Item_Other_Field (const ET_File *ETFile, File_Tag *FileTag);
 
 GList   *ET_Displayed_File_List_First       (void);
 GList   *ET_Displayed_File_List_Previous    (void);
@@ -278,6 +233,8 @@ void     ET_Display_File_Data_To_UI (ET_File *ETFile);
 void     ET_Save_File_Data_From_UI  (ET_File *ETFile);
 gboolean ET_Save_File_Tag_To_HD (ET_File *ETFile, GError **error);
 
+guint ET_Undo_Key_New (void);
+
 gboolean ET_Undo_File_Data          (ET_File *ETFile);
 gboolean ET_Redo_File_Data          (ET_File *ETFile);
 gboolean ET_File_Data_Has_Undo_Data (const ET_File *ETFile);
@@ -295,8 +252,6 @@ gboolean ET_File_Name_Convert_Character          (gchar *filename_utf8);
 gchar *ET_File_Name_Generate (const ET_File *ETFile, const gchar *new_file_name);
 guint ET_Get_Number_Of_Files_In_Directory (const gchar *path_utf8);
 
-gboolean ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1, const File_Tag  *FileTag2);
-
 GList *ET_Sort_File_List (GList *ETFileList, EtSortMode Sorting_Type);
 void ET_Sort_Displayed_File_List_And_Update_UI (EtSortMode Sorting_Type);
 gint ET_Comp_Func_Sort_File_By_Ascending_Filename (const ET_File *ETFile1, const ET_File *ETFile2);
diff --git a/src/file_tag.c b/src/file_tag.c
new file mode 100644
index 0000000..ab2748b
--- /dev/null
+++ b/src/file_tag.c
@@ -0,0 +1,641 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2014  David King <amigadave amigadave com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "file_tag.h"
+
+#include "et_core.h"
+
+static void
+ET_Initialize_File_Tag_Item (File_Tag *FileTag)
+{
+    if (FileTag)
+    {
+        FileTag->key         = ET_Undo_Key_New();
+        FileTag->saved       = FALSE;
+        FileTag->title       = NULL;
+        FileTag->artist      = NULL;
+        FileTag->album_artist= NULL;
+        FileTag->album       = NULL;
+        FileTag->disc_number = NULL;
+        FileTag->disc_total = NULL;
+        FileTag->track       = NULL;
+        FileTag->track_total = NULL;
+        FileTag->year        = NULL;
+        FileTag->genre       = NULL;
+        FileTag->comment     = NULL;
+        FileTag->composer    = NULL;
+        FileTag->orig_artist = NULL;
+        FileTag->copyright   = NULL;
+        FileTag->url         = NULL;
+        FileTag->encoded_by  = NULL;
+        FileTag->picture     = NULL;
+        FileTag->other       = NULL;
+    }
+}
+
+/*
+ * Create a new File_Tag structure
+ */
+File_Tag *ET_File_Tag_Item_New (void)
+{
+    File_Tag *FileTag;
+
+    FileTag = g_slice_new (File_Tag);
+    ET_Initialize_File_Tag_Item (FileTag);
+
+    return FileTag;
+}
+
+/*
+ * Frees the list of 'other' field in a File_Tag item (contains attached gchar data).
+ */
+static gboolean
+ET_Free_File_Tag_Item_Other_Field (File_Tag *FileTag)
+{
+    g_list_free_full (FileTag->other, g_free);
+
+    return TRUE;
+}
+
+
+/*
+ * Frees a File_Tag item.
+ */
+gboolean ET_Free_File_Tag_Item (File_Tag *FileTag)
+{
+    g_return_val_if_fail (FileTag != NULL, FALSE);
+
+    g_free(FileTag->title);
+    g_free(FileTag->artist);
+    g_free(FileTag->album_artist);
+    g_free(FileTag->album);
+    g_free(FileTag->disc_number);
+    g_free (FileTag->disc_total);
+    g_free(FileTag->year);
+    g_free(FileTag->track);
+    g_free(FileTag->track_total);
+    g_free(FileTag->genre);
+    g_free(FileTag->comment);
+    g_free(FileTag->composer);
+    g_free(FileTag->orig_artist);
+    g_free(FileTag->copyright);
+    g_free(FileTag->url);
+    g_free(FileTag->encoded_by);
+    et_file_tag_set_picture (FileTag, NULL);
+    // Free list of other fields
+    ET_Free_File_Tag_Item_Other_Field(FileTag);
+
+    g_slice_free (File_Tag, FileTag);
+    return TRUE;
+}
+
+/*
+ * Duplicate the 'other' list
+ */
+void
+ET_Copy_File_Tag_Item_Other_Field (const ET_File *ETFile,
+                                   File_Tag *FileTag)
+{
+    const File_Tag *FileTagCur;
+    GList *l;
+
+    FileTagCur = (File_Tag *)(ETFile->FileTag)->data;
+
+    for (l = FileTagCur->other; l != NULL; l = g_list_next (l))
+    {
+        FileTag->other = g_list_prepend (FileTag->other,
+                                         g_strdup ((gchar *)l->data));
+    }
+
+    FileTag->other = g_list_reverse (FileTag->other);
+}
+
+
+/*
+ * Copy data of the File_Tag structure (of ETFile) to the FileTag item.
+ * Reallocate data if not null.
+ */
+gboolean
+ET_Copy_File_Tag_Item (const ET_File *ETFile, File_Tag *FileTag)
+{
+    const File_Tag *FileTagCur;
+
+    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL &&
+                          (File_Tag *)(ETFile->FileTag)->data != NULL, FALSE);
+    g_return_val_if_fail (FileTag != NULL, FALSE);
+
+    /* The data to duplicate to FileTag */
+    FileTagCur = (File_Tag *)(ETFile->FileTag)->data;
+    // Key for the item, may be overwritten
+    FileTag->key = ET_Undo_Key_New();
+
+    if (FileTagCur->title)
+    {
+        FileTag->title = g_strdup(FileTagCur->title);
+    }else
+    {
+        g_free(FileTag->title);
+        FileTag->title = NULL;
+    }
+
+    if (FileTagCur->artist)
+    {
+        FileTag->artist = g_strdup(FileTagCur->artist);
+    }else
+    {
+        g_free(FileTag->artist);
+        FileTag->artist = NULL;
+    }
+
+    if (FileTagCur->album_artist)
+    {
+        FileTag->album_artist = g_strdup(FileTagCur->album_artist);
+    }else
+    {
+        g_free(FileTag->album_artist);
+        FileTag->album_artist = NULL;
+    }
+
+    if (FileTagCur->album)
+    {
+        FileTag->album = g_strdup(FileTagCur->album);
+    }else
+    {
+        g_free(FileTag->album);
+        FileTag->album = NULL;
+    }
+
+    if (FileTagCur->disc_number)
+    {
+        FileTag->disc_number = g_strdup(FileTagCur->disc_number);
+    }else
+    {
+        g_free(FileTag->disc_number);
+        FileTag->disc_number = NULL;
+    }
+
+    if (FileTagCur->disc_total)
+    {
+        FileTag->disc_total = g_strdup (FileTagCur->disc_total);
+    }
+    else
+    {
+        g_free (FileTag->disc_total);
+        FileTag->disc_total = NULL;
+    }
+
+    if (FileTagCur->year)
+    {
+        FileTag->year = g_strdup(FileTagCur->year);
+    }else
+    {
+        g_free(FileTag->year);
+        FileTag->year = NULL;
+    }
+
+    if (FileTagCur->track)
+    {
+        FileTag->track = g_strdup(FileTagCur->track);
+    }else
+    {
+        g_free(FileTag->track);
+        FileTag->track = NULL;
+    }
+
+    if (FileTagCur->track_total)
+    {
+        FileTag->track_total = g_strdup(FileTagCur->track_total);
+    }else
+    {
+        g_free(FileTag->track_total);
+        FileTag->track_total = NULL;
+    }
+
+    if (FileTagCur->genre)
+    {
+        FileTag->genre = g_strdup(FileTagCur->genre);
+    }else
+    {
+        g_free(FileTag->genre);
+        FileTag->genre = NULL;
+    }
+
+    if (FileTagCur->comment)
+    {
+        FileTag->comment = g_strdup(FileTagCur->comment);
+    }else
+    {
+        g_free(FileTag->comment);
+        FileTag->comment = NULL;
+    }
+
+    if (FileTagCur->composer)
+    {
+        FileTag->composer = g_strdup(FileTagCur->composer);
+    }else
+    {
+        g_free(FileTag->composer);
+        FileTag->composer = NULL;
+    }
+
+    if (FileTagCur->orig_artist)
+    {
+        FileTag->orig_artist = g_strdup(FileTagCur->orig_artist);
+    }else
+    {
+        g_free(FileTag->orig_artist);
+        FileTag->orig_artist = NULL;
+    }
+
+    if (FileTagCur->copyright)
+    {
+        FileTag->copyright = g_strdup(FileTagCur->copyright);
+    }else
+    {
+        g_free(FileTag->copyright);
+        FileTag->copyright = NULL;
+    }
+
+    if (FileTagCur->url)
+    {
+        FileTag->url = g_strdup(FileTagCur->url);
+    }else
+    {
+        g_free(FileTag->url);
+        FileTag->url = NULL;
+    }
+
+    if (FileTagCur->encoded_by)
+    {
+        FileTag->encoded_by = g_strdup(FileTagCur->encoded_by);
+    }else
+    {
+        g_free(FileTag->encoded_by);
+        FileTag->encoded_by = NULL;
+    }
+
+    et_file_tag_set_picture (FileTag, FileTagCur->picture);
+
+    if (FileTagCur->other)
+    {
+        ET_Copy_File_Tag_Item_Other_Field(ETFile,FileTag);
+    }else
+    {
+        ET_Free_File_Tag_Item_Other_Field (FileTag);
+    }
+
+    return TRUE;
+}
+
+/*
+ * Set the value of a field of a FileTag item (for ex, value of FileTag->title)
+ * Must be used only for the 'gchar *' components
+ */
+static void
+ET_Set_Field_File_Tag_Item (gchar **FileTagField,
+                            const gchar *value)
+{
+    g_return_if_fail (FileTagField != NULL);
+
+    if (*FileTagField != NULL)
+    {
+        g_free (*FileTagField);
+        *FileTagField = NULL;
+    }
+
+    if (value != NULL)
+    {
+        if (*value != '\0')
+        {
+            *FileTagField = g_strdup (value);
+        }
+    }
+}
+
+void
+et_file_tag_set_title (File_Tag *file_tag,
+                       const gchar *title)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->title, title);
+}
+
+void
+et_file_tag_set_artist (File_Tag *file_tag,
+                        const gchar *artist)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->artist, artist);
+}
+
+void
+et_file_tag_set_album_artist (File_Tag *file_tag,
+                              const gchar *album_artist)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->album_artist, album_artist);
+}
+
+void
+et_file_tag_set_album (File_Tag *file_tag,
+                       const gchar *album)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->album, album);
+}
+
+void
+et_file_tag_set_disc_number (File_Tag *file_tag,
+                             const gchar *disc_number)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->disc_number, disc_number);
+}
+
+void
+et_file_tag_set_disc_total (File_Tag *file_tag,
+                            const gchar *disc_total)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->disc_total, disc_total);
+}
+
+void
+et_file_tag_set_year (File_Tag *file_tag,
+                      const gchar *year)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->year, year);
+}
+
+void
+et_file_tag_set_track_number (File_Tag *file_tag,
+                              const gchar *track_number)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->track, track_number);
+}
+
+void
+et_file_tag_set_track_total (File_Tag *file_tag,
+                             const gchar *track_total)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->track_total, track_total);
+}
+
+void
+et_file_tag_set_genre (File_Tag *file_tag,
+                       const gchar *genre)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->genre, genre);
+}
+
+void
+et_file_tag_set_comment (File_Tag *file_tag,
+                         const gchar *comment)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->comment, comment);
+}
+
+void
+et_file_tag_set_composer (File_Tag *file_tag,
+                          const gchar *composer)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->composer, composer);
+}
+
+void
+et_file_tag_set_orig_artist (File_Tag *file_tag,
+                             const gchar *orig_artist)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->orig_artist, orig_artist);
+}
+
+void
+et_file_tag_set_copyright (File_Tag *file_tag,
+                           const gchar *copyright)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->copyright, copyright);
+}
+
+void
+et_file_tag_set_url (File_Tag *file_tag,
+                     const gchar *url)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->url, url);
+}
+
+void
+et_file_tag_set_encoded_by (File_Tag *file_tag,
+                            const gchar *encoded_by)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    ET_Set_Field_File_Tag_Item (&file_tag->encoded_by, encoded_by);
+}
+
+/*
+ * et_file_tag_set_picture:
+ * @file_tag: the #File_Tag on which to set the image
+ * @pic: the image to set
+ *
+ * Set the images inside @file_tag to be @pic, freeing existing images as
+ * necessary. Copies @pic with et_picture_copy_all().
+ */
+void
+et_file_tag_set_picture (File_Tag *file_tag,
+                         const EtPicture *pic)
+{
+    g_return_if_fail (file_tag != NULL);
+
+    if (file_tag->picture != NULL)
+    {
+        et_picture_free (file_tag->picture);
+        file_tag->picture = NULL;
+    }
+
+    if (pic)
+    {
+        file_tag->picture = et_picture_copy_all (pic);
+    }
+}
+
+/*
+ * Compares two File_Tag items and returns TRUE if there aren't the same.
+ * Notes:
+ *  - if field is '' or NULL => will be removed
+ */
+gboolean
+ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1,
+                               const File_Tag *FileTag2)
+{
+    const EtPicture *pic1;
+    const EtPicture *pic2;
+
+    g_return_val_if_fail (FileTag1 != NULL && FileTag2 != NULL, FALSE);
+
+    if ( ( FileTag1 && !FileTag2)
+      || (!FileTag1 &&  FileTag2) )
+        return TRUE;
+
+    /* Title */
+    if ( FileTag1->title && !FileTag2->title && g_utf8_strlen(FileTag1->title, -1)>0 ) return TRUE;
+    if (!FileTag1->title &&  FileTag2->title && g_utf8_strlen(FileTag2->title, -1)>0 ) return TRUE;
+    if ( FileTag1->title &&  FileTag2->title && g_utf8_collate(FileTag1->title,FileTag2->title)!=0 ) return 
TRUE;
+
+    /* Artist */
+    if ( FileTag1->artist && !FileTag2->artist && g_utf8_strlen(FileTag1->artist, -1)>0 ) return TRUE;
+    if (!FileTag1->artist &&  FileTag2->artist && g_utf8_strlen(FileTag2->artist, -1)>0 ) return TRUE;
+    if ( FileTag1->artist &&  FileTag2->artist && g_utf8_collate(FileTag1->artist,FileTag2->artist)!=0 ) 
return TRUE;
+
+       /* Album Artist */
+    if ( FileTag1->album_artist && !FileTag2->album_artist && g_utf8_strlen(FileTag1->album_artist, -1)>0 ) 
return TRUE;
+    if (!FileTag1->album_artist &&  FileTag2->album_artist && g_utf8_strlen(FileTag2->album_artist, -1)>0 ) 
return TRUE;
+    if ( FileTag1->album_artist &&  FileTag2->album_artist && 
g_utf8_collate(FileTag1->album_artist,FileTag2->album_artist)!=0 ) return TRUE;
+
+    /* Album */
+    if ( FileTag1->album && !FileTag2->album && g_utf8_strlen(FileTag1->album, -1)>0 ) return TRUE;
+    if (!FileTag1->album &&  FileTag2->album && g_utf8_strlen(FileTag2->album, -1)>0 ) return TRUE;
+    if ( FileTag1->album &&  FileTag2->album && g_utf8_collate(FileTag1->album,FileTag2->album)!=0 ) return 
TRUE;
+
+    /* Disc Number */
+    if ( FileTag1->disc_number && !FileTag2->disc_number && g_utf8_strlen(FileTag1->disc_number, -1)>0 ) 
return TRUE;
+    if (!FileTag1->disc_number &&  FileTag2->disc_number && g_utf8_strlen(FileTag2->disc_number, -1)>0 ) 
return TRUE;
+    if ( FileTag1->disc_number &&  FileTag2->disc_number && 
g_utf8_collate(FileTag1->disc_number,FileTag2->disc_number)!=0 ) return TRUE;
+
+    /* Discs Total */
+    if (FileTag1->disc_total && !FileTag2->disc_total
+        && g_utf8_strlen (FileTag1->disc_total, -1) > 0)
+    {
+        return TRUE;
+    }
+
+    if (!FileTag1->disc_total &&  FileTag2->disc_total
+        && g_utf8_strlen (FileTag2->disc_total, -1) > 0)
+    {
+        return TRUE;
+    }
+
+    if (FileTag1->disc_total &&  FileTag2->disc_total
+        && g_utf8_collate (FileTag1->disc_total, FileTag2->disc_total) != 0)
+    {
+        return TRUE;
+    }
+
+    /* Year */
+    if ( FileTag1->year && !FileTag2->year && g_utf8_strlen(FileTag1->year, -1)>0 ) return TRUE;
+    if (!FileTag1->year &&  FileTag2->year && g_utf8_strlen(FileTag2->year, -1)>0 ) return TRUE;
+    if ( FileTag1->year &&  FileTag2->year && g_utf8_collate(FileTag1->year,FileTag2->year)!=0 ) return TRUE;
+
+    /* Track */
+    if ( FileTag1->track && !FileTag2->track && g_utf8_strlen(FileTag1->track, -1)>0 ) return TRUE;
+    if (!FileTag1->track &&  FileTag2->track && g_utf8_strlen(FileTag2->track, -1)>0 ) return TRUE;
+    if ( FileTag1->track &&  FileTag2->track && g_utf8_collate(FileTag1->track,FileTag2->track)!=0 ) return 
TRUE;
+
+    /* Track Total */
+    if ( FileTag1->track_total && !FileTag2->track_total && g_utf8_strlen(FileTag1->track_total, -1)>0 ) 
return TRUE;
+    if (!FileTag1->track_total &&  FileTag2->track_total && g_utf8_strlen(FileTag2->track_total, -1)>0 ) 
return TRUE;
+    if ( FileTag1->track_total &&  FileTag2->track_total && 
g_utf8_collate(FileTag1->track_total,FileTag2->track_total)!=0 ) return TRUE;
+
+    /* Genre */
+    if ( FileTag1->genre && !FileTag2->genre && g_utf8_strlen(FileTag1->genre, -1)>0 ) return TRUE;
+    if (!FileTag1->genre &&  FileTag2->genre && g_utf8_strlen(FileTag2->genre, -1)>0 ) return TRUE;
+    if ( FileTag1->genre &&  FileTag2->genre && g_utf8_collate(FileTag1->genre,FileTag2->genre)!=0 ) return 
TRUE;
+
+    /* Comment */
+    if ( FileTag1->comment && !FileTag2->comment && g_utf8_strlen(FileTag1->comment, -1)>0 ) return TRUE;
+    if (!FileTag1->comment &&  FileTag2->comment && g_utf8_strlen(FileTag2->comment, -1)>0 ) return TRUE;
+    if ( FileTag1->comment &&  FileTag2->comment && g_utf8_collate(FileTag1->comment,FileTag2->comment)!=0 ) 
return TRUE;
+
+    /* Composer */
+    if ( FileTag1->composer && !FileTag2->composer && g_utf8_strlen(FileTag1->composer, -1)>0 ) return TRUE;
+    if (!FileTag1->composer &&  FileTag2->composer && g_utf8_strlen(FileTag2->composer, -1)>0 ) return TRUE;
+    if ( FileTag1->composer &&  FileTag2->composer && 
g_utf8_collate(FileTag1->composer,FileTag2->composer)!=0 ) return TRUE;
+
+    /* Original artist */
+    if ( FileTag1->orig_artist && !FileTag2->orig_artist && g_utf8_strlen(FileTag1->orig_artist, -1)>0 ) 
return TRUE;
+    if (!FileTag1->orig_artist &&  FileTag2->orig_artist && g_utf8_strlen(FileTag2->orig_artist, -1)>0 ) 
return TRUE;
+    if ( FileTag1->orig_artist &&  FileTag2->orig_artist && 
g_utf8_collate(FileTag1->orig_artist,FileTag2->orig_artist)!=0 ) return TRUE;
+
+    /* Copyright */
+    if ( FileTag1->copyright && !FileTag2->copyright && g_utf8_strlen(FileTag1->copyright, -1)>0 ) return 
TRUE;
+    if (!FileTag1->copyright &&  FileTag2->copyright && g_utf8_strlen(FileTag2->copyright, -1)>0 ) return 
TRUE;
+    if ( FileTag1->copyright &&  FileTag2->copyright && 
g_utf8_collate(FileTag1->copyright,FileTag2->copyright)!=0 ) return TRUE;
+
+    /* URL */
+    if ( FileTag1->url && !FileTag2->url && g_utf8_strlen(FileTag1->url, -1)>0 ) return TRUE;
+    if (!FileTag1->url &&  FileTag2->url && g_utf8_strlen(FileTag2->url, -1)>0 ) return TRUE;
+    if ( FileTag1->url &&  FileTag2->url && g_utf8_collate(FileTag1->url,FileTag2->url)!=0 ) return TRUE;
+
+    /* Encoded by */
+    if ( FileTag1->encoded_by && !FileTag2->encoded_by && g_utf8_strlen(FileTag1->encoded_by, -1)>0 ) return 
TRUE;
+    if (!FileTag1->encoded_by &&  FileTag2->encoded_by && g_utf8_strlen(FileTag2->encoded_by, -1)>0 ) return 
TRUE;
+    if ( FileTag1->encoded_by &&  FileTag2->encoded_by && 
g_utf8_collate(FileTag1->encoded_by,FileTag2->encoded_by)!=0 ) return TRUE;
+
+    /* Picture */
+    for (pic1 = FileTag1->picture, pic2 = FileTag2->picture; ;
+         pic1 = pic1->next, pic2 = pic2->next)
+    {
+        if( (pic1 && !pic2) || (!pic1 && pic2) )
+            return TRUE;
+        if (!pic1 || !pic2)
+            break; // => no changes
+        //if (!pic1->data || !pic2->data)
+        //    break; // => no changes
+
+        if (!g_bytes_equal (pic1->bytes, pic2->bytes))
+        {
+            return TRUE;
+        }
+        if (pic1->type != pic2->type)
+            return TRUE;
+        if (pic1->description && !pic2->description
+        &&  g_utf8_strlen(pic1->description, -1)>0 )
+            return TRUE;
+        if (!pic1->description && pic2->description
+        &&  g_utf8_strlen(pic2->description, -1)>0 )
+            return TRUE;
+        if (pic1->description && pic2->description
+        &&  g_utf8_collate(pic1->description, pic2->description)!=0 )
+            return TRUE;
+    }
+
+    return FALSE; /* No changes */
+}
diff --git a/src/file_tag.h b/src/file_tag.h
new file mode 100644
index 0000000..9793535
--- /dev/null
+++ b/src/file_tag.h
@@ -0,0 +1,103 @@
+/* EasyTAG - tag editor for audio files
+ * Copyright (C) 2014  David King <amigadave amigadave com>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef ET_FILE_TAG_H_
+#define ET_FILE_TAG_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "picture.h"
+
+/*
+ * File_Tag:
+ * @key: incremented value
+ * @saved: %TRUE if the tag has been saved, %FALSE otherwise
+ * @title: track name
+ * @artist: track artist
+ * @album_artist: artist for the album of which this track is part
+ * @album: album name
+ * @disc_number: disc number within a set (as a string)
+ * @disc_total: total number of discs in the set (as a string)
+ * @year: year (as a string)
+ * @track: track number (as a string)
+ * @track_total: total number of tracks (as a string)
+ * @genre: text genre
+ * @comment: comment
+ * @composer: composer
+ * @orig_artist: original artist
+ * @copyright: copyright
+ * @url: URL
+ * @encoded_by: encoded by (strictly, a person, but often the encoding
+ *              application)
+ * @picture: #EtPicture, which may have several other linked instances
+ * @other: a list of other tags, used for Vorbis comments
+ * Description of each item of the TagList list
+ */
+typedef struct
+{
+    guint key;
+    gboolean saved;
+
+    gchar *title;
+    gchar *artist;
+    gchar *album_artist;
+    gchar *album;
+    gchar *disc_number;
+    gchar *disc_total;
+    gchar *year;
+    gchar *track;
+    gchar *track_total;
+    gchar *genre;
+    gchar *comment;
+    gchar *composer;
+    gchar *orig_artist;
+    gchar *copyright;
+    gchar *url;
+    gchar *encoded_by;
+    EtPicture *picture;
+    GList *other;
+} File_Tag;
+
+File_Tag * ET_File_Tag_Item_New (void);
+gboolean ET_Free_File_Tag_Item (File_Tag *FileTag);
+
+void et_file_tag_set_title (File_Tag *file_tag, const gchar *title);
+void et_file_tag_set_artist (File_Tag *file_tag, const gchar *artist);
+void et_file_tag_set_album_artist (File_Tag *file_tag, const gchar *album_artist);
+void et_file_tag_set_album (File_Tag *file_tag, const gchar *album);
+void et_file_tag_set_disc_number (File_Tag *file_tag, const gchar *disc_number);
+void et_file_tag_set_disc_total (File_Tag *file_tag, const gchar *disc_total);
+void et_file_tag_set_year (File_Tag *file_tag, const gchar *year);
+void et_file_tag_set_track_number (File_Tag *file_tag, const gchar *track_number);
+void et_file_tag_set_track_total (File_Tag *file_tag, const gchar *track_total);
+void et_file_tag_set_genre (File_Tag *file_tag, const gchar *genre);
+void et_file_tag_set_comment (File_Tag *file_tag, const gchar *comment);
+void et_file_tag_set_composer (File_Tag *file_tag, const gchar *composer);
+void et_file_tag_set_orig_artist (File_Tag *file_tag, const gchar *orig_artist);
+void et_file_tag_set_copyright (File_Tag *file_tag, const gchar *copyright);
+void et_file_tag_set_url (File_Tag *file_tag, const gchar *url);
+void et_file_tag_set_encoded_by (File_Tag *file_tag, const gchar *encoded_by);
+void et_file_tag_set_picture (File_Tag *file_tag, const EtPicture *pic);
+
+gboolean ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1, const File_Tag  *FileTag2);
+
+G_END_DECLS
+
+#endif /* !ET_FILE_TAG_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]