[easytag/wip/et_core-refactor: 8/9] Split majority of et_core.c out into new file.c



commit 103c20223cdbf9e6870d371fd3a7a82a317dca96
Author: David King <amigadave amigadave com>
Date:   Sun Dec 28 22:32:37 2014 +0000

    Split majority of et_core.c out into new file.c

 Makefile.am    |    2 +
 po/POTFILES.in |    1 +
 src/et_core.c  | 3912 +-------------------------------------------------------
 src/et_core.h  |  175 +---
 src/file.c     | 3893 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/file.h     |  181 +++
 6 files changed, 4089 insertions(+), 4075 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 7caf5b5..5d0f723 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ easytag_SOURCES = \
        src/easytag.c \
        src/enums.c \
        src/et_core.c \
+       src/file.c \
        src/file_area.c \
        src/file_description.c \
        src/file_tag.c \
@@ -106,6 +107,7 @@ easytag_headers = \
        src/dlm.h \
        src/easytag.h \
        src/et_core.h \
+       src/file.h \
        src/file_area.h \
        src/file_description.h \
        src/file_tag.h \
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 195bbf3..3088fca 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ src/charset.c
 src/easytag.c
 src/et_core.c
 src/file_area.c
+src/file.c
 src/load_files_dialog.c
 src/log.c
 src/misc.c
diff --git a/src/et_core.c b/src/et_core.c
index 8bef0e9..ab4a285 100644
--- a/src/et_core.c
+++ b/src/et_core.c
@@ -17,61 +17,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#include "config.h"
-
 #include "et_core.h"
 
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <utime.h>
-
 #include "application_window.h"
-#include "easytag.h"
-#include "file_tag.h"
-#include "mpeg_header.h"
-#include "monkeyaudio_header.h"
-#include "musepack_header.h"
-#ifdef ENABLE_MP3
-#   include "id3_tag.h"
-#endif
-#include "picture.h"
-#include "ape_tag.h"
-#ifdef ENABLE_OGG
-#   include "ogg_header.h"
-#   include "ogg_tag.h"
-#endif
-#ifdef ENABLE_FLAC
-#   include "flac_header.h"
-#   include "flac_tag.h"
-#endif
-#ifdef ENABLE_MP4
-#   include "mp4_header.h"
-#   include "mp4_tag.h"
-#endif
-#ifdef ENABLE_WAVPACK
-#   include "wavpack_header.h"
-#   include "wavpack_tag.h"
-#endif
-#ifdef ENABLE_OPUS
-#include "opus_tag.h"
-#include "opus_header.h"
-#endif
-#include "browser.h"
-#include "log.h"
-#include "misc.h"
-#include "setting.h"
-#include "charset.h"
-
-#include "win32/win32dep.h"
-
-
-/***************
- * Declaration *
- ***************/
+#include "file.h"
 
 ET_Core *ETCore = NULL;
 
@@ -80,72 +29,8 @@ ET_Core *ETCore = NULL;
  */
 GdkRGBA RED = {1.0, 0.0, 0.0, 1.0 };
 
-
-/**************
- * Prototypes *
- **************/
-
-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_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_Name_Item (File_Name *FileName);
-
-static guint ET_File_Key_New (void);
-
-static gboolean ET_Remove_File_From_Artist_Album_List (ET_File *ETFile);
-
-static void ET_Display_Filename_To_UI (const ET_File *ETFile);
-static EtFileHeaderFields * ET_Display_File_Info_To_UI (const ET_File *ETFile);
-
-static gboolean ET_Save_File_Name_From_UI (const ET_File *ETFile,
-                                           File_Name *FileName);
-static gboolean ET_Save_File_Name_Internal (const ET_File *ETFile, File_Name *FileName);
-static gboolean ET_Save_File_Tag_Internal (ET_File *ETFile, File_Tag *FileTag);
-
-static void ET_Mark_File_Tag_As_Saved (ET_File *ETFile);
-
-static gboolean ET_Detect_Changes_Of_File_Name (const File_Name *FileName1,
-                                                const File_Name *FileName2);
-static gboolean ET_Add_File_Name_To_List (ET_File *ETFile,
-                                          File_Name *FileName);
-static gboolean ET_Add_File_Tag_To_List (ET_File *ETFile, File_Tag  *FileTag);
-static gboolean ET_Add_File_To_History_List (ET_File *ETFile);
-static gboolean ET_Add_File_To_Artist_Album_File_List (ET_File *ETFile);
-
-static guint ET_Displayed_File_List_Get_Length      (void);
-static void ET_Displayed_File_List_Number (void);
-
-static gboolean et_core_read_file_info (GFile *file,
-                                        ET_File_Info *ETFileInfo,
-                                        GError **error);
-
-static gint ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist (const GList *AlbumList1,
-                                                               const GList *AlbumList2);
-static gint ET_Comp_Func_Sort_Album_Item_By_Ascending_Album (const GList *etfilelist1,
-                                                             const GList *etfilelist2);
-static gint ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename (const ET_File *ETFile1,
-                                                                 const ET_File *ETFile2);
-static gchar *ET_File_Name_Format_Extension (const ET_File *ETFile);
-
-static void set_sort_order_for_column_id (gint column_id,
-                                          GtkTreeViewColumn *column,
-                                          EtSortMode sort_type);
-
-
-/*******************
- * Basic functions *
- *******************/
-
-/*****************************************************************************
- * Manipulation of ET_Core functions (main functions needed for the program) *
- *****************************************************************************/
-void ET_Core_Create (void)
+void
+ET_Core_Create (void)
 {
     /* Allocate. */
     if (ETCore == NULL)
@@ -157,7 +42,8 @@ void ET_Core_Create (void)
     ET_Core_Initialize ();
 }
 
-void ET_Core_Initialize (void)
+void
+ET_Core_Initialize (void)
 {
     ETCore->ETFileList                        = NULL;
     ETCore->ETFileDisplayedList               = NULL;
@@ -170,7 +56,8 @@ void ET_Core_Initialize (void)
     ETCore->ETArtistAlbumFileList             = NULL;
 }
 
-void ET_Core_Free (void)
+void
+ET_Core_Free (void)
 {
     // Frees first lists, then initialize
     if (ETCore->ETFileList)
@@ -199,3788 +86,3 @@ ET_Core_Destroy (void)
         ETCore = NULL;
     }
 }
-
-
-
-/**************************
- * Initializing functions *
- **************************/
-
-/*
- * Create a new File_Name structure
- */
-File_Name *ET_File_Name_Item_New (void)
-{
-    File_Name *FileName;
-
-    FileName = g_slice_new (File_Name);
-    ET_Initialize_File_Name_Item (FileName);
-
-    return FileName;
-}
-
-/*
- * Create a new File_Info structure
- */
-static ET_File_Info *
-ET_File_Info_Item_New (void)
-{
-    ET_File_Info *ETFileInfo;
-
-    ETFileInfo = g_slice_new0 (ET_File_Info);
-
-    return ETFileInfo;
-}
-
-
-/*
- * Create a new ET_File structure
- */
-ET_File *ET_File_Item_New (void)
-{
-    ET_File *ETFile;
-
-    ETFile = g_slice_new0 (ET_File);
-
-    return ETFile;
-}
-
-
-static void
-ET_Initialize_File_Name_Item (File_Name *FileName)
-{
-    if (FileName)
-    {
-        FileName->key        = ET_Undo_Key_New();
-        FileName->saved      = FALSE;
-        FileName->value      = NULL;
-        FileName->value_utf8 = NULL;
-        FileName->value_ck   = NULL;
-    }
-}
-
-
-/* Key for each item of ETFileList */
-static guint
-ET_File_Key_New (void)
-{
-    static guint ETFileKey = 0;
-    return ++ETFileKey;
-}
-
-/* Key for Undo */
-guint
-ET_Undo_Key_New (void)
-{
-    static guint ETUndoKey = 0;
-    return ++ETUndoKey;
-}
-
-
-
-
-/**********************************
- * File adding/removing functions *
- **********************************/
-
-/*
- * ET_Add_File_To_File_List: Add a file to the "main" list. And get all information of the file.
- * The filename passed in should be in raw format, only convert it to UTF8 when displaying it.
- */
-GList *ET_Add_File_To_File_List (gchar *filename)
-{
-    const ET_File_Description *ETFileDescription;
-    ET_File      *ETFile;
-    File_Name    *FileName;
-    File_Tag     *FileTag;
-    ET_File_Info *ETFileInfo;
-    gchar        *ETFileExtension;
-    guint         ETFileKey;
-    guint         undo_key;
-    GFile *file;
-    GFileInfo *fileinfo;
-    gchar        *filename_utf8 = filename_to_display(filename);
-    const gchar  *locale_lc_ctype = getenv("LC_CTYPE");
-    GError *error = NULL;
-    gboolean success;
-
-    if (!filename)
-        return ETCore->ETFileList;
-
-    file = g_file_new_for_path (filename);
-
-    /* Primary Key for this file */
-    ETFileKey = ET_File_Key_New();
-
-    /* Get description of the file */
-    ETFileDescription = ET_Get_File_Description(filename);
-
-    /* Get real extension of the file (keeping the case) */
-    ETFileExtension = g_strdup(ET_Get_File_Extension(filename));
-
-    /* Fill the File_Name structure for FileNameList */
-    FileName = ET_File_Name_Item_New();
-    FileName->saved      = TRUE;    /* The file hasn't been changed, so it's saved */
-    FileName->value      = filename;
-    FileName->value_utf8 = filename_utf8;
-    FileName->value_ck   = g_utf8_collate_key_for_filename(filename_utf8, -1);
-
-    /* Fill the File_Tag structure for FileTagList */
-    FileTag = ET_File_Tag_Item_New();
-    FileTag->saved = TRUE;    /* The file hasn't been changed, so it's saved */
-
-    /* Patch from Doruk Fisek and Onur Kucuk: avoid upper/lower conversion bugs
-     * (like I->i conversion in some locales) in tag parsing. The problem occurs
-     * for example with Turkish language where it can't read 'TITLE=' field if
-     * it is written as 'Title=' in the file */
-    setlocale(LC_CTYPE, "C");
-
-    switch (ETFileDescription->TagType)
-    {
-#ifdef ENABLE_MP3
-        case ID3_TAG:
-            if (!id3tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           "Error reading ID3 tag from file ‘%s’: %s",
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#endif
-#ifdef ENABLE_OGG
-        case OGG_TAG:
-            if (!ogg_tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading tag from Ogg file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#endif
-#ifdef ENABLE_FLAC
-        case FLAC_TAG:
-            if (!flac_tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading tag from FLAC file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#endif
-        case APE_TAG:
-            if (!ape_tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading APE tag from file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#ifdef ENABLE_MP4
-        case MP4_TAG:
-            if (!mp4tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading tag from MP4 file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#endif
-#ifdef ENABLE_WAVPACK
-        case WAVPACK_TAG:
-            if (!wavpack_tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading tag from WavPack file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-        break;
-#endif
-#ifdef ENABLE_OPUS
-        case OPUS_TAG:
-            if (!et_opus_tag_read_file_tag (file, FileTag, &error))
-            {
-                Log_Print (LOG_ERROR,
-                           _("Error reading tag from Opus file ‘%s’: %s"),
-                           filename_utf8, error->message);
-                g_clear_error (&error);
-            }
-            break;
-#endif
-        case UNKNOWN_TAG:
-        default:
-            /* FIXME: Translatable string. */
-            Log_Print(LOG_ERROR,"FileTag: Undefined tag type (%d) for file 
%s",ETFileDescription->TagType,filename_utf8);
-            break;
-    }
-
-    if (FileTag->year && g_utf8_strlen (FileTag->year, -1) > 4)
-    {
-        Log_Print (LOG_WARNING,
-                   _("The year value ‘%s’ seems to be invalid in file ‘%s’. The information will be lost 
when saving"),
-                   FileTag->year, filename_utf8);
-    }
-
-    /* Fill the ET_File_Info structure */
-    ETFileInfo = ET_File_Info_Item_New ();
-
-    switch (ETFileDescription->FileType)
-    {
-#if defined ENABLE_MP3 && defined ENABLE_ID3LIB
-        case MP3_FILE:
-        case MP2_FILE:
-            success = et_mpeg_header_read_file_info (file, ETFileInfo, &error);
-            break;
-#endif
-#ifdef ENABLE_OGG
-        case OGG_FILE:
-            success = et_ogg_header_read_file_info (file, ETFileInfo, &error);
-            break;
-#endif
-#ifdef ENABLE_SPEEX
-        case SPEEX_FILE:
-            success = et_speex_header_read_file_info (file, ETFileInfo,
-                                                      &error);
-            break;
-#endif
-#ifdef ENABLE_FLAC
-        case FLAC_FILE:
-            success = et_flac_header_read_file_info (file, ETFileInfo, &error);
-            break;
-#endif
-        case MPC_FILE:
-            success = et_mpc_header_read_file_info (file, ETFileInfo, &error);
-            break;
-        case MAC_FILE:
-            success = et_mac_header_read_file_info (file, ETFileInfo, &error);
-            break;
-#ifdef ENABLE_WAVPACK
-        case WAVPACK_FILE:
-            success = et_wavpack_header_read_file_info (file, ETFileInfo,
-                                                        &error);
-            break;
-#endif
-#ifdef ENABLE_MP4
-        case MP4_FILE:
-            success = et_mp4_header_read_file_info (file, ETFileInfo, &error);
-            break;
-#endif
-#ifdef ENABLE_OPUS
-        case OPUS_FILE:
-            success = et_opus_read_file_info (file, ETFileInfo, &error);
-            break;
-#endif
-        case UNKNOWN_FILE:
-        default:
-            /* FIXME: Translatable string. */
-            Log_Print(LOG_ERROR,"ETFileInfo: Undefined file type (%d) for file 
%s",ETFileDescription->FileType,filename_utf8);
-            /* To get at least the file size. */
-            success = et_core_read_file_info (file, ETFileInfo, &error);
-            break;
-    }
-
-    if (!success)
-    {
-        Log_Print (LOG_ERROR,
-                   _("Error while querying information for file ‘%s’: %s"),
-                   filename_utf8, error->message);
-        g_error_free (error);
-    }
-
-    /* Restore previous value */
-    setlocale(LC_CTYPE, locale_lc_ctype ? locale_lc_ctype : "");
-
-    /* Store the modification time of the file to check if the file was changed
-     * before saving */
-    fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED,
-                                  G_FILE_QUERY_INFO_NONE, NULL, NULL);
-    g_object_unref (file);
-
-    /* Attach all data defined above to this ETFile item */
-    ETFile = ET_File_Item_New();
-
-    if (fileinfo)
-    {
-        ETFile->FileModificationTime = g_file_info_get_attribute_uint64 (fileinfo,
-                                                                         G_FILE_ATTRIBUTE_TIME_MODIFIED);
-        g_object_unref (fileinfo);
-    }
-    else
-    {
-        ETFile->FileModificationTime = 0;
-    }
-
-    ETFile->IndexKey             = 0; // Will be renumered after...
-    ETFile->ETFileKey            = ETFileKey;
-    ETFile->ETFileDescription    = ETFileDescription;
-    ETFile->ETFileExtension      = ETFileExtension;
-    ETFile->FileNameList         = g_list_append(NULL,FileName);
-    ETFile->FileNameCur          = ETFile->FileNameList;
-    ETFile->FileNameNew          = ETFile->FileNameList;
-    ETFile->FileTagList          = g_list_append(NULL,FileTag);
-    ETFile->FileTag              = ETFile->FileTagList;
-    ETFile->ETFileInfo           = ETFileInfo;
-
-    /* Add the item to the "main list" */
-    ETCore->ETFileList = g_list_append(ETCore->ETFileList,ETFile);
-
-
-    /*
-     * Process the filename and tag to generate undo if needed...
-     * The undo key must be the same for FileName and FileTag => changed in the same time
-     */
-    undo_key = ET_Undo_Key_New();
-
-    FileName = ET_File_Name_Item_New();
-    FileName->key = undo_key;
-    ET_Save_File_Name_Internal(ETFile,FileName);
-
-    FileTag = ET_File_Tag_Item_New();
-    FileTag->key = undo_key;
-    ET_Save_File_Tag_Internal(ETFile,FileTag);
-
-    /*
-     * Generate undo for the file and the main undo list.
-     * If no changes detected, FileName and FileTag item are deleted.
-     */
-    ET_Manage_Changes_Of_File_Data(ETFile,FileName,FileTag);
-
-    /*
-     * Display a message if the file was changed at start
-     */
-    FileTag  = (File_Tag *)ETFile->FileTag->data;
-    FileName = (File_Name *)ETFile->FileNameNew->data;
-    if ( (FileName && FileName->saved==FALSE) || (FileTag && FileTag->saved==FALSE) )
-    {
-        Log_Print (LOG_INFO, _("Automatic corrections applied for file ‘%s’"),
-                   filename_utf8);
-    }
-
-    /* Add the item to the ArtistAlbum list (placed here to take advantage of previous changes) */
-    //ET_Add_File_To_Artist_Album_File_List(ETFile);
-
-    //ET_Debug_Print_File_List(ETCore->ETFileList,__FILE__,__LINE__,__FUNCTION__);
-    return ETCore->ETFileList;
-}
-
-gboolean ET_Create_Artist_Album_File_List (void)
-{
-    GList *l;
-
-    if (ETCore->ETArtistAlbumFileList)
-        ET_Free_Artist_Album_File_List();
-
-    for (l = g_list_first (ETCore->ETFileList); l != NULL; l = g_list_next (l))
-    {
-        ET_File *ETFile = (ET_File *)l->data;
-        ET_Add_File_To_Artist_Album_File_List(ETFile);
-    }
-    //ET_Debug_Print_Artist_Album_List(__FILE__,__LINE__,__FUNCTION__);
-    return TRUE;
-}
-/*
- * The ETArtistAlbumFileList contains 3 levels of lists to sort the ETFile by artist then by album :
- *  - "ETArtistAlbumFileList" list is a list of "ArtistList" items,
- *  - "ArtistList" list is a list of "AlbumList" items,
- *  - "AlbumList" list is a list of ETFile items.
- * Note : use the function ET_Debug_Print_Artist_Album_List(...) to understand how it works, it needed...
- */
-static gboolean
-ET_Add_File_To_Artist_Album_File_List (ET_File *ETFile)
-{
-    const gchar *ETFile_Artist;
-    const gchar *ETFile_Album;
-    const gchar *etfile_artist;
-    const gchar *etfile_album;
-    GList *ArtistList;
-    GList *AlbumList = NULL;
-    GList *etfilelist = NULL;
-    ET_File *etfile = NULL;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    /* Album value of the ETFile passed in parameter. */
-    ETFile_Album = ((File_Tag *)ETFile->FileTag->data)->album;
-    /* Artist value of the ETFile passed in parameter. */
-    ETFile_Artist = ((File_Tag *)ETFile->FileTag->data)->artist;
-
-    for (ArtistList = ETCore->ETArtistAlbumFileList; ArtistList != NULL;
-         ArtistList = g_list_next (ArtistList))
-    {
-        AlbumList = (GList *)ArtistList->data;  /* Take the first item */
-        /* Take the first item, and the first etfile item. */
-        if (AlbumList && (etfilelist = (GList *)AlbumList->data)
-            && (etfile = (ET_File *)etfilelist->data)
-            && ((File_Tag *)etfile->FileTag->data) != NULL)
-        {
-            etfile_artist = ((File_Tag *)etfile->FileTag->data)->artist;
-        }
-        else
-        {
-            etfile_artist = NULL;
-        }
-
-        if ((etfile_artist &&  ETFile_Artist && strcmp (etfile_artist,
-                                                        ETFile_Artist) == 0)
-            || (!etfile_artist && !ETFile_Artist)) /* The "artist" values correspond? */
-        {
-            /* The "ArtistList" item was found! */
-            while (AlbumList)
-            {
-                if ((etfilelist = (GList *)AlbumList->data)
-                    && (etfile = (ET_File *)etfilelist->data)
-                    && ((File_Tag *)etfile->FileTag->data) != NULL)
-                {
-                    etfile_album = ((File_Tag *)etfile->FileTag->data)->album;
-                }
-                else
-                {
-                    etfile_album = NULL;
-                }
-
-                if ((etfile_album && ETFile_Album && strcmp (etfile_album,
-                                                             ETFile_Album) == 0)
-                    || (!etfile_album && !ETFile_Album))
-                    /* The "album" values correspond? */
-                {
-                    /* The "AlbumList" item was found!
-                     * Add the ETFile to this AlbumList item */
-                    AlbumList->data = g_list_append ((GList *)AlbumList->data,
-                                                     ETFile);
-                    AlbumList->data = g_list_sort ((GList *)AlbumList->data,
-                                                   
(GCompareFunc)ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename);
-                    return TRUE;
-                }
-
-                AlbumList = g_list_next (AlbumList);
-            }
-
-            /* The "AlbumList" item was NOT found! => Add a new "AlbumList"
-             * item (+...) item to the "ArtistList" list. */
-            etfilelist = g_list_append (NULL, ETFile);
-            ArtistList->data = g_list_append ((GList *)ArtistList->data,
-                                              etfilelist);
-            ArtistList->data = g_list_sort ((GList *)ArtistList->data,
-                                            (GCompareFunc)ET_Comp_Func_Sort_Album_Item_By_Ascending_Album);
-            return TRUE;
-        }
-    }
-
-    /* The "ArtistList" item was NOT found! => Add a new "ArtistList" to the
-     * main list (=ETArtistAlbumFileList). */
-    etfilelist = g_list_append (NULL, ETFile);
-    AlbumList  = g_list_append (NULL, etfilelist);
-    ETCore->ETArtistAlbumFileList = g_list_append (ETCore->ETArtistAlbumFileList,
-                                                   AlbumList);
-
-    /* Sort the list by ascending Artist. */
-    ETCore->ETArtistAlbumFileList = g_list_sort (ETCore->ETArtistAlbumFileList,
-                                                 
(GCompareFunc)ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist);
-
-    return TRUE;
-}
-
-
-
-/*
- * Delete the corresponding file and free the allocated data. Return TRUE if deleted.
- */
-gboolean ET_Remove_File_From_File_List (ET_File *ETFile)
-{
-    GList *ETFileList = NULL;          // Item containing the ETFile to delete... (in ETCore->ETFileList)
-    GList *ETFileDisplayedList = NULL; // Item containing the ETFile to delete... (in 
ETCore->ETFileDisplayedList)
-
-    // Remove infos of the file
-    ETCore->ETFileDisplayedList_TotalSize     -= ((ET_File_Info *)ETFile->ETFileInfo)->size;
-    ETCore->ETFileDisplayedList_TotalDuration -= ((ET_File_Info *)ETFile->ETFileInfo)->duration;
-
-    // Find the ETFileList containing the ETFile item
-    ETFileDisplayedList = g_list_find(g_list_first(ETCore->ETFileDisplayedList),ETFile);
-    ETFileList          = g_list_find(g_list_first(ETCore->ETFileList),ETFile);
-
-    // Note : this ETFileList must be used only for ETCore->ETFileDisplayedList, and not 
ETCore->ETFileDisplayed
-    if (ETCore->ETFileDisplayedList == ETFileDisplayedList)
-    {
-        if (ETFileList->next)
-            ETCore->ETFileDisplayedList = ETFileDisplayedList->next;
-        else if (ETFileList->prev)
-            ETCore->ETFileDisplayedList = ETFileDisplayedList->prev;
-        else
-            ETCore->ETFileDisplayedList = NULL;
-    }
-    // If the current displayed file is just removing, it will be unable to display it again!
-    if (ETCore->ETFileDisplayed == ETFile)
-    {
-        if (ETCore->ETFileDisplayedList)
-            ETCore->ETFileDisplayed = (ET_File *)ETCore->ETFileDisplayedList->data;
-        else
-            ETCore->ETFileDisplayed = (ET_File *)NULL;
-    }
-
-    /* Remove the file from the ETFileList list. */
-    ETCore->ETFileList = g_list_remove (g_list_first (ETCore->ETFileList),
-                                        ETFileList);
-
-    // Remove the file from the ETArtistAlbumList list
-    ET_Remove_File_From_Artist_Album_List(ETFile);
-
-    /* Remove the file from the ETFileDisplayedList list (if not already). */
-    ETCore->ETFileDisplayedList = g_list_remove (g_list_first (ETCore->ETFileDisplayedList),
-                                                 ETFileDisplayedList);
-
-    // Free data of the file
-    ET_Free_File_List_Item(ETFile);
-    if (ETFileList)
-        g_list_free(ETFileList);
-    if (ETFileDisplayedList)
-        g_list_free(ETFileDisplayedList);
-
-    // Recalculate length of ETFileDisplayedList list
-    ET_Displayed_File_List_Get_Length();
-
-    // To number the ETFile in the list
-    ET_Displayed_File_List_Number();
-
-    // Displaying...
-    if (ETCore->ETFileDisplayedList)
-    {
-        if (ETCore->ETFileDisplayed)
-        {
-            ET_Displayed_File_List_By_Etfile(ETCore->ETFileDisplayed);
-        }else if (ETCore->ETFileDisplayedList->data)
-        {
-            // Select the new file (synchronize index,...)
-            ET_Displayed_File_List_By_Etfile((ET_File *)ETCore->ETFileDisplayedList->data);
-        }
-    }else
-    {
-        // Reinit the tag and file area
-        et_application_window_file_area_clear (ET_APPLICATION_WINDOW (MainWindow));
-        et_application_window_tag_area_clear (ET_APPLICATION_WINDOW (MainWindow));
-        et_application_window_update_actions (ET_APPLICATION_WINDOW (MainWindow));
-    }
-
-    return TRUE;
-}
-
-
-/*
- * Delete the corresponding file (allocated data was previously freed!). Return TRUE if deleted.
- */
-static gboolean
-ET_Remove_File_From_Artist_Album_List (ET_File *ETFile)
-{
-    GList *ArtistList;
-    GList *AlbumList;
-    GList *etfilelist;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    /* Search for the ETFile in the list. */
-    for (ArtistList = ETCore->ETArtistAlbumFileList; ArtistList != NULL;
-         ArtistList = g_list_next (ArtistList))
-    {
-        for (AlbumList = g_list_first ((GList *)ArtistList->data);
-             AlbumList != NULL; AlbumList = g_list_next (AlbumList))
-        {
-            for (etfilelist = g_list_first ((GList *)AlbumList->data);
-                 etfilelist != NULL; etfilelist = g_list_next (etfilelist))
-            {
-                ET_File *etfile = (ET_File *)etfilelist->data;
-
-                if (ETFile == etfile) /* The ETFile to delete was found! */
-                {
-                    etfilelist = g_list_remove (etfilelist, ETFile);
-
-                    if (etfilelist) /* Delete from AlbumList. */
-                    {
-                        AlbumList->data = (gpointer) g_list_first (etfilelist);
-                    }
-                    else
-                    {
-                        AlbumList = g_list_remove (AlbumList, AlbumList->data);
-
-                        if (AlbumList) /* Delete from ArtistList. */
-                        {
-                            ArtistList->data = AlbumList;
-                        }
-                        else
-                        {
-                            /* Delete from the main list. */
-                            ETCore->ETArtistAlbumFileList = g_list_remove (ArtistList,ArtistList->data);
-
-                            return TRUE;
-                        }
-
-                        return TRUE;
-                    }
-
-                    return TRUE;
-                }
-            }
-        }
-    }
-
-    return FALSE; /* ETFile is NUL, or not found in the list. */
-}
-
-/**************************
- * File sorting functions *
- **************************/
-
-/*
- * Sort the 'ETFileDisplayedList' following the 'Sorting_Type'
- * Note : Add also new sorting in 'Browser_List_Sort_Func'
- */
-static void
-ET_Sort_Displayed_File_List (EtSortMode Sorting_Type)
-{
-    ETCore->ETFileDisplayedList = ET_Sort_File_List(ETCore->ETFileDisplayedList,Sorting_Type);
-}
-
-/*
- * Sort an 'ETFileList'
- */
-GList *
-ET_Sort_File_List (GList *ETFileList, EtSortMode Sorting_Type)
-{
-    EtApplicationWindow *window;
-    GtkTreeViewColumn *column;
-    GList *etfilelist;
-    gint column_id = Sorting_Type / 2;
-
-    window = ET_APPLICATION_WINDOW (MainWindow);
-    column = et_application_window_browser_get_column_for_column_id (window,
-                                                                     column_id);
-
-    /* Important to rewind before. */
-    etfilelist = g_list_first (ETFileList);
-
-    /* FIXME: Port to sort-mode? */
-    set_sort_order_for_column_id (column_id, column, Sorting_Type);
-
-    /* Sort... */
-    switch (Sorting_Type)
-    {
-        case ET_SORT_MODE_ASCENDING_FILENAME:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Filename);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILENAME:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Filename);
-            break;
-        case ET_SORT_MODE_ASCENDING_TITLE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Title);
-            break;
-        case ET_SORT_MODE_DESCENDING_TITLE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Title);
-            break;
-        case ET_SORT_MODE_ASCENDING_ARTIST:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Artist);
-            break;
-        case ET_SORT_MODE_DESCENDING_ARTIST:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Artist);
-            break;
-        case ET_SORT_MODE_ASCENDING_ALBUM_ARTIST:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Album_Artist);
-            break;
-        case ET_SORT_MODE_DESCENDING_ALBUM_ARTIST:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Album_Artist);
-            break;
-               case ET_SORT_MODE_ASCENDING_ALBUM:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Album);
-            break;
-        case ET_SORT_MODE_DESCENDING_ALBUM:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Album);
-            break;
-        case ET_SORT_MODE_ASCENDING_YEAR:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Year);
-            break;
-        case ET_SORT_MODE_DESCENDING_YEAR:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Year);
-            break;
-        case ET_SORT_MODE_ASCENDING_DISC_NUMBER:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)et_comp_func_sort_file_by_ascending_disc_number);
-            break;
-        case ET_SORT_MODE_DESCENDING_DISC_NUMBER:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)et_comp_func_sort_file_by_descending_disc_number);
-            break;
-        case ET_SORT_MODE_ASCENDING_TRACK_NUMBER:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Track_Number);
-            break;
-        case ET_SORT_MODE_DESCENDING_TRACK_NUMBER:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Track_Number);
-            break;
-        case ET_SORT_MODE_ASCENDING_GENRE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Genre);
-            break;
-        case ET_SORT_MODE_DESCENDING_GENRE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Genre);
-            break;
-        case ET_SORT_MODE_ASCENDING_COMMENT:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Comment);
-            break;
-        case ET_SORT_MODE_DESCENDING_COMMENT:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Comment);
-            break;
-        case ET_SORT_MODE_ASCENDING_COMPOSER:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Composer);
-            break;
-        case ET_SORT_MODE_DESCENDING_COMPOSER:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Composer);
-            break;
-        case ET_SORT_MODE_ASCENDING_ORIG_ARTIST:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist);
-            break;
-        case ET_SORT_MODE_DESCENDING_ORIG_ARTIST:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Orig_Artist);
-            break;
-        case ET_SORT_MODE_ASCENDING_COPYRIGHT:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Copyright);
-            break;
-        case ET_SORT_MODE_DESCENDING_COPYRIGHT:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Copyright);
-            break;
-        case ET_SORT_MODE_ASCENDING_URL:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Url);
-            break;
-        case ET_SORT_MODE_DESCENDING_URL:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Url);
-            break;
-        case ET_SORT_MODE_ASCENDING_ENCODED_BY:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Encoded_By);
-            break;
-        case ET_SORT_MODE_DESCENDING_ENCODED_BY:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Encoded_By);
-            break;
-        case ET_SORT_MODE_ASCENDING_CREATION_DATE:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Creation_Date);
-            break;
-        case ET_SORT_MODE_DESCENDING_CREATION_DATE:
-            etfilelist = g_list_sort (etfilelist,
-                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Creation_Date);
-            break;
-        case ET_SORT_MODE_ASCENDING_FILE_TYPE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Type);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILE_TYPE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Type);
-            break;
-        case ET_SORT_MODE_ASCENDING_FILE_SIZE:
-            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Size);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILE_SIZE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Size);
-            break;
-        case ET_SORT_MODE_ASCENDING_FILE_DURATION:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Duration);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILE_DURATION:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Duration);
-            break;
-        case ET_SORT_MODE_ASCENDING_FILE_BITRATE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILE_BITRATE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Bitrate);
-            break;
-        case ET_SORT_MODE_ASCENDING_FILE_SAMPLERATE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate);
-            break;
-        case ET_SORT_MODE_DESCENDING_FILE_SAMPLERATE:
-            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Samplerate);
-            break;
-    }
-    /* Save sorting mode (note: needed when called from UI). */
-    g_settings_set_enum (MainSettings, "sort-mode", Sorting_Type);
-
-    //ETFileList = g_list_first(etfilelist);
-    return etfilelist;
-}
-
-
-/*
- * Sort the list of files following the 'Sorting_Type' value. The new sorting is displayed in the UI.
- */
-void
-ET_Sort_Displayed_File_List_And_Update_UI (EtSortMode Sorting_Type)
-{
-    g_return_if_fail (ETCore->ETFileList != NULL);
-
-    ET_Save_File_Data_From_UI(ETCore->ETFileDisplayed);
-
-    /* Sort the list */
-    ET_Sort_Displayed_File_List(Sorting_Type);
-
-    /* To number the ETFile in the list */
-    ET_Displayed_File_List_Number();
-
-    /* Reload files in browser list */
-    ET_Displayed_File_List_By_Etfile(ETCore->ETFileDisplayed);  // Just to update 'ETFileDisplayedList'
-    et_application_window_browser_select_file_by_et_file (ET_APPLICATION_WINDOW (MainWindow),
-                                                          ETCore->ETFileDisplayed,
-                                                          TRUE);
-    ET_Display_File_Data_To_UI(ETCore->ETFileDisplayed);
-
-    et_application_window_browser_refresh_sort (ET_APPLICATION_WINDOW (MainWindow));
-    et_application_window_update_actions (ET_APPLICATION_WINDOW (MainWindow));
-}
-
-
-/*
- * Comparison function for sorting by ascending filename.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Filename (const ET_File *ETFile1,
-                                              const ET_File *ETFile2)
-{
-    const gchar *file1_ck = ((File_Name *)((GList *)ETFile1->FileNameCur)->data)->value_ck;
-    const gchar *file2_ck = ((File_Name *)((GList *)ETFile2->FileNameCur)->data)->value_ck;
-    // !!!! : Must be the same rules as "Cddb_Track_List_Sort_Func" to be
-    // able to sort in the same order files in cddb and in the file list.
-    return g_settings_get_boolean (MainSettings,
-                                   "sort-case-sensitive") ? strcmp (file1_ck, file2_ck)
-                                                          : strcasecmp (file1_ck, file2_ck);
-}
-
-/*
- * Comparison function for sorting by descending filename.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Filename (const ET_File *ETFile1,
-                                               const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending disc number.
- */
-gint
-et_comp_func_sort_file_by_ascending_disc_number (const ET_File *ETFile1,
-                                                 const ET_File *ETFile2)
-{
-    gint track1, track2;
-
-    if (!ETFile1->FileTag->data
-        || !((File_Tag *)ETFile1->FileTag->data)->disc_number)
-    {
-        track1 = 0;
-    }
-    else
-    {
-        track1 = atoi (((File_Tag *)ETFile1->FileTag->data)->disc_number);
-    }
-
-    if (!ETFile2->FileTag->data
-        || !((File_Tag *)ETFile2->FileTag->data)->disc_number)
-    {
-        track2 = 0;
-    }
-    else
-    {
-        track2 = atoi (((File_Tag *)ETFile2->FileTag->data)->disc_number);
-    }
-
-    /* Second criterion. */
-    if (track1 == track2)
-    {
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename (ETFile1, ETFile2);
-    }
-
-    /* First criterion. */
-    return (track1 - track2);
-}
-
-/*
- * Comparison function for sorting by descending disc number.
- */
-gint
-et_comp_func_sort_file_by_descending_disc_number (const ET_File *ETFile1,
-                                                  const ET_File *ETFile2)
-{
-    return et_comp_func_sort_file_by_ascending_disc_number (ETFile2, ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending track number.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Track_Number (const ET_File *ETFile1,
-                                                  const ET_File *ETFile2)
-{
-    gint track1, track2;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->track )
-        track1 = 0;
-    else
-        track1 = atoi( ((File_Tag *)ETFile1->FileTag->data)->track );
-
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->track )
-        track2 = 0;
-    else
-        track2 = atoi( ((File_Tag *)ETFile2->FileTag->data)->track );
-
-    // Second criterion
-    if (track1 == track2)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (track1 - track2);
-}
-
-/*
- * Comparison function for sorting by descending track number.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Track_Number (const ET_File *ETFile1,
-                                                   const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Track_Number(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending creation date.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Creation_Date (const ET_File *ETFile1,
-                                                   const ET_File *ETFile2)
-{
-    GFile *file;
-    GFileInfo *info;
-    guint64 time1 = 0;
-    guint64 time2 = 0;
-
-    /* TODO: Report errors? */
-    file = g_file_new_for_path (((File_Name *)ETFile1->FileNameCur->data)->value);
-    info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_CHANGED,
-                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
-
-    g_object_unref (file);
-
-    if (info)
-    {
-        time1 = g_file_info_get_attribute_uint64 (info,
-                                                  G_FILE_ATTRIBUTE_TIME_CHANGED);
-        g_object_unref (info);
-    }
-
-    file = g_file_new_for_path (((File_Name *)ETFile2->FileNameCur->data)->value);
-    info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_CHANGED,
-                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
-
-    g_object_unref (file);
-
-    if (info)
-    {
-        time2 = g_file_info_get_attribute_uint64 (info,
-                                                  G_FILE_ATTRIBUTE_TIME_CHANGED);
-        g_object_unref (info);
-    }
-
-    /* Second criterion. */
-    if (time1 == time2)
-    {
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename (ETFile1, ETFile2);
-    }
-
-    /* First criterion. */
-    return (gint64)(time1 - time2);
-}
-
-/*
- * Comparison function for sorting by descending creation date.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Creation_Date (const ET_File *ETFile1,
-                                                    const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Creation_Date(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending title.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Title (const ET_File *ETFile1,
-                                           const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->title == ((File_Tag *)ETFile2->FileTag->data)->title))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->title )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->title )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag *)ETFile2->FileTag->data)->title) 
== 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-      else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title);
-    }
-}
-
-/*
- * Comparison function for sorting by descending title.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Title (const ET_File *ETFile1,
-                                            const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Title(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Artist (const ET_File *ETFile1,
-                                            const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->artist == ((File_Tag *)ETFile2->FileTag->data)->artist))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->artist )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->artist )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist);
-    }
-}
-
-/*
- * Comparison function for sorting by descending artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Artist (const ET_File *ETFile1,
-                                             const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile2,ETFile1);
-}
-
-/*
- * Comparison function for sorting by ascending album artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Album_Artist (const ET_File *ETFile1,
-                                                  const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->album_artist == ((File_Tag 
*)ETFile2->FileTag->data)->album_artist))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->album_artist )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->album_artist )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist);
-    }
-}
-
-/*
- * Comparison function for sorting by descending album artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Album_Artist (const ET_File *ETFile1,
-                                                   const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Album_Artist(ETFile2,ETFile1);
-}
-
-/*
- * Comparison function for sorting by ascending album.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Album (const ET_File *ETFile1,
-                                           const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->album == ((File_Tag *)ETFile2->FileTag->data)->album))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->album )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->album )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag *)ETFile2->FileTag->data)->album) 
== 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album);
-    }
-}
-
-/*
- * Comparison function for sorting by descending album.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Album (const ET_File *ETFile1,
-                                            const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Album(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending year.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Year (const ET_File *ETFile1,
-                                          const ET_File *ETFile2)
-{
-    gint year1, year2;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->year )
-        year1 = 0;
-    else
-        year1 = atoi( ((File_Tag *)ETFile1->FileTag->data)->year );
-
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->year )
-        year2 = 0;
-    else
-        year2 = atoi( ((File_Tag *)ETFile2->FileTag->data)->year );
-
-    // Second criterion
-    if (year1 == year2)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (year1 - year2);
-}
-
-/*
- * Comparison function for sorting by descending year.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Year (const ET_File *ETFile1,
-                                           const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Year(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending genre.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Genre (const ET_File *ETFile1,
-                                           const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->genre == ((File_Tag *)ETFile2->FileTag->data)->genre))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->genre ) return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->genre ) return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag *)ETFile2->FileTag->data)->genre) 
== 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre);
-    }
-}
-
-/*
- * Comparison function for sorting by descending genre.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Genre (const ET_File *ETFile1,
-                                            const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Genre(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending comment.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Comment (const ET_File *ETFile1,
-                                             const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->comment == ((File_Tag *)ETFile2->FileTag->data)->comment))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->comment )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->comment )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment);
-    }
-}
-
-/*
- * Comparison function for sorting by descending comment.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Comment (const ET_File *ETFile1,
-                                              const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Comment(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending composer.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Composer (const ET_File *ETFile1,
-                                              const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->composer == ((File_Tag *)ETFile2->FileTag->data)->composer))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->composer )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->composer )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer);
-    }
-}
-
-/*
- * Comparison function for sorting by descending composer.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Composer (const ET_File *ETFile1,
-                                               const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Composer(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending original artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist (const ET_File *ETFile1,
-                                                 const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->orig_artist == ((File_Tag 
*)ETFile2->FileTag->data)->orig_artist))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->orig_artist )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->orig_artist )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist);
-    }
-}
-
-/*
- * Comparison function for sorting by descending original artist.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Orig_Artist (const ET_File *ETFile1,
-                                                  const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending copyright.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Copyright (const ET_File *ETFile1,
-                                               const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->copyright == ((File_Tag *)ETFile2->FileTag->data)->copyright))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->copyright )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->copyright )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright);
-    }
-}
-
-/*
- * Comparison function for sorting by descending copyright.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Copyright (const ET_File *ETFile1,
-                                                const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Copyright(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending URL.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Url (const ET_File *ETFile1,
-                                         const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->url == ((File_Tag *)ETFile2->FileTag->data)->url))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->url )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->url )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag *)ETFile2->FileTag->data)->url) == 
0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag 
*)ETFile2->FileTag->data)->url);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag *)ETFile2->FileTag->data)->url) 
== 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag 
*)ETFile2->FileTag->data)->url);
-    }
-}
-
-/*
- * Comparison function for sorting by descending URL.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Url (const ET_File *ETFile1,
-                                          const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Url(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending encoded by.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_Encoded_By (const ET_File *ETFile1,
-                                                const ET_File *ETFile2)
-{
-   // Compare pointers just in case they are the same (e.g. both are NULL)
-   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
-   ||  (((File_Tag *)ETFile1->FileTag->data)->encoded_by == ((File_Tag 
*)ETFile2->FileTag->data)->encoded_by))
-        return 0;
-
-    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->encoded_by )
-        return -1;
-    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->encoded_by )
-        return 1;
-
-    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-    {
-        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by);
-    }else
-    {
-        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by) == 0 )
-            // Second criterion
-            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-        else
-            // First criterion
-            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by);
-    }
-}
-
-/*
- * Comparison function for sorting by descendingencoded by.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_Encoded_By (const ET_File *ETFile1,
-                                                 const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_Encoded_By(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending file type (mp3, ogg, ...).
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_File_Type (const ET_File *ETFile1,
-                                               const ET_File *ETFile2)
-{
-    if ( !ETFile1->ETFileDescription ) return -1;
-    if ( !ETFile2->ETFileDescription ) return 1;
-
-    // Second criterion
-    if (ETFile1->ETFileDescription->FileType == ETFile2->ETFileDescription->FileType)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (ETFile1->ETFileDescription->FileType - ETFile2->ETFileDescription->FileType);
-}
-
-/*
- * Comparison function for sorting by descending file type (mp3, ogg, ...).
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_File_Type (const ET_File *ETFile1,
-                                                const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_File_Type(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending file size.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_File_Size (const ET_File *ETFile1,
-                                               const ET_File *ETFile2)
-{
-    if ( !ETFile1->ETFileInfo ) return -1;
-    if ( !ETFile2->ETFileInfo ) return 1;
-
-    // Second criterion
-    if (ETFile1->ETFileInfo->size == ETFile2->ETFileInfo->size)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (ETFile1->ETFileInfo->size - ETFile2->ETFileInfo->size);
-}
-
-/*
- * Comparison function for sorting by descending file size.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_File_Size (const ET_File *ETFile1,
-                                                const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_File_Size(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending file duration.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_File_Duration (const ET_File *ETFile1,
-                                                   const ET_File *ETFile2)
-{
-    if ( !ETFile1->ETFileInfo ) return -1;
-    if ( !ETFile2->ETFileInfo ) return 1;
-
-    // Second criterion
-    if (ETFile1->ETFileInfo->duration == ETFile2->ETFileInfo->duration)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (ETFile1->ETFileInfo->duration - ETFile2->ETFileInfo->duration);
-}
-
-/*
- * Comparison function for sorting by descending file duration.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_File_Duration (const ET_File *ETFile1,
-                                                    const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_File_Duration(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending file bitrate.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate (const ET_File *ETFile1,
-                                                  const ET_File *ETFile2)
-{
-    if ( !ETFile1->ETFileInfo ) return -1;
-    if ( !ETFile2->ETFileInfo ) return 1;
-
-    // Second criterion
-    if (ETFile1->ETFileInfo->bitrate == ETFile2->ETFileInfo->bitrate)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (ETFile1->ETFileInfo->bitrate - ETFile2->ETFileInfo->bitrate);
-}
-
-/*
- * Comparison function for sorting by descending file bitrate.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_File_Bitrate (const ET_File *ETFile1,
-                                                   const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending file samplerate.
- */
-gint
-ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate (const ET_File *ETFile1,
-                                                     const ET_File *ETFile2)
-{
-    if ( !ETFile1->ETFileInfo ) return -1;
-    if ( !ETFile2->ETFileInfo ) return 1;
-
-    // Second criterion
-    if (ETFile1->ETFileInfo->samplerate == ETFile2->ETFileInfo->samplerate)
-        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-
-    // First criterion
-    return (ETFile1->ETFileInfo->samplerate - ETFile2->ETFileInfo->samplerate);
-}
-
-/*
- * Comparison function for sorting by descending file samplerate.
- */
-gint
-ET_Comp_Func_Sort_File_By_Descending_File_Samplerate (const ET_File *ETFile1,
-                                                      const ET_File *ETFile2)
-{
-    return ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate(ETFile2,ETFile1);
-}
-
-
-/*
- * Comparison function for sorting by ascending artist in the ArtistAlbumList.
- */
-static gint
-ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist (const GList *AlbumList1,
-                                                   const GList *AlbumList2)
-{
-    const GList *etfilelist1 = NULL;
-    const GList *etfilelist2 = NULL;
-    const ET_File *etfile1 = NULL;
-    const ET_File *etfile2 = NULL;
-    const gchar *etfile1_artist;
-    const gchar *etfile2_artist;
-
-    if (!AlbumList1
-    || !(etfilelist1    = (GList *)AlbumList1->data)
-    || !(etfile1        = (ET_File *)etfilelist1->data)
-    || !(etfile1_artist = ((File_Tag *)etfile1->FileTag->data)->artist) )
-        return -1;
-
-    if (!AlbumList2
-    || !(etfilelist2    = (GList *)AlbumList2->data)
-    || !(etfile2        = (ET_File *)etfilelist2->data)
-    || !(etfile2_artist = ((File_Tag *)etfile2->FileTag->data)->artist) )
-        return 1;
-
-    /*if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-     *    return strcmp(etfile1_artist,etfile2_artist); */
-    //else
-        return strcasecmp(etfile1_artist,etfile2_artist);
-}
-
-/*
- * Comparison function for sorting by ascending album in the ArtistAlbumList.
- */
-static gint
-ET_Comp_Func_Sort_Album_Item_By_Ascending_Album (const GList *etfilelist1,
-                                                 const GList *etfilelist2)
-{
-    const ET_File *etfile1;
-    const ET_File *etfile2;
-    const gchar *etfile1_album;
-    const gchar *etfile2_album;
-
-    if (!etfilelist1
-    || !(etfile1        = (ET_File *)etfilelist1->data)
-    || !(etfile1_album  = ((File_Tag *)etfile1->FileTag->data)->album) )
-        return -1;
-
-    if (!etfilelist2
-    || !(etfile2        = (ET_File *)etfilelist2->data)
-    || !(etfile2_album  = ((File_Tag *)etfile2->FileTag->data)->album) )
-        return 1;
-
-    /*if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
-     *    return strcmp(etfile1_album,etfile2_album); */
-    //else
-        return strcasecmp(etfile1_album,etfile2_album);
-}
-
-/*
- * Comparison function for sorting etfile in the ArtistAlbumList.
- * FIX ME : should use the default sorting!
- */
-static gint
-ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename (const ET_File *ETFile1,
-                                                     const ET_File *ETFile2)
-{
-
-    if (!ETFile1) return -1;
-    if (!ETFile2) return  1;
-
-    return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
-}
-
-
-
-
-/***************************
- * List handling functions *
- ***************************/
-
-/*
- * Returns the first item of the "displayed list"
- */
-GList *ET_Displayed_File_List_First (void)
-{
-    ETCore->ETFileDisplayedList = g_list_first(ETCore->ETFileDisplayedList);
-    return ETCore->ETFileDisplayedList;
-}
-
-/*
- * Returns the previous item of the "displayed list". When no more item, it returns NULL.
- */
-GList *ET_Displayed_File_List_Previous (void)
-{
-    if (ETCore->ETFileDisplayedList && ETCore->ETFileDisplayedList->prev)
-        return ETCore->ETFileDisplayedList = ETCore->ETFileDisplayedList->prev;
-    else
-        return NULL;
-}
-
-/*
- * Returns the next item of the "displayed list".
- * When no more item, it returns NULL to don't "overwrite" the list.
- */
-GList *ET_Displayed_File_List_Next (void)
-{
-    if (ETCore->ETFileDisplayedList && ETCore->ETFileDisplayedList->next)
-        return ETCore->ETFileDisplayedList = ETCore->ETFileDisplayedList->next;
-    else
-        return NULL;
-}
-
-/*
- * Returns the last item of the "displayed list"
- */
-GList *ET_Displayed_File_List_Last (void)
-{
-    ETCore->ETFileDisplayedList = g_list_last(ETCore->ETFileDisplayedList);
-    return ETCore->ETFileDisplayedList;
-}
-
-/*
- * Returns the item of the "displayed list" which correspond to the given 'ETFile' (used into browser list).
- */
-GList *
-ET_Displayed_File_List_By_Etfile (const ET_File *ETFile)
-{
-    GList *etfilelist;
-
-    for (etfilelist = ET_Displayed_File_List_First (); etfilelist != NULL;
-         etfilelist = ET_Displayed_File_List_Next ())
-    {
-        if (ETFile == (ET_File *)etfilelist->data)
-            break;
-    }
-
-    if (etfilelist)
-    {
-        /* To "save" the position like in ET_File_List_Next... (not very good -
-         * FIXME) */
-        ETCore->ETFileDisplayedList = etfilelist;
-    }
-    return etfilelist;
-}
-
-/*
- * Just returns the current item of the "main list"
- */
-/*GList *ET_Displayed_File_List_Current (void)
-{
-    return ETCore->ETFileDisplayedList;
-    //return ETCore->ETFileDisplayedListPtr;
-}*/
-
-/*
- * Renumber the list of displayed files (IndexKey) from 1 to n
- */
-static void
-ET_Displayed_File_List_Number (void)
-{
-    GList *l = NULL;
-    guint i = 1;
-
-    for (l = g_list_first (ETCore->ETFileDisplayedList); l != NULL;
-         l = g_list_next (l))
-    {
-        ((ET_File *)l->data)->IndexKey = i++;
-    }
-}
-
-/*
- * Returns the length of the list of displayed files
- */
-static guint
-ET_Displayed_File_List_Get_Length (void)
-{
-    GList *list = NULL;
-
-    list = g_list_first(ETCore->ETFileDisplayedList);
-    ETCore->ETFileDisplayedList_Length = g_list_length(list);
-    return ETCore->ETFileDisplayedList_Length;
-}
-
-/*
- * Load the list of displayed files (calculate length, size, ...)
- * It contains part (filtrated : view by artists and albums) or full ETCore->ETFileList list
- */
-gboolean ET_Set_Displayed_File_List (GList *ETFileList)
-{
-    GList *l = NULL;
-
-    ETCore->ETFileDisplayedList = g_list_first(ETFileList);
-
-    //ETCore->ETFileDisplayedListPtr = ETCore->ETFileDisplayedList;
-    ETCore->ETFileDisplayedList_Length = ET_Displayed_File_List_Get_Length();
-    ETCore->ETFileDisplayedList_TotalSize     = 0;
-    ETCore->ETFileDisplayedList_TotalDuration = 0;
-
-    // Get size and duration of files in the list
-    for (l = ETCore->ETFileDisplayedList; l != NULL; l = g_list_next (l))
-    {
-        ETCore->ETFileDisplayedList_TotalSize += ((ET_File_Info *)((ET_File *)l->data)->ETFileInfo)->size;
-        ETCore->ETFileDisplayedList_TotalDuration += ((ET_File_Info *)((ET_File 
*)l->data)->ETFileInfo)->duration;
-    }
-
-    /* Sort the file list. */
-    ET_Sort_Displayed_File_List (g_settings_get_enum (MainSettings,
-                                 "sort-mode"));
-
-    // Should renums ETCore->ETFileDisplayedList only!
-    ET_Displayed_File_List_Number();
-
-    return TRUE;
-}
-
-
-
-/*********************
- * Freeing functions *
- *********************/
-
-/*
- * Frees the full main list of files: GList *ETFileList and reinitialize it.
- */
-gboolean ET_Free_File_List (void)
-{
-    g_return_val_if_fail (ETCore != NULL && ETCore->ETFileList != NULL, FALSE);
-
-    g_list_free_full (ETCore->ETFileList,
-                      (GDestroyNotify)ET_Free_File_List_Item);
-    ETCore->ETFileList = NULL;
-
-    return TRUE;
-}
-
-
-/*
- * Frees one item of the full main list of files.
- */
-void
-ET_Free_File_List_Item (ET_File *ETFile)
-{
-    if (ETFile)
-    {
-        /* Frees the lists */
-        if (ETFile->FileNameList)
-        {
-            ET_Free_File_Name_List(ETFile->FileNameList);
-        }
-        if (ETFile->FileNameListBak)
-        {
-            ET_Free_File_Name_List(ETFile->FileNameListBak);
-        }
-        if (ETFile->FileTagList)
-        {
-            ET_Free_File_Tag_List (ETFile->FileTagList);
-        }
-        if (ETFile->FileTagListBak)
-        {
-            ET_Free_File_Tag_List (ETFile->FileTagListBak);
-        }
-        /* Frees infos of ETFileInfo */
-        if (ETFile->ETFileInfo)
-        {
-            ET_Free_File_Info_Item (ETFile->ETFileInfo);
-        }
-
-        g_free(ETFile->ETFileExtension);
-        g_slice_free (ET_File, ETFile);
-    }
-}
-
-
-/*
- * Frees the full list: GList *FileNameList.
- */
-gboolean ET_Free_File_Name_List (GList *FileNameList)
-{
-    g_return_val_if_fail (FileNameList != NULL, FALSE);
-
-    FileNameList = g_list_first (FileNameList);
-
-    g_list_free_full (FileNameList, (GDestroyNotify)ET_Free_File_Name_Item);
-
-    return TRUE;
-}
-
-
-/*
- * Frees a File_Name item.
- */
-static void
-ET_Free_File_Name_Item (File_Name *FileName)
-{
-    g_return_if_fail (FileName != NULL);
-
-    g_free(FileName->value);
-    g_free(FileName->value_utf8);
-    g_free(FileName->value_ck);
-    g_slice_free (File_Name, FileName);
-}
-
-
-/*
- * Frees the full list: GList *TagList.
- */
-static gboolean
-ET_Free_File_Tag_List (GList *FileTagList)
-{
-    GList *l;
-
-    g_return_val_if_fail (FileTagList != NULL, FALSE);
-
-    FileTagList = g_list_first (FileTagList);
-
-    for (l = FileTagList; l != NULL; l = g_list_next (l))
-    {
-        if ((File_Tag *)l->data)
-            ET_Free_File_Tag_Item ((File_Tag *)l->data);
-    }
-
-    g_list_free (FileTagList);
-
-    return TRUE;
-}
-
-
-/*
- * Frees a File_Info item.
- */
-static gboolean
-ET_Free_File_Info_Item (ET_File_Info *ETFileInfo)
-{
-    g_return_val_if_fail (ETFileInfo != NULL, FALSE);
-
-    g_free(ETFileInfo->mpc_profile);
-    g_free(ETFileInfo->mpc_version);
-
-    g_slice_free (ET_File_Info, ETFileInfo);
-    return TRUE;
-}
-
-
-static void
-et_history_file_free (ET_History_File *file)
-{
-    g_slice_free (ET_History_File, file);
-}
-
-/*
- * History list contains only pointers, so no data to free except the history structure.
- */
-static gboolean
-ET_Free_History_File_List (void)
-{
-    g_return_val_if_fail (ETCore != NULL && ETCore->ETHistoryFileList != NULL,
-                          FALSE);
-
-    ETCore->ETHistoryFileList = g_list_first (ETCore->ETHistoryFileList);
-
-    g_list_free_full (ETCore->ETHistoryFileList,
-                      (GDestroyNotify)et_history_file_free);
-
-    ETCore->ETHistoryFileList = NULL;
-
-    return TRUE;
-}
-
-/*
- * "Display" list contains only pointers, so NOTHING to free
- */
-static gboolean
-ET_Free_Displayed_File_List (void)
-{
-    g_return_val_if_fail (ETCore != NULL
-                          && ETCore->ETFileDisplayedList != NULL, FALSE);
-
-    ETCore->ETFileDisplayedList = NULL;
-
-    return TRUE;
-}
-
-
-/*
- * ArtistAlbum list contains 3 levels of lists
- */
-static gboolean
-ET_Free_Artist_Album_File_List (void)
-{
-    GList *l;
-
-    g_return_val_if_fail (ETCore != NULL
-                          && ETCore->ETArtistAlbumFileList != NULL, FALSE);
-
-    /* Pointers are stored inside the artist/album list-stores, so free them
-     * first. */
-    et_application_window_browser_clear_artist_model (ET_APPLICATION_WINDOW (MainWindow));
-    et_application_window_browser_clear_album_model (ET_APPLICATION_WINDOW (MainWindow));
-
-    for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l))
-    {
-        GList *m;
-
-        for (m = (GList *)l->data; m != NULL; m = g_list_next (m))
-        {
-            GList *n = (GList *)m->data;
-            if (n)
-                g_list_free (n);
-        }
-
-        if (l->data) /* Free AlbumList list. */
-            g_list_free ((GList *)l->data);
-    }
-
-    if (ETCore->ETArtistAlbumFileList)
-        g_list_free(ETCore->ETArtistAlbumFileList);
-
-    ETCore->ETArtistAlbumFileList = NULL;
-
-    return TRUE;
-}
-
-
-
-
-/*********************
- * Copying functions *
- *********************/
-
-/*
- * 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"
- */
-gboolean
-ET_Set_Filename_File_Name_Item (File_Name *FileName,
-                                const gchar *filename_utf8,
-                                const gchar *filename)
-{
-    g_return_val_if_fail (FileName != NULL, FALSE);
-
-    if (filename_utf8 && filename)
-    {
-        FileName->value_utf8 = g_strdup(filename_utf8);
-        FileName->value      = g_strdup(filename);
-        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-    }else if (filename_utf8)
-    {
-        FileName->value_utf8 = g_strdup(filename_utf8);
-        FileName->value      = filename_from_display(filename_utf8);
-        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-    }else if (filename)
-    {
-        FileName->value_utf8 = filename_to_display(filename);;
-        FileName->value      = g_strdup(filename);
-        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-    }else
-    {
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/************************
- * Displaying functions *
- ************************/
-
-static void
-et_file_header_fields_free (EtFileHeaderFields *fields)
-{
-    g_free (fields->version);
-    g_free (fields->bitrate);
-    g_free (fields->samplerate);
-    g_free (fields->mode);
-    g_free (fields->size);
-    g_free (fields->duration);
-    g_slice_free (EtFileHeaderFields, fields);
-}
-
-/*
- * Display information of the file (Position + Header + Tag) to the user interface.
- * Before doing it, it saves data of the file currently displayed
- */
-void
-ET_Display_File_Data_To_UI (ET_File *ETFile)
-{
-    EtApplicationWindow *window;
-    const ET_File_Description *ETFileDescription;
-    const gchar *cur_filename_utf8;
-    gchar *msg;
-    EtFileHeaderFields *fields;
-
-    g_return_if_fail (ETFile != NULL &&
-                      ((GList *)ETFile->FileNameCur)->data != NULL);
-                      /* For the case where ETFile is an "empty" structure. */
-
-    cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
-    ETFileDescription = ETFile->ETFileDescription;
-
-    /* Save the current displayed file */
-    ETCore->ETFileDisplayed = ETFile;
-
-    window = ET_APPLICATION_WINDOW (MainWindow);
-
-    /* Display position in list + show/hide icon if file writable/read_only (cur_filename) */
-    et_application_window_file_area_set_file_fields (window, ETFile);
-
-    /* Display filename (and his path) (value in FileNameNew) */
-    ET_Display_Filename_To_UI(ETFile);
-
-    /* Display tag data */
-    et_application_window_tag_area_display_et_file (window, ETFile);
-
-    /* Display controls in tag area */
-    et_application_window_tag_area_display_controls (window, ETFile);
-
-    /* Display file data, header data and file type */
-    switch (ETFileDescription->FileType)
-    {
-#if defined ENABLE_MP3 && defined ENABLE_ID3LIB
-        case MP3_FILE:
-        case MP2_FILE:
-            fields = et_mpeg_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_mpeg_file_header_fields_free (fields);
-            break;
-#endif
-#ifdef ENABLE_OGG
-        case OGG_FILE:
-            fields = et_ogg_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_ogg_file_header_fields_free (fields);
-            break;
-#endif
-#ifdef ENABLE_SPEEX
-        case SPEEX_FILE:
-            fields = et_ogg_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_ogg_file_header_fields_free (fields);
-            break;
-#endif
-#ifdef ENABLE_FLAC
-        case FLAC_FILE:
-            fields = et_flac_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_flac_file_header_fields_free (fields);
-            break;
-#endif
-        case MPC_FILE:
-            fields = et_mpc_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_mpc_file_header_fields_free (fields);
-            break;
-        case MAC_FILE:
-            fields = et_mac_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_mac_file_header_fields_free (fields);
-            break;
-#ifdef ENABLE_MP4
-        case MP4_FILE:
-            fields = et_mp4_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_mp4_file_header_fields_free (fields);
-            break;
-#endif
-#ifdef ENABLE_WAVPACK
-        case WAVPACK_FILE:
-            fields = et_wavpack_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_wavpack_file_header_fields_free (fields);
-            break;
-#endif
-#ifdef ENABLE_OPUS
-        case OPUS_FILE:
-            fields = et_opus_header_display_file_info_to_ui (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_opus_file_header_fields_free (fields);
-            break;
-#endif
-        case UNKNOWN_FILE:
-        default:
-            /* Default displaying. */
-            fields = ET_Display_File_Info_To_UI (ETFile);
-            et_application_window_file_area_set_header_fields (window, fields);
-            et_file_header_fields_free (fields);
-            Log_Print (LOG_ERROR,
-                       "ETFileInfo: Undefined file type %d for file %s.",
-                       ETFileDescription->FileType, cur_filename_utf8);
-            break;
-    }
-
-    msg = g_strdup_printf (_("File: ‘%s’"), cur_filename_utf8);
-    et_application_window_status_bar_message (window, msg, FALSE);
-    g_free (msg);
-}
-
-static void
-ET_Display_Filename_To_UI (const ET_File *ETFile)
-{
-    const gchar *new_filename_utf8;
-    gchar *dirname_utf8;
-    gchar *text;
-
-    g_return_if_fail (ETFile != NULL);
-
-    new_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameNew)->data)->value_utf8;
-
-    /*
-     * Set the path to the file into BrowserEntry (dirbrowser)
-     */
-    dirname_utf8 = g_path_get_dirname(new_filename_utf8);
-    et_application_window_browser_entry_set_text (ET_APPLICATION_WINDOW (MainWindow),
-                                                  dirname_utf8);
-
-    // And refresh the number of files in this directory
-    text = g_strdup_printf(ngettext("One file","%u 
files",ET_Get_Number_Of_Files_In_Directory(dirname_utf8)),ET_Get_Number_Of_Files_In_Directory(dirname_utf8));
-    et_application_window_browser_label_set_text (ET_APPLICATION_WINDOW (MainWindow),
-                                                  text);
-    g_free(dirname_utf8);
-    g_free(text);
-}
-
-
-/*
- * "Default" way to display File Info to the user interface.
- */
-static EtFileHeaderFields *
-ET_Display_File_Info_To_UI (const ET_File *ETFile)
-{
-    EtFileHeaderFields *fields;
-    ET_File_Info *info;
-    gchar *time  = NULL;
-    gchar *time1 = NULL;
-    gchar *size  = NULL;
-    gchar *size1 = NULL;
-
-    info = ETFile->ETFileInfo;
-    fields = g_slice_new (EtFileHeaderFields);
-
-    fields->description = _("File");
-
-    /* MPEG, Layer versions */
-    fields->version = g_strdup_printf ("%d, Layer %d", info->version,
-                                       info->layer);
-
-    /* Bitrate */
-    fields->bitrate = g_strdup_printf (_("%d kb/s"), info->bitrate);
-
-    /* Samplerate */
-    fields->samplerate = g_strdup_printf (_("%d Hz"), info->samplerate);
-
-    /* Mode */
-    fields->mode = g_strdup_printf ("%d", info->mode);
-
-    /* Size */
-    size = g_format_size (info->size);
-    size1 = g_format_size (ETCore->ETFileDisplayedList_TotalSize);
-    fields->size = g_strdup_printf ("%s (%s)", size, size1);
-    g_free (size);
-    g_free (size1);
-
-    /* Duration */
-    time = Convert_Duration (info->duration);
-    time1 = Convert_Duration (ETCore->ETFileDisplayedList_TotalDuration);
-    fields->duration = g_strdup_printf ("%s (%s)", time, time1);
-    g_free (time);
-    g_free (time1);
-
-    return fields;
-}
-
-/********************
- * Saving functions *
- ********************/
-
-/*
- * Save information of the file, contained into the entries of the user interface, in the list.
- * An undo key is generated to be used for filename and tag if there are changed is the same time.
- * Filename and Tag.
- */
-void ET_Save_File_Data_From_UI (ET_File *ETFile)
-{
-    const ET_File_Description *ETFileDescription;
-    File_Name *FileName;
-    File_Tag  *FileTag;
-    guint      undo_key;
-    const gchar *cur_filename_utf8;
-
-    g_return_if_fail (ETFile != NULL && ETFile->FileNameCur != NULL
-                      && ETFile->FileNameCur->data != NULL);
-
-    cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
-    ETFileDescription = ETFile->ETFileDescription;
-    undo_key = ET_Undo_Key_New();
-
-
-    /*
-     * Save filename and generate undo for filename
-     */
-    FileName = g_slice_new (File_Name);
-    ET_Initialize_File_Name_Item (FileName);
-    FileName->key = undo_key;
-    ET_Save_File_Name_From_UI(ETFile,FileName); // Used for all files!
-
-    switch (ETFileDescription->TagType)
-    {
-#ifdef ENABLE_MP3
-        case ID3_TAG:
-#endif
-#ifdef ENABLE_OGG
-        case OGG_TAG:
-#endif
-#ifdef ENABLE_FLAC
-        case FLAC_TAG:
-#endif
-#ifdef ENABLE_MP4
-        case MP4_TAG:
-#endif
-#ifdef ENABLE_WAVPACK
-        case WAVPACK_TAG:
-#endif
-#ifdef ENABLE_OPUS
-        case OPUS_TAG:
-#endif
-        case APE_TAG:
-            FileTag = et_application_window_tag_area_create_file_tag (ET_APPLICATION_WINDOW (MainWindow));
-            ET_Copy_File_Tag_Item_Other_Field (ETFile, FileTag);
-            break;
-        case UNKNOWN_TAG:
-        default:
-            FileTag = ET_File_Tag_Item_New ();
-            Log_Print(LOG_ERROR,"FileTag: Undefined tag type %d for file 
%s.",ETFileDescription->TagType,cur_filename_utf8);
-            break;
-    }
-
-    /*
-     * Generate undo for the file and the main undo list.
-     * If no changes detected, FileName and FileTag item are deleted.
-     */
-    ET_Manage_Changes_Of_File_Data(ETFile,FileName,FileTag);
-
-    /* Refresh file into browser list */
-    et_application_window_browser_refresh_file_in_list (ET_APPLICATION_WINDOW (MainWindow),
-                                                        ETFile);
-}
-
-
-/*
- * Save displayed filename into list if it had been changed. Generates also an history list for undo/redo.
- *  - ETFile : the current etfile that we want to save,
- *  - FileName : where is 'temporary' saved the new filename.
- *
- * Note : it builds new filename (with path) from strings encoded into file system
- *        encoding, not UTF-8 (it preserves file system encoding of parent directories).
- */
-static gboolean
-ET_Save_File_Name_From_UI (const ET_File *ETFile, File_Name *FileName)
-{
-    gchar *filename_new = NULL;
-    gchar *dirname = NULL;
-    gchar *filename;
-    const gchar *filename_utf8;
-    gchar *extension;
-
-    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
-
-    filename_utf8 = et_application_window_file_area_get_filename (ET_APPLICATION_WINDOW (MainWindow));
-    filename = filename_from_display (filename_utf8);
-
-    if (!filename)
-    {
-        // If translation fails...
-        GtkWidget *msgdialog;
-        gchar *filename_escaped_utf8 = g_strescape(filename_utf8, NULL);
-        msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
-                                           GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-                                           GTK_MESSAGE_ERROR,
-                                           GTK_BUTTONS_CLOSE,
-                                           _("Could not convert filename ‘%s’ to system filename encoding"),
-                                           filename_escaped_utf8);
-        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msgdialog),_("Try setting the 
environment variable G_FILENAME_ENCODING."));
-        gtk_window_set_title(GTK_WINDOW(msgdialog), _("Filename translation"));
-
-        gtk_dialog_run(GTK_DIALOG(msgdialog));
-        gtk_widget_destroy(msgdialog);
-        g_free(filename_escaped_utf8);
-        return FALSE;
-    }
-
-    // Get the current path to the file
-    dirname = g_path_get_dirname( ((File_Name *)ETFile->FileNameNew->data)->value );
-
-    // Convert filename extension (lower or upper)
-    extension = ET_File_Name_Format_Extension(ETFile);
-
-    // Check length of filename (limit ~255 characters)
-    //ET_File_Name_Check_Length(ETFile,filename);
-
-    // Filename (in file system encoding!)
-    if (filename && strlen(filename)>0)
-    {
-        // Regenerate the new filename (without path)
-        filename_new = g_strconcat(filename,extension,NULL);
-    }else
-    {
-        // Keep the 'last' filename (if a 'blank' filename was entered in the fileentry for ex)...
-        filename_new = g_path_get_basename( ((File_Name *)ETFile->FileNameNew->data)->value );
-    }
-    g_free (filename);
-    g_free (extension);
-
-    // Check if new filename seems to be correct
-    if ( !filename_new || strlen(filename_new) <= strlen(ETFile->ETFileDescription->Extension) )
-    {
-        FileName->value      = NULL;
-        FileName->value_utf8 = NULL;
-        FileName->value_ck   = NULL;
-
-        g_free(filename_new);
-        g_free(dirname);
-        return FALSE;
-    }
-
-    // Convert the illegal characters
-    ET_File_Name_Convert_Character(filename_new); // FIX ME : should be in UTF8?
-
-    /* Set the new filename (in file system encoding). */
-    FileName->value = g_strconcat(dirname,G_DIR_SEPARATOR_S,filename_new,NULL);
-    /* Set the new filename (in UTF-8 encoding). */
-    FileName->value_utf8 = filename_to_display(FileName->value);
-    // Calculates collate key
-    FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-
-    g_free(filename_new);
-    g_free(dirname);
-    return TRUE;
-}
-
-
-/*
- * Do the same thing of ET_Save_File_Name_From_UI, but without getting the
- * data from the UI.
- */
-static gboolean
-ET_Save_File_Name_Internal (const ET_File *ETFile,
-                            File_Name *FileName)
-{
-    gchar *filename_new = NULL;
-    gchar *dirname = NULL;
-    gchar *filename;
-    gchar *extension;
-    gchar *pos;
-
-    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
-
-    // Get the current path to the file
-    dirname = g_path_get_dirname( ((File_Name *)ETFile->FileNameNew->data)->value );
-
-    // Get the name of file (and rebuild it with extension with a 'correct' case)
-    filename = g_path_get_basename( ((File_Name *)ETFile->FileNameNew->data)->value );
-
-    // Remove the extension
-    if ((pos=strrchr(filename, '.'))!=NULL)
-        *pos = 0;
-
-    // Convert filename extension (lower/upper)
-    extension = ET_File_Name_Format_Extension(ETFile);
-
-    // Check length of filename
-    //ET_File_Name_Check_Length(ETFile,filename);
-
-    // Regenerate the new filename (without path)
-    filename_new = g_strconcat(filename,extension,NULL);
-    g_free(extension);
-    g_free(filename);
-
-    // Check if new filename seems to be correct
-    if (filename_new)
-    {
-        // Convert the illegal characters
-        ET_File_Name_Convert_Character(filename_new);
-
-        /* Set the new filename (in file system encoding). */
-        FileName->value = g_strconcat(dirname,G_DIR_SEPARATOR_S,filename_new,NULL);
-        /* Set the new filename (in UTF-8 encoding). */
-        FileName->value_utf8 = filename_to_display(FileName->value);
-        // Calculate collate key
-        FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-
-        g_free(filename_new);
-        g_free(dirname);
-        return TRUE;
-    }else
-    {
-        FileName->value = NULL;
-        FileName->value_utf8 = NULL;
-        FileName->value_ck = NULL;
-
-        g_free(filename_new);
-        g_free(dirname);
-        return FALSE;
-    }
-}
-
-/*
- * Do the same thing of et_tag_area_create_file_tag without getting the data from the UI.
- */
-static gboolean
-ET_Save_File_Tag_Internal (ET_File *ETFile, File_Tag *FileTag)
-{
-    File_Tag *FileTagCur;
-
-
-    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL
-                          && FileTag != NULL, FALSE);
-
-    FileTagCur = (File_Tag *)ETFile->FileTag->data;
-
-    /* Title */
-    if ( FileTagCur->title && g_utf8_strlen(FileTagCur->title, -1)>0 )
-    {
-        FileTag->title = g_strdup(FileTagCur->title);
-        g_strstrip (FileTag->title);
-    } else
-    {
-        FileTag->title = NULL;
-    }
-
-    /* Artist */
-    if ( FileTagCur->artist && g_utf8_strlen(FileTagCur->artist, -1)>0 )
-    {
-        FileTag->artist = g_strdup(FileTagCur->artist);
-        g_strstrip (FileTag->artist);
-    } else
-    {
-        FileTag->artist = NULL;
-    }
-
-       /* Album Artist */
-    if ( FileTagCur->album_artist && g_utf8_strlen(FileTagCur->album_artist, -1)>0 )
-    {
-        FileTag->album_artist = g_strdup(FileTagCur->album_artist);
-        g_strstrip (FileTag->album_artist);
-    } else
-    {
-        FileTag->album_artist = NULL;
-    }
-
-
-    /* Album */
-    if ( FileTagCur->album && g_utf8_strlen(FileTagCur->album, -1)>0 )
-    {
-        FileTag->album = g_strdup(FileTagCur->album);
-        g_strstrip (FileTag->album);
-    } else
-    {
-        FileTag->album = NULL;
-    }
-
-
-    /* Disc Number */
-    if ( FileTagCur->disc_number && g_utf8_strlen(FileTagCur->disc_number, -1)>0 )
-    {
-        FileTag->disc_number = g_strdup(FileTagCur->disc_number);
-        g_strstrip (FileTag->disc_number);
-    } else
-    {
-        FileTag->disc_number = NULL;
-    }
-
-
-    /* Discs Total */
-    if (FileTagCur->disc_total
-        && g_utf8_strlen (FileTagCur->disc_total, -1) > 0)
-    {
-        FileTag->disc_total = et_disc_number_to_string (atoi (FileTagCur->disc_total));
-        g_strstrip (FileTag->disc_total);
-    }
-    else
-    {
-        FileTag->disc_total = NULL;
-    }
-
-
-    /* Year */
-    if ( FileTagCur->year && g_utf8_strlen(FileTagCur->year, -1)>0 )
-    {
-        FileTag->year = g_strdup(FileTagCur->year);
-        g_strstrip (FileTag->year);
-    } else
-    {
-        FileTag->year = NULL;
-    }
-
-
-    /* Track */
-    if ( FileTagCur->track && g_utf8_strlen(FileTagCur->track, -1)>0 )
-    {
-        gchar *tmp_str;
-
-        FileTag->track = et_track_number_to_string (atoi (FileTagCur->track));
-
-        /* This field must contain only digits. */
-        tmp_str = FileTag->track;
-        while (g_ascii_isdigit (*tmp_str)) tmp_str++;
-            *tmp_str = 0;
-        g_strstrip (FileTag->track);
-    } else
-    {
-        FileTag->track = NULL;
-    }
-
-
-    /* Track Total */
-    if ( FileTagCur->track_total && g_utf8_strlen(FileTagCur->track_total, -1)>0 )
-    {
-        FileTag->track_total = et_track_number_to_string (atoi (FileTagCur->track_total));
-        g_strstrip (FileTag->track_total);
-    } else
-    {
-        FileTag->track_total = NULL;
-    }
-
-
-    /* Genre */
-    if ( FileTagCur->genre && g_utf8_strlen(FileTagCur->genre, -1)>0 )
-    {
-        FileTag->genre = g_strdup(FileTagCur->genre);
-        g_strstrip (FileTag->genre);
-    } else
-    {
-        FileTag->genre = NULL;
-    }
-
-
-    /* Comment */
-    if ( FileTagCur->comment && g_utf8_strlen(FileTagCur->comment, -1)>0 )
-    {
-        FileTag->comment = g_strdup(FileTagCur->comment);
-        g_strstrip (FileTag->comment);
-    } else
-    {
-        FileTag->comment = NULL;
-    }
-
-
-    /* Composer */
-    if ( FileTagCur->composer && g_utf8_strlen(FileTagCur->composer, -1)>0 )
-    {
-        FileTag->composer = g_strdup(FileTagCur->composer);
-        g_strstrip (FileTag->composer);
-    } else
-    {
-        FileTag->composer = NULL;
-    }
-
-
-    /* Original Artist */
-    if ( FileTagCur->orig_artist && g_utf8_strlen(FileTagCur->orig_artist, -1)>0 )
-    {
-        FileTag->orig_artist = g_strdup(FileTagCur->orig_artist);
-        g_strstrip (FileTag->orig_artist);
-    } else
-    {
-        FileTag->orig_artist = NULL;
-    }
-
-
-    /* Copyright */
-    if ( FileTagCur->copyright && g_utf8_strlen(FileTagCur->copyright, -1)>0 )
-    {
-        FileTag->copyright = g_strdup(FileTagCur->copyright);
-        g_strstrip (FileTag->copyright);
-    } else
-    {
-        FileTag->copyright = NULL;
-    }
-
-
-    /* URL */
-    if ( FileTagCur->url && g_utf8_strlen(FileTagCur->url, -1)>0 )
-    {
-        FileTag->url = g_strdup(FileTagCur->url);
-        g_strstrip (FileTag->url);
-    } else
-    {
-        FileTag->url = NULL;
-    }
-
-
-    /* Encoded by */
-    if ( FileTagCur->encoded_by && g_utf8_strlen(FileTagCur->encoded_by, -1)>0 )
-    {
-        FileTag->encoded_by = g_strdup(FileTagCur->encoded_by);
-        g_strstrip (FileTag->encoded_by);
-    } else
-    {
-        FileTag->encoded_by = NULL;
-    }
-
-
-    /* Picture */
-    et_file_tag_set_picture (FileTag, FileTagCur->picture);
-
-    return TRUE;
-}
-
-
-/*
- * Save data contained into File_Tag structure to the file on hard disk.
- */
-gboolean
-ET_Save_File_Tag_To_HD (ET_File *ETFile, GError **error)
-{
-    const ET_File_Description *ETFileDescription;
-    const gchar *cur_filename;
-    const gchar *cur_filename_utf8;
-    gboolean state;
-    GFile *file;
-    GFileInfo *fileinfo;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
-    cur_filename = ((File_Name *)(ETFile->FileNameCur)->data)->value;
-    cur_filename_utf8 = ((File_Name *)(ETFile->FileNameCur)->data)->value_utf8;
-
-    ETFileDescription = ETFile->ETFileDescription;
-
-    /* Store the file timestamps (in case they are to be preserved) */
-    file = g_file_new_for_path (cur_filename);
-    fileinfo = g_file_query_info (file, "time::*", G_FILE_QUERY_INFO_NONE,
-                                  NULL, NULL);
-
-    switch (ETFileDescription->TagType)
-    {
-#ifdef ENABLE_MP3
-        case ID3_TAG:
-            state = id3tag_write_file_tag (ETFile, error);
-            break;
-#endif
-#ifdef ENABLE_OGG
-        case OGG_TAG:
-            state = ogg_tag_write_file_tag (ETFile, error);
-            break;
-#endif
-#ifdef ENABLE_FLAC
-        case FLAC_TAG:
-            state = flac_tag_write_file_tag (ETFile, error);
-            break;
-#endif
-        case APE_TAG:
-            state = ape_tag_write_file_tag (ETFile, error);
-            break;
-#ifdef ENABLE_MP4
-        case MP4_TAG:
-            state = mp4tag_write_file_tag (ETFile, error);
-            break;
-#endif
-#ifdef ENABLE_WAVPACK
-        case WAVPACK_TAG:
-            state = wavpack_tag_write_file_tag (ETFile, error);
-            break;
-#endif
-#ifdef ENABLE_OPUS
-        case OPUS_TAG:
-            state = ogg_tag_write_file_tag (ETFile, error);
-            break;
-#endif
-        case UNKNOWN_TAG:
-        default:
-            Log_Print(LOG_ERROR,"Saving to HD: Undefined function for tag type '%d' (file %s).",
-                ETFileDescription->TagType,cur_filename_utf8);
-            state = FALSE;
-            break;
-    }
-
-    /* Update properties for the file. */
-    if (fileinfo)
-    {
-        if (g_settings_get_boolean (MainSettings,
-                                    "file-preserve-modification-time"))
-        {
-            g_file_set_attributes_from_info (file, fileinfo,
-                                             G_FILE_QUERY_INFO_NONE,
-                                             NULL, NULL);
-        }
-
-        g_object_unref (fileinfo);
-    }
-
-    /* Update the stored file modification time to prevent EasyTAG from warning
-     * that an external program has changed the file. */
-    fileinfo = g_file_query_info (file,
-                                  G_FILE_ATTRIBUTE_TIME_MODIFIED,
-                                  G_FILE_QUERY_INFO_NONE, NULL, NULL);
-
-    if (fileinfo)
-    {
-        ETFile->FileModificationTime = g_file_info_get_attribute_uint64 (fileinfo,
-                                                                         G_FILE_ATTRIBUTE_TIME_MODIFIED);
-        g_object_unref (fileinfo);
-    }
-
-    g_object_unref (file);
-
-    if (state==TRUE)
-    {
-
-        /* Update date and time of the parent directory of the file after
-         * changing the tag value (ex: needed for Amarok for refreshing). Note
-         * that when renaming a file the parent directory is automatically
-         * updated.
-         */
-        if (g_settings_get_boolean (MainSettings,
-                                    "file-update-parent-modification-time"))
-        {
-            gchar *path = g_path_get_dirname (cur_filename);
-            utime (path, NULL);
-            g_free (path);
-        }
-
-        ET_Mark_File_Tag_As_Saved(ETFile);
-        return TRUE;
-    }
-    else
-    {
-        g_assert (error == NULL || *error != NULL);
-
-        return FALSE;
-    }
-}
-
-/*
- * Function used to update path of filenames into list after renaming a parent directory
- * (for ex: "/mp3/old_path/file.mp3" to "/mp3/new_path/file.mp3"
- */
-void
-ET_Update_Directory_Name_Into_File_List (const gchar *last_path,
-                                         const gchar *new_path)
-{
-    GList *filelist;
-    ET_File *file;
-    GList *filenamelist;
-    gchar *filename;
-    gchar *last_path_tmp;
-
-    if (!ETCore->ETFileList || !last_path || !new_path ||
-        strlen(last_path) < 1 || strlen(new_path) < 1 )
-        return;
-
-    // Add '/' to end of path to avoid ambiguity between a directory and a filename...
-    if (last_path[strlen(last_path)-1]==G_DIR_SEPARATOR)
-        last_path_tmp = g_strdup(last_path);
-    else
-        last_path_tmp = g_strconcat(last_path,G_DIR_SEPARATOR_S,NULL);
-
-    for (filelist = g_list_first (ETCore->ETFileList); filelist != NULL;
-         filelist = g_list_next (filelist))
-    {
-        if ((file = filelist->data))
-        {
-            for (filenamelist = file->FileNameList; filenamelist != NULL;
-                 filenamelist = g_list_next (filenamelist))
-            {
-                File_Name *FileName = (File_Name *)filenamelist->data;
-
-                if ( FileName && (filename=FileName->value) )
-                {
-                    // Replace path of filename
-                    if ( strncmp(filename,last_path_tmp,strlen(last_path_tmp))==0 )
-                    {
-                        gchar *filename_tmp;
-
-                        // Create the new filename
-                        filename_tmp = g_strconcat(new_path,
-                                                   (new_path[strlen(new_path)-1]==G_DIR_SEPARATOR) ? "" : 
G_DIR_SEPARATOR_S,
-                                                   &filename[strlen(last_path_tmp)],NULL);
-
-                        /* Replace the filename (in file system encoding). */
-                        g_free(FileName->value);
-                        FileName->value = filename_tmp;
-                        /* Replace the filename (in file system encoding). */
-                        g_free(FileName->value_utf8);
-                        FileName->value_utf8 = filename_to_display(FileName->value);
-                        // Recalculate the collate key
-                        g_free(FileName->value_ck);
-                        FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
-                    }
-                }
-             }
-        }
-    }
-
-    g_free(last_path_tmp);
-}
-
-
-
-/***********************
- * Undo/Redo functions *
- ***********************/
-
-/*
- * Check if 'FileName' and 'FileTag' differ with those of 'ETFile'.
- * Manage undo feature for the ETFile and the main undo list.
- */
-gboolean ET_Manage_Changes_Of_File_Data (ET_File *ETFile, File_Name *FileName, File_Tag *FileTag)
-{
-    gboolean undo_added = FALSE;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    /*
-     * Detect changes of filename and generate the filename undo list
-     */
-    if (FileName)
-    {
-        if ( ETFile->FileNameNew && ET_Detect_Changes_Of_File_Name( (File_Name 
*)(ETFile->FileNameNew)->data,FileName )==TRUE )
-        {
-            ET_Add_File_Name_To_List(ETFile,FileName);
-            undo_added |= TRUE;
-        }else
-        {
-            ET_Free_File_Name_Item(FileName);
-        }
-    }
-
-    /*
-     * Detect changes in tag data and generate the tag undo list
-     */
-    if (FileTag)
-    {
-        if ( ETFile->FileTag && ET_Detect_Changes_Of_File_Tag( (File_Tag *)(ETFile->FileTag)->data,FileTag 
)==TRUE )
-        {
-            ET_Add_File_Tag_To_List(ETFile,FileTag);
-            undo_added |= TRUE;
-        }else
-        {
-            ET_Free_File_Tag_Item(FileTag);
-        }
-    }
-
-    /*
-     * Generate main undo (file history of modifications)
-     */
-    if (undo_added)
-        ET_Add_File_To_History_List(ETFile);
-
-    //return TRUE;
-    return undo_added;
-}
-
-
-/*
- * Compares two File_Name items :
- *  - returns TRUE if there aren't the same
- *  - else returns FALSE
- */
-static gboolean
-ET_Detect_Changes_Of_File_Name (const File_Name *FileName1,
-                                const File_Name *FileName2)
-{
-    const gchar *filename1_ck;
-    const gchar *filename2_ck;
-
-    if (!FileName1 && !FileName2) return FALSE;
-    if (FileName1 && !FileName2) return TRUE;
-    if (!FileName1 && FileName2) return TRUE;
-
-    /* Both FileName1 and FileName2 are != NULL. */
-    if (!FileName1->value && !FileName2->value) return FALSE;
-    if (FileName1->value && !FileName2->value) return TRUE;
-    if (!FileName1->value && FileName2->value) return TRUE;
-
-    /* Compare collate keys (with FileName->value converted to UTF-8 as it
-     * contains raw data). */
-    filename1_ck = FileName1->value_ck;
-    filename2_ck = FileName2->value_ck;
-
-    /* Filename changed ? (we check path + file). */
-    if (strcmp (filename1_ck, filename2_ck) != 0)
-    {
-        return TRUE;
-    }
-    else
-    {
-        return FALSE;
-    }
-}
-
-/*
- * Add a FileName item to the history list of ETFile
- */
-static gboolean
-ET_Add_File_Name_To_List (ET_File *ETFile, File_Name *FileName)
-{
-    GList *cut_list = NULL;
-
-    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
-
-    /* How it works : Cut the FileNameList list after the current item,
-     * and appends it to the FileNameListBak list for saving the data.
-     * Then appends the new item to the FileNameList list */
-    if (ETFile->FileNameList)
-    {
-        cut_list = ETFile->FileNameNew->next; // Cut after the current item...
-        ETFile->FileNameNew->next = NULL;
-    }
-    if (cut_list)
-        cut_list->prev = NULL;
-
-    /* Add the new item to the list */
-    ETFile->FileNameList = g_list_append(ETFile->FileNameList,FileName);
-    /* Set the current item to use */
-    ETFile->FileNameNew  = g_list_last(ETFile->FileNameList);
-    /* Backup list */
-    /* FIX ME! Keep only the saved item */
-    ETFile->FileNameListBak = g_list_concat(ETFile->FileNameListBak,cut_list);
-
-    return TRUE;
-}
-
-/*
- * Add a FileTag item to the history list of ETFile
- */
-static gboolean
-ET_Add_File_Tag_To_List (ET_File *ETFile, File_Tag *FileTag)
-{
-    GList *cut_list = NULL;
-
-    g_return_val_if_fail (ETFile != NULL && FileTag != NULL, FALSE);
-
-    if (ETFile->FileTag)
-    {
-        cut_list = ETFile->FileTag->next; // Cut after the current item...
-        ETFile->FileTag->next = NULL;
-    }
-    if (cut_list)
-        cut_list->prev = NULL;
-
-    /* Add the new item to the list */
-    ETFile->FileTagList = g_list_append(ETFile->FileTagList,FileTag);
-    /* Set the current item to use */
-    ETFile->FileTag     = g_list_last(ETFile->FileTagList);
-    /* Backup list */
-    ETFile->FileTagListBak = g_list_concat(ETFile->FileTagListBak,cut_list);
-
-    return TRUE;
-}
-
-/*
- * Add a ETFile item to the main undo list of files
- */
-static gboolean
-ET_Add_File_To_History_List (ET_File *ETFile)
-{
-    ET_History_File *ETHistoryFile;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    ETHistoryFile = g_slice_new0 (ET_History_File);
-    ETHistoryFile->ETFile = ETFile;
-
-    /* The undo list must contains one item before the 'first undo' data */
-    if (!ETCore->ETHistoryFileList)
-    {
-        ETCore->ETHistoryFileList = g_list_append (ETCore->ETHistoryFileList,
-                                                   g_slice_new0 (ET_History_File));
-    }
-
-    /* Add the item to the list (cut end of list from the current element) */
-    ETCore->ETHistoryFileList = g_list_append(ETCore->ETHistoryFileList,ETHistoryFile);
-    ETCore->ETHistoryFileList = g_list_last(ETCore->ETHistoryFileList);
-
-    return TRUE;
-}
-
-
-/*
- * Applies one undo to the ETFile data (to reload the previous data).
- * Returns TRUE if an undo had been applied.
- */
-gboolean ET_Undo_File_Data (ET_File *ETFile)
-{
-    gboolean has_filename_undo_data = FALSE;
-    gboolean has_filetag_undo_data  = FALSE;
-    guint    filename_key, filetag_key, undo_key;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    /* Find the valid key */
-    if (ETFile->FileNameNew->prev && ETFile->FileNameNew->data)
-        filename_key = ((File_Name *)ETFile->FileNameNew->data)->key;
-    else
-        filename_key = 0;
-    if (ETFile->FileTag->prev && ETFile->FileTag->data)
-        filetag_key = ((File_Tag *)ETFile->FileTag->data)->key;
-    else
-        filetag_key = 0;
-    // The key to use
-    undo_key = MAX(filename_key,filetag_key);
-
-    /* Undo filename */
-    if (ETFile->FileNameNew->prev && ETFile->FileNameNew->data
-    && (undo_key==((File_Name *)ETFile->FileNameNew->data)->key))
-    {
-        ETFile->FileNameNew = ETFile->FileNameNew->prev;
-        has_filename_undo_data = TRUE; // To indicate that an undo has been applied
-    }
-
-    /* Undo tag data */
-    if (ETFile->FileTag->prev && ETFile->FileTag->data
-    && (undo_key==((File_Tag *)ETFile->FileTag->data)->key))
-    {
-        ETFile->FileTag = ETFile->FileTag->prev;
-        has_filetag_undo_data  = TRUE;
-    }
-
-    return has_filename_undo_data | has_filetag_undo_data;
-}
-
-
-/*
- * Returns TRUE if file contains undo data (filename or tag)
- */
-gboolean
-ET_File_Data_Has_Undo_Data (const ET_File *ETFile)
-{
-    gboolean has_filename_undo_data = FALSE;
-    gboolean has_filetag_undo_data  = FALSE;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    if (ETFile->FileNameNew && ETFile->FileNameNew->prev) has_filename_undo_data = TRUE;
-    if (ETFile->FileTag && ETFile->FileTag->prev)         has_filetag_undo_data  = TRUE;
-
-    return has_filename_undo_data | has_filetag_undo_data;
-}
-
-
-/*
- * Applies one redo to the ETFile data. Returns TRUE if a redo had been applied.
- */
-gboolean ET_Redo_File_Data (ET_File *ETFile)
-{
-    gboolean has_filename_redo_data = FALSE;
-    gboolean has_filetag_redo_data  = FALSE;
-    guint    filename_key, filetag_key, undo_key;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    /* Find the valid key */
-    if (ETFile->FileNameNew->next && ETFile->FileNameNew->next->data)
-        filename_key = ((File_Name *)ETFile->FileNameNew->next->data)->key;
-    else
-        filename_key = (guint)~0; // To have the max value for guint
-    if (ETFile->FileTag->next && ETFile->FileTag->next->data)
-        filetag_key = ((File_Tag *)ETFile->FileTag->next->data)->key;
-    else
-        filetag_key = (guint)~0; // To have the max value for guint
-    // The key to use
-    undo_key = MIN(filename_key,filetag_key);
-
-    /* Redo filename */
-    if (ETFile->FileNameNew->next && ETFile->FileNameNew->next->data
-    && (undo_key==((File_Name *)ETFile->FileNameNew->next->data)->key))
-    {
-        ETFile->FileNameNew = ETFile->FileNameNew->next;
-        has_filename_redo_data = TRUE; // To indicate that a redo has been applied
-    }
-
-    /* Redo tag data */
-    if (ETFile->FileTag->next && ETFile->FileTag->next->data
-    && (undo_key==((File_Tag *)ETFile->FileTag->next->data)->key))
-    {
-        ETFile->FileTag = ETFile->FileTag->next;
-        has_filetag_redo_data  = TRUE;
-    }
-
-    return has_filename_redo_data | has_filetag_redo_data;
-}
-
-
-/*
- * Returns TRUE if file contains redo data (filename or tag)
- */
-gboolean
-ET_File_Data_Has_Redo_Data (const ET_File *ETFile)
-{
-    gboolean has_filename_redo_data = FALSE;
-    gboolean has_filetag_redo_data  = FALSE;
-
-    g_return_val_if_fail (ETFile != NULL, FALSE);
-
-    if (ETFile->FileNameNew && ETFile->FileNameNew->next) has_filename_redo_data = TRUE;
-    if (ETFile->FileTag && ETFile->FileTag->next)         has_filetag_redo_data  = TRUE;
-
-    return has_filename_redo_data | has_filetag_redo_data;
-}
-
-
-/*
- * Execute one 'undo' in the main undo list (it selects the last ETFile changed,
- * before to apply an undo action)
- */
-ET_File *ET_Undo_History_File_Data (void)
-{
-    ET_File *ETFile;
-    const ET_History_File *ETHistoryFile;
-
-    g_return_val_if_fail (ETCore->ETHistoryFileList != NULL ||
-                          ET_History_File_List_Has_Undo_Data (), NULL);
-
-    ETHistoryFile = (ET_History_File *)ETCore->ETHistoryFileList->data;
-    ETFile        = (ET_File *)ETHistoryFile->ETFile;
-    ET_Displayed_File_List_By_Etfile(ETFile);
-    ET_Undo_File_Data(ETFile);
-
-    if (ETCore->ETHistoryFileList->prev)
-        ETCore->ETHistoryFileList = ETCore->ETHistoryFileList->prev;
-    return ETFile;
-}
-
-
-/*
- * Returns TRUE if undo file list contains undo data
- */
-gboolean ET_History_File_List_Has_Undo_Data (void)
-{
-    if (ETCore->ETHistoryFileList && ETCore->ETHistoryFileList->prev)
-        return TRUE;
-    else
-        return FALSE;
-}
-
-
-/*
- * Execute one 'redo' in the main undo list
- */
-ET_File *ET_Redo_History_File_Data (void)
-{
-    ET_File *ETFile;
-    ET_History_File *ETHistoryFile;
-
-    if (!ETCore->ETHistoryFileList || !ET_History_File_List_Has_Redo_Data()) return NULL;
-
-    ETHistoryFile = (ET_History_File *)ETCore->ETHistoryFileList->next->data;
-    ETFile        = (ET_File *)ETHistoryFile->ETFile;
-    ET_Displayed_File_List_By_Etfile(ETFile);
-    ET_Redo_File_Data(ETFile);
-
-    if (ETCore->ETHistoryFileList->next)
-        ETCore->ETHistoryFileList = ETCore->ETHistoryFileList->next;
-    return ETFile;
-}
-
-
-/*
- * Returns TRUE if undo file list contains redo data
- */
-gboolean ET_History_File_List_Has_Redo_Data (void)
-{
-    if (ETCore->ETHistoryFileList && ETCore->ETHistoryFileList->next)
-        return TRUE;
-    else
-        return FALSE;
-}
-
-
-
-
-/**********************
- * Checking functions *
- **********************/
-
-
-/*
- * Ckecks if the current files had been changed but not saved.
- * Returns TRUE if the file has been saved.
- * Returns FALSE if some changes haven't been saved.
- */
-gboolean
-ET_Check_If_File_Is_Saved (const ET_File *ETFile)
-{
-    File_Tag  *FileTag     = NULL;
-    File_Name *FileNameNew = NULL;
-
-    g_return_val_if_fail (ETFile != NULL, TRUE);
-
-    if (ETFile->FileTag)
-        FileTag     = ETFile->FileTag->data;
-    if (ETFile->FileNameNew)
-        FileNameNew = ETFile->FileNameNew->data;
-
-    // Check if the tag has been changed
-    if ( FileTag && FileTag->saved != TRUE )
-        return FALSE;
-
-    // Check if name of file has been changed
-    if ( FileNameNew && FileNameNew->saved != TRUE )
-        return FALSE;
-
-    // No changes
-    return TRUE;
-}
-
-
-/*
- * Ckecks if some files, in the list, had been changed but not saved.
- * Returns TRUE if all files have been saved.
- * Returns FALSE if some changes haven't been saved.
- */
-gboolean ET_Check_If_All_Files_Are_Saved (void)
-{
-    /* Check if some files haven't been saved, if didn't nochange=0 */
-    if (!ETCore->ETFileList)
-    {
-        return TRUE;
-    }else
-    {
-        GList *l;
-
-        for (l = g_list_first (ETCore->ETFileList); l != NULL;
-             l = g_list_next (l))
-        {
-            if (ET_Check_If_File_Is_Saved ((ET_File *)l->data) == FALSE)
-                return FALSE;
-        }
-        return TRUE;
-    }
-}
-
-
-
-
-/*******************
- * Extra functions *
- *******************/
-
-/*
- * Set to TRUE the value of 'FileTag->saved' for the File_Tag item passed in parameter.
- * And set ALL other values of the list to FALSE.
- */
-static void
-Set_Saved_Value_Of_File_Tag (File_Tag *FileTag, gboolean saved)
-{
-    if (FileTag) FileTag->saved = saved;
-}
-
-static void
-ET_Mark_File_Tag_As_Saved (ET_File *ETFile)
-{
-    File_Tag *FileTag;
-    GList *FileTagList;
-
-    FileTag     = (File_Tag *)ETFile->FileTag->data;    // The current FileTag, to set to TRUE
-    FileTagList = ETFile->FileTagList;
-    g_list_foreach(FileTagList,(GFunc)Set_Saved_Value_Of_File_Tag,FALSE); // All other FileTag set to FALSE
-    FileTag->saved = TRUE; // The current FileTag set to TRUE
-}
-
-
-void ET_Mark_File_Name_As_Saved (ET_File *ETFile)
-{
-    File_Name *FileNameNew;
-    GList *FileNameList;
-
-    FileNameNew  = (File_Name *)ETFile->FileNameNew->data;    // The current FileName, to set to TRUE
-    FileNameList = ETFile->FileNameList;
-    g_list_foreach(FileNameList,(GFunc)Set_Saved_Value_Of_File_Tag,FALSE);
-    FileNameNew->saved = TRUE;
-}
-
-
-/*
- * et_core_read_file_info:
- * @file: a file from which to read information
- * @ETFileInfo: (out caller-allocates): a file information structure
- * @error: a #GError to provide information on erros, or %NULL to ignore
- *
- * Fille @ETFileInfo with information about the file. Currently, this only
- * fills the file size.
- *
- * Returns: %TRUE on success, %FALSE otherwise
- */
-static gboolean
-et_core_read_file_info (GFile *file,
-                        ET_File_Info *ETFileInfo,
-                        GError **error)
-{
-    GFileInfo *info;
-
-    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-    g_return_val_if_fail (file != NULL && ETFileInfo != NULL, FALSE);
-
-    info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
-                              G_FILE_QUERY_INFO_NONE, NULL, error);
-
-    if (!info)
-    {
-        g_assert (error == NULL || *error != NULL);
-        return FALSE;
-    }
-
-    ETFileInfo->version    = 0;
-    ETFileInfo->bitrate    = 0;
-    ETFileInfo->samplerate = 0;
-    ETFileInfo->mode       = 0;
-    ETFileInfo->size = g_file_info_get_size (info);
-    ETFileInfo->duration   = 0;
-
-    g_assert (error == NULL || *error == NULL);
-    g_object_unref (info);
-
-    return TRUE;
-}
-
-/*
- * This function generates a new filename using path of the old file and the
- * new name.
- * - ETFile -> old_file_name : "/path_to_file/old_name.ext"
- * - new_file_name_utf8      : "new_name.ext"
- * Returns "/path_to_file/new_name.ext" into allocated data (in UTF-8)!
- * Notes :
- *   - filenames (basemane) musn't exceed 255 characters (i.e. : "new_name.ext")
- *   - ogg filename musn't exceed 255-6 characters as we use mkstemp
- */
-#if 1
-gchar *
-ET_File_Name_Generate (const ET_File *ETFile,
-                       const gchar *new_file_name_utf8)
-{
-    gchar *dirname_utf8;
-
-    if (ETFile && ETFile->FileNameNew->data && new_file_name_utf8
-    && (dirname_utf8=g_path_get_dirname(((File_Name *)ETFile->FileNameNew->data)->value_utf8)) )
-    {
-        gchar *extension;
-        gchar *new_file_name_path_utf8;
-
-        // Convert filename extension (lower/upper)
-        extension = ET_File_Name_Format_Extension(ETFile);
-
-        // Check length of filename (limit ~255 characters)
-        //ET_File_Name_Check_Length(ETFile,new_file_name_utf8);
-
-        // If filemame starts with /, it's a full filename with path but without extension
-        if (g_path_is_absolute(new_file_name_utf8))
-        {
-            // We just add the extension
-            new_file_name_path_utf8 = g_strconcat(new_file_name_utf8,extension,NULL);
-        }else
-        {
-            // New path (with filename)
-            if ( strcmp(dirname_utf8,G_DIR_SEPARATOR_S)==0 ) // Root directory?
-                new_file_name_path_utf8 = g_strconcat(dirname_utf8,new_file_name_utf8,extension,NULL);
-            else
-                new_file_name_path_utf8 = 
g_strconcat(dirname_utf8,G_DIR_SEPARATOR_S,new_file_name_utf8,extension,NULL);
-        }
-
-        g_free (dirname_utf8);
-        g_free(extension);
-        return new_file_name_path_utf8; // in UTF-8
-    }else
-    {
-        return NULL;
-    }
-}
-#else
-/* FOR TESTING */
-/* Returns filename in file system encoding */
-gchar *ET_File_Name_Generate (ET_File *ETFile, gchar *new_file_name_utf8)
-{
-    gchar *dirname;
-
-    if (ETFile && ETFile->FileNameNew->data && new_file_name_utf8
-    && (dirname=g_path_get_dirname(((File_Name *)ETFile->FileNameNew->data)->value)) )
-    {
-        gchar *extension;
-        gchar *new_file_name_path;
-        gchar *new_file_name;
-
-        new_file_name = filename_from_display(new_file_name_utf8);
-
-        // Convert filename extension (lower/upper)
-        extension = ET_File_Name_Format_Extension(ETFile);
-
-        // Check length of filename (limit ~255 characters)
-        //ET_File_Name_Check_Length(ETFile,new_file_name_utf8);
-
-        // If filemame starts with /, it's a full filename with path but without extension
-        if (g_path_is_absolute(new_file_name))
-        {
-            // We just add the extension
-            new_file_name_path = g_strconcat(new_file_name,extension,NULL);
-        }else
-        {
-            // New path (with filename)
-            if ( strcmp(dirname,G_DIR_SEPARATOR_S)==0 ) // Root directory?
-                new_file_name_path = g_strconcat(dirname,new_file_name,extension,NULL);
-            else
-                new_file_name_path = g_strconcat(dirname,G_DIR_SEPARATOR_S,new_file_name,extension,NULL);
-        }
-
-        g_free(dirname);
-        g_free(new_file_name);
-        g_free(extension);
-        return new_file_name_path; // in file system encoding
-    }else
-    {
-        return NULL;
-    }
-}
-#endif
-
-
-/* Convert filename extension (lower/upper/no change). */
-static gchar *
-ET_File_Name_Format_Extension (const ET_File *ETFile)
-{
-    EtFilenameExtensionMode mode;
-
-    mode = g_settings_get_enum (MainSettings, "rename-extension-mode");
-
-    switch (mode)
-    {
-        /* FIXME: Should use filename encoding, not UTF-8! */
-        case ET_FILENAME_EXTENSION_LOWER_CASE:
-            return g_utf8_strdown (ETFile->ETFileDescription->Extension, -1);
-        case ET_FILENAME_EXTENSION_UPPER_CASE:
-            return g_utf8_strup (ETFile->ETFileDescription->Extension, -1);
-        case ET_FILENAME_EXTENSION_NO_CHANGE:
-        default:
-            return g_strdup (ETFile->ETFileExtension);
-    };
-}
-
-
-/*
- * Used to replace the illegal characters in the filename
- * Paremeter 'filename' musn't contain the path, else directories separators would be replaced!
- */
-gboolean ET_File_Name_Convert_Character (gchar *filename_utf8)
-{
-    gchar *character;
-
-    g_return_val_if_fail (filename_utf8 != NULL, FALSE);
-
-    // Convert automatically the directory separator ('/' on LINUX and '\' on WIN32) to '-'.
-    while ( (character=g_utf8_strchr(filename_utf8, -1, G_DIR_SEPARATOR))!=NULL )
-        *character = '-';
-
-#ifdef G_OS_WIN32
-    /* Convert character '\' on WIN32 to '-'. */
-    while ( (character=g_utf8_strchr(filename_utf8, -1, '\\'))!=NULL )
-        *character = '-';
-    /* Convert character '/' on WIN32 to '-'. May be converted to '\' after. */
-    while ( (character=g_utf8_strchr(filename_utf8, -1, '/'))!=NULL )
-        *character = '-';
-#endif /* G_OS_WIN32 */
-
-    /* Convert other illegal characters on FAT32/16 filesystems and ISO9660 and
-     * Joliet (CD-ROM filesystems). */
-    if (g_settings_get_boolean (MainSettings, "rename-replace-illegal-chars"))
-    {
-        // Commented as we display unicode values as "\351" for "é"
-        //while ( (character=g_utf8_strchr(filename_utf8, -1, '\\'))!=NULL )
-        //    *character = ',';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, ':'))!=NULL )
-            *character = '-';
-        //while ( (character=g_utf8_strchr(filename_utf8, -1, ';'))!=NULL )
-        //    *character = '-';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '*'))!=NULL )
-            *character = '+';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '?'))!=NULL )
-            *character = '_';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '\"'))!=NULL )
-            *character = '\'';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '<'))!=NULL )
-            *character = '(';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '>'))!=NULL )
-            *character = ')';
-        while ( (character=g_utf8_strchr(filename_utf8, -1, '|'))!=NULL )
-            *character = '-';
-    }
-    return TRUE;
-}
-
-
-/*
- * Returns the number of file in the directory of the selected file.
- * Parameter "path" should be in UTF-8
- */
-guint
-ET_Get_Number_Of_Files_In_Directory (const gchar *path_utf8)
-{
-    gchar *path_key;
-    GList *l;
-    guint  count = 0;
-
-    g_return_val_if_fail (path_utf8 != NULL, count);
-
-    path_key = g_utf8_collate_key (path_utf8, -1);
-
-    for (l = g_list_first (ETCore->ETFileList); l != NULL; l = g_list_next (l))
-    {
-        ET_File *ETFile = (ET_File *)l->data;
-        const gchar *cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
-        gchar *dirname_utf8      = g_path_get_dirname(cur_filename_utf8);
-        gchar *dirname_key = g_utf8_collate_key (dirname_utf8, -1);
-
-        if (strcmp (dirname_utf8, path_utf8) == 0)
-        {
-            count++;
-        }
-
-        g_free (dirname_utf8);
-        g_free (dirname_key);
-    }
-
-    g_free (path_key);
-
-    return count;
-}
-
-/*
- * Set appropriate sort order for the given column_id
- */
-static void
-set_sort_order_for_column_id (gint column_id, GtkTreeViewColumn *column,
-                              EtSortMode sort_type)
-{
-    EtApplicationWindow *window;
-    EtSortMode current_mode;
-
-    window = ET_APPLICATION_WINDOW (MainWindow);
-
-    /* Removing the sort indicator for the currently selected treeview
-     * column. */
-    current_mode = g_settings_get_enum (MainSettings, "sort-mode");
-
-    if (current_mode < ET_SORT_MODE_ASCENDING_CREATION_DATE)
-    {
-        gtk_tree_view_column_set_sort_indicator (et_application_window_browser_get_column_for_column_id 
(window, current_mode / 2),
-                                                 FALSE);
-    }
-
-    if (sort_type < ET_SORT_MODE_ASCENDING_CREATION_DATE)
-    {
-        gtk_tree_view_column_clicked (et_application_window_browser_get_column_for_column_id (window, 
column_id));
-
-        if (sort_type % 2 == 0)
-        {
-            /* GTK_SORT_ASCENDING */
-            if (et_application_window_browser_get_sort_order_for_column_id (window, column_id)
-                == GTK_SORT_DESCENDING)
-            {
-                gtk_tree_view_column_set_sort_order (column,
-                                                     GTK_SORT_ASCENDING);
-            }
-        }
-        else
-        {
-            /* GTK_SORT_DESCENDING */
-            if (et_application_window_browser_get_sort_order_for_column_id (window, column_id)
-                == GTK_SORT_ASCENDING)
-            {
-                gtk_tree_view_column_set_sort_order (column,
-                                                     GTK_SORT_DESCENDING);
-            }
-        }
-    }
-}
diff --git a/src/et_core.h b/src/et_core.h
index e0914a1..1afb9a3 100644
--- a/src/et_core.h
+++ b/src/et_core.h
@@ -20,17 +20,13 @@
 #ifndef ET_CORE_H_
 #define ET_CORE_H_
 
-#include "setting.h"
+#include <glib.h>
 
 G_BEGIN_DECLS
 
-#include <glib.h>
 #include <gdk/gdk.h>
 
-#include "core_types.h"
-#include "file_description.h"
-#include "file_tag.h"
-#include "picture.h"
+#include "file.h"
 
 /*
  * Colors Used (see declaration into et_core.c)
@@ -38,63 +34,9 @@ G_BEGIN_DECLS
 extern GdkRGBA RED;
 
 /*
- * Description of each item of the FileNameList list
- */
-typedef struct _File_Name File_Name;
-struct _File_Name
-{
-    guint key;
-    gboolean saved;        /* Set to TRUE if this filename had been saved */
-    gchar *value;          /* The filename containing the full path and the extension of the file */
-    gchar *value_utf8;     /* Same than "value", but converted to UTF-8 to avoid multiple call to the 
convertion function */
-    gchar *value_ck;       /* Collate key of "value_utf8" to speed up comparaison */
-};
-
-/*
- * Description of each item of the ETFileList list
- */
-typedef struct _ET_File ET_File;
-struct _ET_File
-{
-    guint IndexKey;           /* Value used to display the position in the list (and in the BrowserList) - 
Must be renumered after resorting the list - This value varies when resorting list */
-
-    guint ETFileKey;          /* Primary key to identify each item of the list (no longer used?) */
-
-    time_t FileModificationTime;            /* Save modification time of the file */
-
-    const ET_File_Description *ETFileDescription;
-    gchar               *ETFileExtension;   /* Real extension of the file (keeping the case) (should be 
placed in ETFileDescription?) */
-    ET_File_Info        *ETFileInfo;        /* Header infos: bitrate, duration, ... */
-
-    GList *FileNameCur;       /* Points to item of FileNameList that represents the current value of 
filename state (i.e. file on hard disk) */
-    GList *FileNameNew;       /* Points to item of FileNameList that represents the new value of filename 
state */
-    GList *FileNameList; /* Contains the history of changes about the filename. */
-    GList *FileNameListBak;   /* Contains items of FileNameList removed by 'undo' procedure but have data 
currently saved (for example, when you save your last changes, make some 'undo', then make new changes) */
-    
-    GList *FileTag;           /* Points to the current item used of FileTagList */
-    GList *FileTagList;       /* Contains the history of changes about file tag data */
-    GList *FileTagListBak;    /* Contains items of FileTagList removed by 'undo' procedure but have data 
currently saved */
-    
-};
-
-
-
-/*
- * Description of each item of the ETHistoryFileList list
- */
-typedef struct _ET_History_File ET_History_File;
-struct _ET_History_File
-{
-    ET_File *ETFile;           /* Pointer to item of ETFileList changed */
-};
-
-
-
-/*
  * Description of all variables, lists needed by EasyTAG
  */
-typedef struct _ET_Core ET_Core;
-struct _ET_Core
+typedef struct
 {
     // The main list of files
     GList *ETFileList;                  // List of ALL FILES (ET_File) loaded in the directory and 
sub-directories (List of ET_File) (This list musn't be altered, and points always to the first item)
@@ -102,135 +44,28 @@ struct _ET_Core
     // The list of files organized by artist then album
     GList *ETArtistAlbumFileList;
 
-
     // Displayed list (part of the main list of files displayed in BrowserList) (used when displaying by 
Artist & Album) 
     GList *ETFileDisplayedList;                 // List of files displayed (List of ET_File from ETFileList 
/ ATArtistAlbumFileList) | !! May not point to the first item!!
     GList *ETFileDisplayedListPtr;              // Pointer to the current item of ETFileDisplayedList used 
with ET_Displayed_File_List_First, ET_Displayed_File_List_Previous
     guint  ETFileDisplayedList_Length;          // Contains the length of the displayed list
     gfloat ETFileDisplayedList_TotalSize;       // Total of the size of files in displayed list (in bytes)
     gulong ETFileDisplayedList_TotalDuration;   // Total of duration of files in displayed list (in seconds)
-    
+
     // Displayed item
     ET_File *ETFileDisplayed;           // Pointer to the current ETFile displayed in EasyTAG (may be NULL)
 
 
     // History list
     GList *ETHistoryFileList;           // History list of files changes for undo/redo actions
-};
+} ET_Core;
 
 extern ET_Core *ETCore; /* Main pointer to structure needed by EasyTAG. */
 
-
-
-/**************
- * Prototypes *
- **************/
-
 void ET_Core_Create     (void);
 void ET_Core_Initialize (void);
 void ET_Core_Free       (void);
 void ET_Core_Destroy    (void);
 
-gboolean ET_File_Is_Supported (const gchar *filename);
-GList   *ET_Add_File_To_File_List        (gchar *filename);
-gboolean ET_Remove_File_From_File_List   (ET_File *ETFile);
-
-gboolean ET_Create_Artist_Album_File_List      (void);
-gboolean ET_Remove_File_From_File_List         (ET_File *ETFile);
-
-gboolean ET_Check_If_File_Is_Saved (const ET_File *ETFile);
-gboolean ET_Check_If_All_Files_Are_Saved (void);
-
-ET_File      *ET_File_Item_New       (void);
-File_Name    *ET_File_Name_Item_New  (void);
-void      ET_Free_File_List_Item (ET_File *ETFile);
-
-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);
-
-/* 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);
-GList   *ET_Displayed_File_List_Next        (void);
-GList   *ET_Displayed_File_List_Last        (void);
-GList *ET_Displayed_File_List_By_Etfile (const ET_File *ETFile);
-
-gboolean ET_Set_Displayed_File_List         (GList *ETFileList);
-
-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);
-gboolean ET_File_Data_Has_Redo_Data (const ET_File *ETFile);
-
-ET_File *ET_Undo_History_File_Data          (void);
-ET_File *ET_Redo_History_File_Data          (void);
-gboolean ET_History_File_List_Has_Undo_Data (void);
-gboolean ET_History_File_List_Has_Redo_Data (void);
-
-gboolean ET_Manage_Changes_Of_File_Data          (ET_File *ETFile, File_Name *FileName, File_Tag *FileTag);
-void     ET_Mark_File_Name_As_Saved              (ET_File *ETFile);
-void ET_Update_Directory_Name_Into_File_List (const gchar *last_path, const gchar *new_path);
-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);
-
-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);
-gint ET_Comp_Func_Sort_File_By_Descending_Filename (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Creation_Date (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Creation_Date (const ET_File *ETFile1, const ET_File *ETFile2);
-gint et_comp_func_sort_file_by_ascending_disc_number (const ET_File *ETFile1,
-                                                      const ET_File *ETFile2);
-gint et_comp_func_sort_file_by_descending_disc_number (const ET_File *ETFile1,
-                                                       const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Track_Number (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Track_Number (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Title (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Title (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Album_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Album_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Album (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Album (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Year (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Year (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Genre (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Genre (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Comment (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Comment (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Composer (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Composer (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Orig_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Copyright (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Copyright (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Url (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Url (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_Encoded_By (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_Encoded_By (const ET_File *ETFile1, const ET_File *ETFile2);
-
-gint ET_Comp_Func_Sort_File_By_Ascending_File_Type (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_File_Type (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_File_Size (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_File_Size (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_File_Duration (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_File_Duration (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_File_Bitrate (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate (const ET_File *ETFile1, const ET_File *ETFile2);
-gint ET_Comp_Func_Sort_File_By_Descending_File_Samplerate (const ET_File *ETFile1, const ET_File *ETFile2);
-
 G_END_DECLS
 
 #endif /* ET_CORE_H_ */
diff --git a/src/file.c b/src/file.c
new file mode 100644
index 0000000..9888aee
--- /dev/null
+++ b/src/file.c
@@ -0,0 +1,3893 @@
+/* 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 "config.h"
+
+#include "file.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include "application_window.h"
+#include "easytag.h"
+#include "file_tag.h"
+#include "mpeg_header.h"
+#include "monkeyaudio_header.h"
+#include "musepack_header.h"
+#ifdef ENABLE_MP3
+#   include "id3_tag.h"
+#endif
+#include "picture.h"
+#include "ape_tag.h"
+#ifdef ENABLE_OGG
+#   include "ogg_header.h"
+#   include "ogg_tag.h"
+#endif
+#ifdef ENABLE_FLAC
+#   include "flac_header.h"
+#   include "flac_tag.h"
+#endif
+#ifdef ENABLE_MP4
+#   include "mp4_header.h"
+#   include "mp4_tag.h"
+#endif
+#ifdef ENABLE_WAVPACK
+#   include "wavpack_header.h"
+#   include "wavpack_tag.h"
+#endif
+#ifdef ENABLE_OPUS
+#include "opus_tag.h"
+#include "opus_header.h"
+#endif
+#include "browser.h"
+#include "log.h"
+#include "misc.h"
+#include "setting.h"
+#include "charset.h"
+
+#include "win32/win32dep.h"
+
+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_Info_Item (ET_File_Info *ETFileInfo);
+
+static void ET_Initialize_File_Name_Item (File_Name *FileName);
+
+static guint ET_File_Key_New (void);
+
+static gboolean ET_Remove_File_From_Artist_Album_List (ET_File *ETFile);
+
+static void ET_Display_Filename_To_UI (const ET_File *ETFile);
+static EtFileHeaderFields * ET_Display_File_Info_To_UI (const ET_File *ETFile);
+
+static gboolean ET_Save_File_Name_From_UI (const ET_File *ETFile,
+                                           File_Name *FileName);
+static gboolean ET_Save_File_Name_Internal (const ET_File *ETFile, File_Name *FileName);
+static gboolean ET_Save_File_Tag_Internal (ET_File *ETFile, File_Tag *FileTag);
+
+static void ET_Mark_File_Tag_As_Saved (ET_File *ETFile);
+
+static gboolean ET_Detect_Changes_Of_File_Name (const File_Name *FileName1,
+                                                const File_Name *FileName2);
+static gboolean ET_Add_File_Name_To_List (ET_File *ETFile,
+                                          File_Name *FileName);
+static gboolean ET_Add_File_Tag_To_List (ET_File *ETFile, File_Tag  *FileTag);
+static gboolean ET_Add_File_To_History_List (ET_File *ETFile);
+static gboolean ET_Add_File_To_Artist_Album_File_List (ET_File *ETFile);
+
+static guint ET_Displayed_File_List_Get_Length      (void);
+static void ET_Displayed_File_List_Number (void);
+
+static gboolean et_core_read_file_info (GFile *file,
+                                        ET_File_Info *ETFileInfo,
+                                        GError **error);
+
+static gint ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist (const GList *AlbumList1,
+                                                               const GList *AlbumList2);
+static gint ET_Comp_Func_Sort_Album_Item_By_Ascending_Album (const GList *etfilelist1,
+                                                             const GList *etfilelist2);
+static gint ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename (const ET_File *ETFile1,
+                                                                 const ET_File *ETFile2);
+static gchar *ET_File_Name_Format_Extension (const ET_File *ETFile);
+
+static void set_sort_order_for_column_id (gint column_id,
+                                          GtkTreeViewColumn *column,
+                                          EtSortMode sort_type);
+
+/*
+ * Frees the full main list of files: GList *ETFileList and reinitialize it.
+ */
+gboolean
+ET_Free_File_List (void)
+{
+    g_return_val_if_fail (ETCore != NULL && ETCore->ETFileList != NULL, FALSE);
+
+    g_list_free_full (ETCore->ETFileList,
+                      (GDestroyNotify)ET_Free_File_List_Item);
+    ETCore->ETFileList = NULL;
+
+    return TRUE;
+}
+
+static void
+et_history_file_free (ET_History_File *file)
+{
+    g_slice_free (ET_History_File, file);
+}
+
+/*
+ * History list contains only pointers, so no data to free except the history structure.
+ */
+gboolean
+ET_Free_History_File_List (void)
+{
+    g_return_val_if_fail (ETCore != NULL && ETCore->ETHistoryFileList != NULL,
+                          FALSE);
+
+    ETCore->ETHistoryFileList = g_list_first (ETCore->ETHistoryFileList);
+
+    g_list_free_full (ETCore->ETHistoryFileList,
+                      (GDestroyNotify)et_history_file_free);
+
+    ETCore->ETHistoryFileList = NULL;
+
+    return TRUE;
+}
+
+/*
+ * "Display" list contains only pointers, so NOTHING to free
+ */
+gboolean
+ET_Free_Displayed_File_List (void)
+{
+    g_return_val_if_fail (ETCore != NULL
+                          && ETCore->ETFileDisplayedList != NULL, FALSE);
+
+    ETCore->ETFileDisplayedList = NULL;
+
+    return TRUE;
+}
+
+/*
+ * ArtistAlbum list contains 3 levels of lists
+ */
+gboolean
+ET_Free_Artist_Album_File_List (void)
+{
+    GList *l;
+
+    g_return_val_if_fail (ETCore != NULL
+                          && ETCore->ETArtistAlbumFileList != NULL, FALSE);
+
+    /* Pointers are stored inside the artist/album list-stores, so free them
+     * first. */
+    et_application_window_browser_clear_artist_model (ET_APPLICATION_WINDOW (MainWindow));
+    et_application_window_browser_clear_album_model (ET_APPLICATION_WINDOW (MainWindow));
+
+    for (l = ETCore->ETArtistAlbumFileList; l != NULL; l = g_list_next (l))
+    {
+        GList *m;
+
+        for (m = (GList *)l->data; m != NULL; m = g_list_next (m))
+        {
+            GList *n = (GList *)m->data;
+            if (n)
+                g_list_free (n);
+        }
+
+        if (l->data) /* Free AlbumList list. */
+            g_list_free ((GList *)l->data);
+    }
+
+    if (ETCore->ETArtistAlbumFileList)
+        g_list_free(ETCore->ETArtistAlbumFileList);
+
+    ETCore->ETArtistAlbumFileList = NULL;
+
+    return TRUE;
+}
+
+
+/*
+ * Create a new File_Name structure
+ */
+File_Name *ET_File_Name_Item_New (void)
+{
+    File_Name *FileName;
+
+    FileName = g_slice_new (File_Name);
+    ET_Initialize_File_Name_Item (FileName);
+
+    return FileName;
+}
+
+/*
+ * Create a new File_Info structure
+ */
+static ET_File_Info *
+ET_File_Info_Item_New (void)
+{
+    ET_File_Info *ETFileInfo;
+
+    ETFileInfo = g_slice_new0 (ET_File_Info);
+
+    return ETFileInfo;
+}
+
+
+/*
+ * Create a new ET_File structure
+ */
+ET_File *ET_File_Item_New (void)
+{
+    ET_File *ETFile;
+
+    ETFile = g_slice_new0 (ET_File);
+
+    return ETFile;
+}
+
+
+static void
+ET_Initialize_File_Name_Item (File_Name *FileName)
+{
+    if (FileName)
+    {
+        FileName->key        = ET_Undo_Key_New();
+        FileName->saved      = FALSE;
+        FileName->value      = NULL;
+        FileName->value_utf8 = NULL;
+        FileName->value_ck   = NULL;
+    }
+}
+
+
+/* Key for each item of ETFileList */
+static guint
+ET_File_Key_New (void)
+{
+    static guint ETFileKey = 0;
+    return ++ETFileKey;
+}
+
+/* Key for Undo */
+guint
+ET_Undo_Key_New (void)
+{
+    static guint ETUndoKey = 0;
+    return ++ETUndoKey;
+}
+
+
+
+
+/**********************************
+ * File adding/removing functions *
+ **********************************/
+
+/*
+ * ET_Add_File_To_File_List: Add a file to the "main" list. And get all information of the file.
+ * The filename passed in should be in raw format, only convert it to UTF8 when displaying it.
+ */
+GList *ET_Add_File_To_File_List (gchar *filename)
+{
+    const ET_File_Description *ETFileDescription;
+    ET_File      *ETFile;
+    File_Name    *FileName;
+    File_Tag     *FileTag;
+    ET_File_Info *ETFileInfo;
+    gchar        *ETFileExtension;
+    guint         ETFileKey;
+    guint         undo_key;
+    GFile *file;
+    GFileInfo *fileinfo;
+    gchar        *filename_utf8 = filename_to_display(filename);
+    const gchar  *locale_lc_ctype = getenv("LC_CTYPE");
+    GError *error = NULL;
+    gboolean success;
+
+    if (!filename)
+        return ETCore->ETFileList;
+
+    file = g_file_new_for_path (filename);
+
+    /* Primary Key for this file */
+    ETFileKey = ET_File_Key_New();
+
+    /* Get description of the file */
+    ETFileDescription = ET_Get_File_Description(filename);
+
+    /* Get real extension of the file (keeping the case) */
+    ETFileExtension = g_strdup(ET_Get_File_Extension(filename));
+
+    /* Fill the File_Name structure for FileNameList */
+    FileName = ET_File_Name_Item_New();
+    FileName->saved      = TRUE;    /* The file hasn't been changed, so it's saved */
+    FileName->value      = filename;
+    FileName->value_utf8 = filename_utf8;
+    FileName->value_ck   = g_utf8_collate_key_for_filename(filename_utf8, -1);
+
+    /* Fill the File_Tag structure for FileTagList */
+    FileTag = ET_File_Tag_Item_New();
+    FileTag->saved = TRUE;    /* The file hasn't been changed, so it's saved */
+
+    /* Patch from Doruk Fisek and Onur Kucuk: avoid upper/lower conversion bugs
+     * (like I->i conversion in some locales) in tag parsing. The problem occurs
+     * for example with Turkish language where it can't read 'TITLE=' field if
+     * it is written as 'Title=' in the file */
+    setlocale(LC_CTYPE, "C");
+
+    switch (ETFileDescription->TagType)
+    {
+#ifdef ENABLE_MP3
+        case ID3_TAG:
+            if (!id3tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           "Error reading ID3 tag from file ‘%s’: %s",
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#endif
+#ifdef ENABLE_OGG
+        case OGG_TAG:
+            if (!ogg_tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading tag from Ogg file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#endif
+#ifdef ENABLE_FLAC
+        case FLAC_TAG:
+            if (!flac_tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading tag from FLAC file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#endif
+        case APE_TAG:
+            if (!ape_tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading APE tag from file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#ifdef ENABLE_MP4
+        case MP4_TAG:
+            if (!mp4tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading tag from MP4 file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#endif
+#ifdef ENABLE_WAVPACK
+        case WAVPACK_TAG:
+            if (!wavpack_tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading tag from WavPack file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+        break;
+#endif
+#ifdef ENABLE_OPUS
+        case OPUS_TAG:
+            if (!et_opus_tag_read_file_tag (file, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error reading tag from Opus file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
+            break;
+#endif
+        case UNKNOWN_TAG:
+        default:
+            /* FIXME: Translatable string. */
+            Log_Print(LOG_ERROR,"FileTag: Undefined tag type (%d) for file 
%s",ETFileDescription->TagType,filename_utf8);
+            break;
+    }
+
+    if (FileTag->year && g_utf8_strlen (FileTag->year, -1) > 4)
+    {
+        Log_Print (LOG_WARNING,
+                   _("The year value ‘%s’ seems to be invalid in file ‘%s’. The information will be lost 
when saving"),
+                   FileTag->year, filename_utf8);
+    }
+
+    /* Fill the ET_File_Info structure */
+    ETFileInfo = ET_File_Info_Item_New ();
+
+    switch (ETFileDescription->FileType)
+    {
+#if defined ENABLE_MP3 && defined ENABLE_ID3LIB
+        case MP3_FILE:
+        case MP2_FILE:
+            success = et_mpeg_header_read_file_info (file, ETFileInfo, &error);
+            break;
+#endif
+#ifdef ENABLE_OGG
+        case OGG_FILE:
+            success = et_ogg_header_read_file_info (file, ETFileInfo, &error);
+            break;
+#endif
+#ifdef ENABLE_SPEEX
+        case SPEEX_FILE:
+            success = et_speex_header_read_file_info (file, ETFileInfo,
+                                                      &error);
+            break;
+#endif
+#ifdef ENABLE_FLAC
+        case FLAC_FILE:
+            success = et_flac_header_read_file_info (file, ETFileInfo, &error);
+            break;
+#endif
+        case MPC_FILE:
+            success = et_mpc_header_read_file_info (file, ETFileInfo, &error);
+            break;
+        case MAC_FILE:
+            success = et_mac_header_read_file_info (file, ETFileInfo, &error);
+            break;
+#ifdef ENABLE_WAVPACK
+        case WAVPACK_FILE:
+            success = et_wavpack_header_read_file_info (file, ETFileInfo,
+                                                        &error);
+            break;
+#endif
+#ifdef ENABLE_MP4
+        case MP4_FILE:
+            success = et_mp4_header_read_file_info (file, ETFileInfo, &error);
+            break;
+#endif
+#ifdef ENABLE_OPUS
+        case OPUS_FILE:
+            success = et_opus_read_file_info (file, ETFileInfo, &error);
+            break;
+#endif
+        case UNKNOWN_FILE:
+        default:
+            /* FIXME: Translatable string. */
+            Log_Print(LOG_ERROR,"ETFileInfo: Undefined file type (%d) for file 
%s",ETFileDescription->FileType,filename_utf8);
+            /* To get at least the file size. */
+            success = et_core_read_file_info (file, ETFileInfo, &error);
+            break;
+    }
+
+    if (!success)
+    {
+        Log_Print (LOG_ERROR,
+                   _("Error while querying information for file ‘%s’: %s"),
+                   filename_utf8, error->message);
+        g_error_free (error);
+    }
+
+    /* Restore previous value */
+    setlocale(LC_CTYPE, locale_lc_ctype ? locale_lc_ctype : "");
+
+    /* Store the modification time of the file to check if the file was changed
+     * before saving */
+    fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                                  G_FILE_QUERY_INFO_NONE, NULL, NULL);
+    g_object_unref (file);
+
+    /* Attach all data defined above to this ETFile item */
+    ETFile = ET_File_Item_New();
+
+    if (fileinfo)
+    {
+        ETFile->FileModificationTime = g_file_info_get_attribute_uint64 (fileinfo,
+                                                                         G_FILE_ATTRIBUTE_TIME_MODIFIED);
+        g_object_unref (fileinfo);
+    }
+    else
+    {
+        ETFile->FileModificationTime = 0;
+    }
+
+    ETFile->IndexKey             = 0; // Will be renumered after...
+    ETFile->ETFileKey            = ETFileKey;
+    ETFile->ETFileDescription    = ETFileDescription;
+    ETFile->ETFileExtension      = ETFileExtension;
+    ETFile->FileNameList         = g_list_append(NULL,FileName);
+    ETFile->FileNameCur          = ETFile->FileNameList;
+    ETFile->FileNameNew          = ETFile->FileNameList;
+    ETFile->FileTagList          = g_list_append(NULL,FileTag);
+    ETFile->FileTag              = ETFile->FileTagList;
+    ETFile->ETFileInfo           = ETFileInfo;
+
+    /* Add the item to the "main list" */
+    ETCore->ETFileList = g_list_append(ETCore->ETFileList,ETFile);
+
+
+    /*
+     * Process the filename and tag to generate undo if needed...
+     * The undo key must be the same for FileName and FileTag => changed in the same time
+     */
+    undo_key = ET_Undo_Key_New();
+
+    FileName = ET_File_Name_Item_New();
+    FileName->key = undo_key;
+    ET_Save_File_Name_Internal(ETFile,FileName);
+
+    FileTag = ET_File_Tag_Item_New();
+    FileTag->key = undo_key;
+    ET_Save_File_Tag_Internal(ETFile,FileTag);
+
+    /*
+     * Generate undo for the file and the main undo list.
+     * If no changes detected, FileName and FileTag item are deleted.
+     */
+    ET_Manage_Changes_Of_File_Data(ETFile,FileName,FileTag);
+
+    /*
+     * Display a message if the file was changed at start
+     */
+    FileTag  = (File_Tag *)ETFile->FileTag->data;
+    FileName = (File_Name *)ETFile->FileNameNew->data;
+    if ( (FileName && FileName->saved==FALSE) || (FileTag && FileTag->saved==FALSE) )
+    {
+        Log_Print (LOG_INFO, _("Automatic corrections applied for file ‘%s’"),
+                   filename_utf8);
+    }
+
+    /* Add the item to the ArtistAlbum list (placed here to take advantage of previous changes) */
+    //ET_Add_File_To_Artist_Album_File_List(ETFile);
+
+    //ET_Debug_Print_File_List(ETCore->ETFileList,__FILE__,__LINE__,__FUNCTION__);
+    return ETCore->ETFileList;
+}
+
+gboolean ET_Create_Artist_Album_File_List (void)
+{
+    GList *l;
+
+    if (ETCore->ETArtistAlbumFileList)
+        ET_Free_Artist_Album_File_List();
+
+    for (l = g_list_first (ETCore->ETFileList); l != NULL; l = g_list_next (l))
+    {
+        ET_File *ETFile = (ET_File *)l->data;
+        ET_Add_File_To_Artist_Album_File_List(ETFile);
+    }
+    //ET_Debug_Print_Artist_Album_List(__FILE__,__LINE__,__FUNCTION__);
+    return TRUE;
+}
+/*
+ * The ETArtistAlbumFileList contains 3 levels of lists to sort the ETFile by artist then by album :
+ *  - "ETArtistAlbumFileList" list is a list of "ArtistList" items,
+ *  - "ArtistList" list is a list of "AlbumList" items,
+ *  - "AlbumList" list is a list of ETFile items.
+ * Note : use the function ET_Debug_Print_Artist_Album_List(...) to understand how it works, it needed...
+ */
+static gboolean
+ET_Add_File_To_Artist_Album_File_List (ET_File *ETFile)
+{
+    const gchar *ETFile_Artist;
+    const gchar *ETFile_Album;
+    const gchar *etfile_artist;
+    const gchar *etfile_album;
+    GList *ArtistList;
+    GList *AlbumList = NULL;
+    GList *etfilelist = NULL;
+    ET_File *etfile = NULL;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    /* Album value of the ETFile passed in parameter. */
+    ETFile_Album = ((File_Tag *)ETFile->FileTag->data)->album;
+    /* Artist value of the ETFile passed in parameter. */
+    ETFile_Artist = ((File_Tag *)ETFile->FileTag->data)->artist;
+
+    for (ArtistList = ETCore->ETArtistAlbumFileList; ArtistList != NULL;
+         ArtistList = g_list_next (ArtistList))
+    {
+        AlbumList = (GList *)ArtistList->data;  /* Take the first item */
+        /* Take the first item, and the first etfile item. */
+        if (AlbumList && (etfilelist = (GList *)AlbumList->data)
+            && (etfile = (ET_File *)etfilelist->data)
+            && ((File_Tag *)etfile->FileTag->data) != NULL)
+        {
+            etfile_artist = ((File_Tag *)etfile->FileTag->data)->artist;
+        }
+        else
+        {
+            etfile_artist = NULL;
+        }
+
+        if ((etfile_artist &&  ETFile_Artist && strcmp (etfile_artist,
+                                                        ETFile_Artist) == 0)
+            || (!etfile_artist && !ETFile_Artist)) /* The "artist" values correspond? */
+        {
+            /* The "ArtistList" item was found! */
+            while (AlbumList)
+            {
+                if ((etfilelist = (GList *)AlbumList->data)
+                    && (etfile = (ET_File *)etfilelist->data)
+                    && ((File_Tag *)etfile->FileTag->data) != NULL)
+                {
+                    etfile_album = ((File_Tag *)etfile->FileTag->data)->album;
+                }
+                else
+                {
+                    etfile_album = NULL;
+                }
+
+                if ((etfile_album && ETFile_Album && strcmp (etfile_album,
+                                                             ETFile_Album) == 0)
+                    || (!etfile_album && !ETFile_Album))
+                    /* The "album" values correspond? */
+                {
+                    /* The "AlbumList" item was found!
+                     * Add the ETFile to this AlbumList item */
+                    AlbumList->data = g_list_append ((GList *)AlbumList->data,
+                                                     ETFile);
+                    AlbumList->data = g_list_sort ((GList *)AlbumList->data,
+                                                   
(GCompareFunc)ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename);
+                    return TRUE;
+                }
+
+                AlbumList = g_list_next (AlbumList);
+            }
+
+            /* The "AlbumList" item was NOT found! => Add a new "AlbumList"
+             * item (+...) item to the "ArtistList" list. */
+            etfilelist = g_list_append (NULL, ETFile);
+            ArtistList->data = g_list_append ((GList *)ArtistList->data,
+                                              etfilelist);
+            ArtistList->data = g_list_sort ((GList *)ArtistList->data,
+                                            (GCompareFunc)ET_Comp_Func_Sort_Album_Item_By_Ascending_Album);
+            return TRUE;
+        }
+    }
+
+    /* The "ArtistList" item was NOT found! => Add a new "ArtistList" to the
+     * main list (=ETArtistAlbumFileList). */
+    etfilelist = g_list_append (NULL, ETFile);
+    AlbumList  = g_list_append (NULL, etfilelist);
+    ETCore->ETArtistAlbumFileList = g_list_append (ETCore->ETArtistAlbumFileList,
+                                                   AlbumList);
+
+    /* Sort the list by ascending Artist. */
+    ETCore->ETArtistAlbumFileList = g_list_sort (ETCore->ETArtistAlbumFileList,
+                                                 
(GCompareFunc)ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist);
+
+    return TRUE;
+}
+
+
+
+/*
+ * Delete the corresponding file and free the allocated data. Return TRUE if deleted.
+ */
+gboolean ET_Remove_File_From_File_List (ET_File *ETFile)
+{
+    GList *ETFileList = NULL;          // Item containing the ETFile to delete... (in ETCore->ETFileList)
+    GList *ETFileDisplayedList = NULL; // Item containing the ETFile to delete... (in 
ETCore->ETFileDisplayedList)
+
+    // Remove infos of the file
+    ETCore->ETFileDisplayedList_TotalSize     -= ((ET_File_Info *)ETFile->ETFileInfo)->size;
+    ETCore->ETFileDisplayedList_TotalDuration -= ((ET_File_Info *)ETFile->ETFileInfo)->duration;
+
+    // Find the ETFileList containing the ETFile item
+    ETFileDisplayedList = g_list_find(g_list_first(ETCore->ETFileDisplayedList),ETFile);
+    ETFileList          = g_list_find(g_list_first(ETCore->ETFileList),ETFile);
+
+    // Note : this ETFileList must be used only for ETCore->ETFileDisplayedList, and not 
ETCore->ETFileDisplayed
+    if (ETCore->ETFileDisplayedList == ETFileDisplayedList)
+    {
+        if (ETFileList->next)
+            ETCore->ETFileDisplayedList = ETFileDisplayedList->next;
+        else if (ETFileList->prev)
+            ETCore->ETFileDisplayedList = ETFileDisplayedList->prev;
+        else
+            ETCore->ETFileDisplayedList = NULL;
+    }
+    // If the current displayed file is just removing, it will be unable to display it again!
+    if (ETCore->ETFileDisplayed == ETFile)
+    {
+        if (ETCore->ETFileDisplayedList)
+            ETCore->ETFileDisplayed = (ET_File *)ETCore->ETFileDisplayedList->data;
+        else
+            ETCore->ETFileDisplayed = (ET_File *)NULL;
+    }
+
+    /* Remove the file from the ETFileList list. */
+    ETCore->ETFileList = g_list_remove (g_list_first (ETCore->ETFileList),
+                                        ETFileList);
+
+    // Remove the file from the ETArtistAlbumList list
+    ET_Remove_File_From_Artist_Album_List(ETFile);
+
+    /* Remove the file from the ETFileDisplayedList list (if not already). */
+    ETCore->ETFileDisplayedList = g_list_remove (g_list_first (ETCore->ETFileDisplayedList),
+                                                 ETFileDisplayedList);
+
+    // Free data of the file
+    ET_Free_File_List_Item(ETFile);
+    if (ETFileList)
+        g_list_free(ETFileList);
+    if (ETFileDisplayedList)
+        g_list_free(ETFileDisplayedList);
+
+    // Recalculate length of ETFileDisplayedList list
+    ET_Displayed_File_List_Get_Length();
+
+    // To number the ETFile in the list
+    ET_Displayed_File_List_Number();
+
+    // Displaying...
+    if (ETCore->ETFileDisplayedList)
+    {
+        if (ETCore->ETFileDisplayed)
+        {
+            ET_Displayed_File_List_By_Etfile(ETCore->ETFileDisplayed);
+        }else if (ETCore->ETFileDisplayedList->data)
+        {
+            // Select the new file (synchronize index,...)
+            ET_Displayed_File_List_By_Etfile((ET_File *)ETCore->ETFileDisplayedList->data);
+        }
+    }else
+    {
+        // Reinit the tag and file area
+        et_application_window_file_area_clear (ET_APPLICATION_WINDOW (MainWindow));
+        et_application_window_tag_area_clear (ET_APPLICATION_WINDOW (MainWindow));
+        et_application_window_update_actions (ET_APPLICATION_WINDOW (MainWindow));
+    }
+
+    return TRUE;
+}
+
+
+/*
+ * Delete the corresponding file (allocated data was previously freed!). Return TRUE if deleted.
+ */
+static gboolean
+ET_Remove_File_From_Artist_Album_List (ET_File *ETFile)
+{
+    GList *ArtistList;
+    GList *AlbumList;
+    GList *etfilelist;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    /* Search for the ETFile in the list. */
+    for (ArtistList = ETCore->ETArtistAlbumFileList; ArtistList != NULL;
+         ArtistList = g_list_next (ArtistList))
+    {
+        for (AlbumList = g_list_first ((GList *)ArtistList->data);
+             AlbumList != NULL; AlbumList = g_list_next (AlbumList))
+        {
+            for (etfilelist = g_list_first ((GList *)AlbumList->data);
+                 etfilelist != NULL; etfilelist = g_list_next (etfilelist))
+            {
+                ET_File *etfile = (ET_File *)etfilelist->data;
+
+                if (ETFile == etfile) /* The ETFile to delete was found! */
+                {
+                    etfilelist = g_list_remove (etfilelist, ETFile);
+
+                    if (etfilelist) /* Delete from AlbumList. */
+                    {
+                        AlbumList->data = (gpointer) g_list_first (etfilelist);
+                    }
+                    else
+                    {
+                        AlbumList = g_list_remove (AlbumList, AlbumList->data);
+
+                        if (AlbumList) /* Delete from ArtistList. */
+                        {
+                            ArtistList->data = AlbumList;
+                        }
+                        else
+                        {
+                            /* Delete from the main list. */
+                            ETCore->ETArtistAlbumFileList = g_list_remove (ArtistList,ArtistList->data);
+
+                            return TRUE;
+                        }
+
+                        return TRUE;
+                    }
+
+                    return TRUE;
+                }
+            }
+        }
+    }
+
+    return FALSE; /* ETFile is NUL, or not found in the list. */
+}
+
+/**************************
+ * File sorting functions *
+ **************************/
+
+/*
+ * Sort the 'ETFileDisplayedList' following the 'Sorting_Type'
+ * Note : Add also new sorting in 'Browser_List_Sort_Func'
+ */
+static void
+ET_Sort_Displayed_File_List (EtSortMode Sorting_Type)
+{
+    ETCore->ETFileDisplayedList = ET_Sort_File_List(ETCore->ETFileDisplayedList,Sorting_Type);
+}
+
+/*
+ * Sort an 'ETFileList'
+ */
+GList *
+ET_Sort_File_List (GList *ETFileList, EtSortMode Sorting_Type)
+{
+    EtApplicationWindow *window;
+    GtkTreeViewColumn *column;
+    GList *etfilelist;
+    gint column_id = Sorting_Type / 2;
+
+    window = ET_APPLICATION_WINDOW (MainWindow);
+    column = et_application_window_browser_get_column_for_column_id (window,
+                                                                     column_id);
+
+    /* Important to rewind before. */
+    etfilelist = g_list_first (ETFileList);
+
+    /* FIXME: Port to sort-mode? */
+    set_sort_order_for_column_id (column_id, column, Sorting_Type);
+
+    /* Sort... */
+    switch (Sorting_Type)
+    {
+        case ET_SORT_MODE_ASCENDING_FILENAME:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Filename);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILENAME:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Filename);
+            break;
+        case ET_SORT_MODE_ASCENDING_TITLE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Title);
+            break;
+        case ET_SORT_MODE_DESCENDING_TITLE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Title);
+            break;
+        case ET_SORT_MODE_ASCENDING_ARTIST:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Artist);
+            break;
+        case ET_SORT_MODE_DESCENDING_ARTIST:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Artist);
+            break;
+        case ET_SORT_MODE_ASCENDING_ALBUM_ARTIST:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Album_Artist);
+            break;
+        case ET_SORT_MODE_DESCENDING_ALBUM_ARTIST:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Album_Artist);
+            break;
+               case ET_SORT_MODE_ASCENDING_ALBUM:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Album);
+            break;
+        case ET_SORT_MODE_DESCENDING_ALBUM:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Album);
+            break;
+        case ET_SORT_MODE_ASCENDING_YEAR:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Year);
+            break;
+        case ET_SORT_MODE_DESCENDING_YEAR:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Year);
+            break;
+        case ET_SORT_MODE_ASCENDING_DISC_NUMBER:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)et_comp_func_sort_file_by_ascending_disc_number);
+            break;
+        case ET_SORT_MODE_DESCENDING_DISC_NUMBER:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)et_comp_func_sort_file_by_descending_disc_number);
+            break;
+        case ET_SORT_MODE_ASCENDING_TRACK_NUMBER:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Track_Number);
+            break;
+        case ET_SORT_MODE_DESCENDING_TRACK_NUMBER:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Track_Number);
+            break;
+        case ET_SORT_MODE_ASCENDING_GENRE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Genre);
+            break;
+        case ET_SORT_MODE_DESCENDING_GENRE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Genre);
+            break;
+        case ET_SORT_MODE_ASCENDING_COMMENT:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Comment);
+            break;
+        case ET_SORT_MODE_DESCENDING_COMMENT:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Comment);
+            break;
+        case ET_SORT_MODE_ASCENDING_COMPOSER:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Composer);
+            break;
+        case ET_SORT_MODE_DESCENDING_COMPOSER:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Composer);
+            break;
+        case ET_SORT_MODE_ASCENDING_ORIG_ARTIST:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist);
+            break;
+        case ET_SORT_MODE_DESCENDING_ORIG_ARTIST:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Orig_Artist);
+            break;
+        case ET_SORT_MODE_ASCENDING_COPYRIGHT:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Copyright);
+            break;
+        case ET_SORT_MODE_DESCENDING_COPYRIGHT:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Copyright);
+            break;
+        case ET_SORT_MODE_ASCENDING_URL:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Url);
+            break;
+        case ET_SORT_MODE_DESCENDING_URL:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Url);
+            break;
+        case ET_SORT_MODE_ASCENDING_ENCODED_BY:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Encoded_By);
+            break;
+        case ET_SORT_MODE_DESCENDING_ENCODED_BY:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Encoded_By);
+            break;
+        case ET_SORT_MODE_ASCENDING_CREATION_DATE:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_Creation_Date);
+            break;
+        case ET_SORT_MODE_DESCENDING_CREATION_DATE:
+            etfilelist = g_list_sort (etfilelist,
+                                      (GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_Creation_Date);
+            break;
+        case ET_SORT_MODE_ASCENDING_FILE_TYPE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Type);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILE_TYPE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Type);
+            break;
+        case ET_SORT_MODE_ASCENDING_FILE_SIZE:
+            etfilelist = g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Size);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILE_SIZE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Size);
+            break;
+        case ET_SORT_MODE_ASCENDING_FILE_DURATION:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Duration);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILE_DURATION:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Duration);
+            break;
+        case ET_SORT_MODE_ASCENDING_FILE_BITRATE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILE_BITRATE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Bitrate);
+            break;
+        case ET_SORT_MODE_ASCENDING_FILE_SAMPLERATE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate);
+            break;
+        case ET_SORT_MODE_DESCENDING_FILE_SAMPLERATE:
+            etfilelist = 
g_list_sort(etfilelist,(GCompareFunc)ET_Comp_Func_Sort_File_By_Descending_File_Samplerate);
+            break;
+    }
+    /* Save sorting mode (note: needed when called from UI). */
+    g_settings_set_enum (MainSettings, "sort-mode", Sorting_Type);
+
+    //ETFileList = g_list_first(etfilelist);
+    return etfilelist;
+}
+
+
+/*
+ * Sort the list of files following the 'Sorting_Type' value. The new sorting is displayed in the UI.
+ */
+void
+ET_Sort_Displayed_File_List_And_Update_UI (EtSortMode Sorting_Type)
+{
+    g_return_if_fail (ETCore->ETFileList != NULL);
+
+    ET_Save_File_Data_From_UI(ETCore->ETFileDisplayed);
+
+    /* Sort the list */
+    ET_Sort_Displayed_File_List(Sorting_Type);
+
+    /* To number the ETFile in the list */
+    ET_Displayed_File_List_Number();
+
+    /* Reload files in browser list */
+    ET_Displayed_File_List_By_Etfile(ETCore->ETFileDisplayed);  // Just to update 'ETFileDisplayedList'
+    et_application_window_browser_select_file_by_et_file (ET_APPLICATION_WINDOW (MainWindow),
+                                                          ETCore->ETFileDisplayed,
+                                                          TRUE);
+    ET_Display_File_Data_To_UI(ETCore->ETFileDisplayed);
+
+    et_application_window_browser_refresh_sort (ET_APPLICATION_WINDOW (MainWindow));
+    et_application_window_update_actions (ET_APPLICATION_WINDOW (MainWindow));
+}
+
+
+/*
+ * Comparison function for sorting by ascending filename.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Filename (const ET_File *ETFile1,
+                                              const ET_File *ETFile2)
+{
+    const gchar *file1_ck = ((File_Name *)((GList *)ETFile1->FileNameCur)->data)->value_ck;
+    const gchar *file2_ck = ((File_Name *)((GList *)ETFile2->FileNameCur)->data)->value_ck;
+    // !!!! : Must be the same rules as "Cddb_Track_List_Sort_Func" to be
+    // able to sort in the same order files in cddb and in the file list.
+    return g_settings_get_boolean (MainSettings,
+                                   "sort-case-sensitive") ? strcmp (file1_ck, file2_ck)
+                                                          : strcasecmp (file1_ck, file2_ck);
+}
+
+/*
+ * Comparison function for sorting by descending filename.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Filename (const ET_File *ETFile1,
+                                               const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending disc number.
+ */
+gint
+et_comp_func_sort_file_by_ascending_disc_number (const ET_File *ETFile1,
+                                                 const ET_File *ETFile2)
+{
+    gint track1, track2;
+
+    if (!ETFile1->FileTag->data
+        || !((File_Tag *)ETFile1->FileTag->data)->disc_number)
+    {
+        track1 = 0;
+    }
+    else
+    {
+        track1 = atoi (((File_Tag *)ETFile1->FileTag->data)->disc_number);
+    }
+
+    if (!ETFile2->FileTag->data
+        || !((File_Tag *)ETFile2->FileTag->data)->disc_number)
+    {
+        track2 = 0;
+    }
+    else
+    {
+        track2 = atoi (((File_Tag *)ETFile2->FileTag->data)->disc_number);
+    }
+
+    /* Second criterion. */
+    if (track1 == track2)
+    {
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename (ETFile1, ETFile2);
+    }
+
+    /* First criterion. */
+    return (track1 - track2);
+}
+
+/*
+ * Comparison function for sorting by descending disc number.
+ */
+gint
+et_comp_func_sort_file_by_descending_disc_number (const ET_File *ETFile1,
+                                                  const ET_File *ETFile2)
+{
+    return et_comp_func_sort_file_by_ascending_disc_number (ETFile2, ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending track number.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Track_Number (const ET_File *ETFile1,
+                                                  const ET_File *ETFile2)
+{
+    gint track1, track2;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->track )
+        track1 = 0;
+    else
+        track1 = atoi( ((File_Tag *)ETFile1->FileTag->data)->track );
+
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->track )
+        track2 = 0;
+    else
+        track2 = atoi( ((File_Tag *)ETFile2->FileTag->data)->track );
+
+    // Second criterion
+    if (track1 == track2)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (track1 - track2);
+}
+
+/*
+ * Comparison function for sorting by descending track number.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Track_Number (const ET_File *ETFile1,
+                                                   const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Track_Number(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending creation date.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Creation_Date (const ET_File *ETFile1,
+                                                   const ET_File *ETFile2)
+{
+    GFile *file;
+    GFileInfo *info;
+    guint64 time1 = 0;
+    guint64 time2 = 0;
+
+    /* TODO: Report errors? */
+    file = g_file_new_for_path (((File_Name *)ETFile1->FileNameCur->data)->value);
+    info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_CHANGED,
+                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+    g_object_unref (file);
+
+    if (info)
+    {
+        time1 = g_file_info_get_attribute_uint64 (info,
+                                                  G_FILE_ATTRIBUTE_TIME_CHANGED);
+        g_object_unref (info);
+    }
+
+    file = g_file_new_for_path (((File_Name *)ETFile2->FileNameCur->data)->value);
+    info = g_file_query_info (file, G_FILE_ATTRIBUTE_TIME_CHANGED,
+                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+    g_object_unref (file);
+
+    if (info)
+    {
+        time2 = g_file_info_get_attribute_uint64 (info,
+                                                  G_FILE_ATTRIBUTE_TIME_CHANGED);
+        g_object_unref (info);
+    }
+
+    /* Second criterion. */
+    if (time1 == time2)
+    {
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename (ETFile1, ETFile2);
+    }
+
+    /* First criterion. */
+    return (gint64)(time1 - time2);
+}
+
+/*
+ * Comparison function for sorting by descending creation date.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Creation_Date (const ET_File *ETFile1,
+                                                    const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Creation_Date(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending title.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Title (const ET_File *ETFile1,
+                                           const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->title == ((File_Tag *)ETFile2->FileTag->data)->title))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->title )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->title )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag *)ETFile2->FileTag->data)->title) 
== 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+      else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->title,((File_Tag 
*)ETFile2->FileTag->data)->title);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending title.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Title (const ET_File *ETFile1,
+                                            const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Title(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Artist (const ET_File *ETFile1,
+                                            const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->artist == ((File_Tag *)ETFile2->FileTag->data)->artist))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->artist )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->artist )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->artist,((File_Tag 
*)ETFile2->FileTag->data)->artist);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Artist (const ET_File *ETFile1,
+                                             const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile2,ETFile1);
+}
+
+/*
+ * Comparison function for sorting by ascending album artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Album_Artist (const ET_File *ETFile1,
+                                                  const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->album_artist == ((File_Tag 
*)ETFile2->FileTag->data)->album_artist))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->album_artist )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->album_artist )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Artist(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album_artist,((File_Tag 
*)ETFile2->FileTag->data)->album_artist);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending album artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Album_Artist (const ET_File *ETFile1,
+                                                   const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Album_Artist(ETFile2,ETFile1);
+}
+
+/*
+ * Comparison function for sorting by ascending album.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Album (const ET_File *ETFile1,
+                                           const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->album == ((File_Tag *)ETFile2->FileTag->data)->album))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->album )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->album )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag *)ETFile2->FileTag->data)->album) 
== 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->album,((File_Tag 
*)ETFile2->FileTag->data)->album);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending album.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Album (const ET_File *ETFile1,
+                                            const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Album(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending year.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Year (const ET_File *ETFile1,
+                                          const ET_File *ETFile2)
+{
+    gint year1, year2;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->year )
+        year1 = 0;
+    else
+        year1 = atoi( ((File_Tag *)ETFile1->FileTag->data)->year );
+
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->year )
+        year2 = 0;
+    else
+        year2 = atoi( ((File_Tag *)ETFile2->FileTag->data)->year );
+
+    // Second criterion
+    if (year1 == year2)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (year1 - year2);
+}
+
+/*
+ * Comparison function for sorting by descending year.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Year (const ET_File *ETFile1,
+                                           const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Year(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending genre.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Genre (const ET_File *ETFile1,
+                                           const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->genre == ((File_Tag *)ETFile2->FileTag->data)->genre))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->genre ) return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->genre ) return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag *)ETFile2->FileTag->data)->genre) 
== 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->genre,((File_Tag 
*)ETFile2->FileTag->data)->genre);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending genre.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Genre (const ET_File *ETFile1,
+                                            const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Genre(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending comment.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Comment (const ET_File *ETFile1,
+                                             const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->comment == ((File_Tag *)ETFile2->FileTag->data)->comment))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->comment )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->comment )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->comment,((File_Tag 
*)ETFile2->FileTag->data)->comment);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending comment.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Comment (const ET_File *ETFile1,
+                                              const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Comment(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending composer.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Composer (const ET_File *ETFile1,
+                                              const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->composer == ((File_Tag *)ETFile2->FileTag->data)->composer))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->composer )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->composer )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->composer,((File_Tag 
*)ETFile2->FileTag->data)->composer);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending composer.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Composer (const ET_File *ETFile1,
+                                               const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Composer(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending original artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist (const ET_File *ETFile1,
+                                                 const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->orig_artist == ((File_Tag 
*)ETFile2->FileTag->data)->orig_artist))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->orig_artist )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->orig_artist )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->orig_artist,((File_Tag 
*)ETFile2->FileTag->data)->orig_artist);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending original artist.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Orig_Artist (const ET_File *ETFile1,
+                                                  const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending copyright.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Copyright (const ET_File *ETFile1,
+                                               const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->copyright == ((File_Tag *)ETFile2->FileTag->data)->copyright))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->copyright )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->copyright )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->copyright,((File_Tag 
*)ETFile2->FileTag->data)->copyright);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending copyright.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Copyright (const ET_File *ETFile1,
+                                                const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Copyright(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending URL.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Url (const ET_File *ETFile1,
+                                         const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->url == ((File_Tag *)ETFile2->FileTag->data)->url))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->url )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->url )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag *)ETFile2->FileTag->data)->url) == 
0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag 
*)ETFile2->FileTag->data)->url);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag *)ETFile2->FileTag->data)->url) 
== 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->url,((File_Tag 
*)ETFile2->FileTag->data)->url);
+    }
+}
+
+/*
+ * Comparison function for sorting by descending URL.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Url (const ET_File *ETFile1,
+                                          const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Url(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending encoded by.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_Encoded_By (const ET_File *ETFile1,
+                                                const ET_File *ETFile2)
+{
+   // Compare pointers just in case they are the same (e.g. both are NULL)
+   if ((ETFile1->FileTag->data == ETFile2->FileTag->data)
+   ||  (((File_Tag *)ETFile1->FileTag->data)->encoded_by == ((File_Tag 
*)ETFile2->FileTag->data)->encoded_by))
+        return 0;
+
+    if ( !ETFile1->FileTag->data || !((File_Tag *)ETFile1->FileTag->data)->encoded_by )
+        return -1;
+    if ( !ETFile2->FileTag->data || !((File_Tag *)ETFile2->FileTag->data)->encoded_by )
+        return 1;
+
+    if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+    {
+        if ( strcmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by);
+    }else
+    {
+        if ( strcasecmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by) == 0 )
+            // Second criterion
+            return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+        else
+            // First criterion
+            return strcasecmp(((File_Tag *)ETFile1->FileTag->data)->encoded_by,((File_Tag 
*)ETFile2->FileTag->data)->encoded_by);
+    }
+}
+
+/*
+ * Comparison function for sorting by descendingencoded by.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_Encoded_By (const ET_File *ETFile1,
+                                                 const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_Encoded_By(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending file type (mp3, ogg, ...).
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_File_Type (const ET_File *ETFile1,
+                                               const ET_File *ETFile2)
+{
+    if ( !ETFile1->ETFileDescription ) return -1;
+    if ( !ETFile2->ETFileDescription ) return 1;
+
+    // Second criterion
+    if (ETFile1->ETFileDescription->FileType == ETFile2->ETFileDescription->FileType)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (ETFile1->ETFileDescription->FileType - ETFile2->ETFileDescription->FileType);
+}
+
+/*
+ * Comparison function for sorting by descending file type (mp3, ogg, ...).
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_File_Type (const ET_File *ETFile1,
+                                                const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_File_Type(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending file size.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_File_Size (const ET_File *ETFile1,
+                                               const ET_File *ETFile2)
+{
+    if ( !ETFile1->ETFileInfo ) return -1;
+    if ( !ETFile2->ETFileInfo ) return 1;
+
+    // Second criterion
+    if (ETFile1->ETFileInfo->size == ETFile2->ETFileInfo->size)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (ETFile1->ETFileInfo->size - ETFile2->ETFileInfo->size);
+}
+
+/*
+ * Comparison function for sorting by descending file size.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_File_Size (const ET_File *ETFile1,
+                                                const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_File_Size(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending file duration.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_File_Duration (const ET_File *ETFile1,
+                                                   const ET_File *ETFile2)
+{
+    if ( !ETFile1->ETFileInfo ) return -1;
+    if ( !ETFile2->ETFileInfo ) return 1;
+
+    // Second criterion
+    if (ETFile1->ETFileInfo->duration == ETFile2->ETFileInfo->duration)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (ETFile1->ETFileInfo->duration - ETFile2->ETFileInfo->duration);
+}
+
+/*
+ * Comparison function for sorting by descending file duration.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_File_Duration (const ET_File *ETFile1,
+                                                    const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_File_Duration(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending file bitrate.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate (const ET_File *ETFile1,
+                                                  const ET_File *ETFile2)
+{
+    if ( !ETFile1->ETFileInfo ) return -1;
+    if ( !ETFile2->ETFileInfo ) return 1;
+
+    // Second criterion
+    if (ETFile1->ETFileInfo->bitrate == ETFile2->ETFileInfo->bitrate)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (ETFile1->ETFileInfo->bitrate - ETFile2->ETFileInfo->bitrate);
+}
+
+/*
+ * Comparison function for sorting by descending file bitrate.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_File_Bitrate (const ET_File *ETFile1,
+                                                   const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending file samplerate.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate (const ET_File *ETFile1,
+                                                     const ET_File *ETFile2)
+{
+    if ( !ETFile1->ETFileInfo ) return -1;
+    if ( !ETFile2->ETFileInfo ) return 1;
+
+    // Second criterion
+    if (ETFile1->ETFileInfo->samplerate == ETFile2->ETFileInfo->samplerate)
+        return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+
+    // First criterion
+    return (ETFile1->ETFileInfo->samplerate - ETFile2->ETFileInfo->samplerate);
+}
+
+/*
+ * Comparison function for sorting by descending file samplerate.
+ */
+gint
+ET_Comp_Func_Sort_File_By_Descending_File_Samplerate (const ET_File *ETFile1,
+                                                      const ET_File *ETFile2)
+{
+    return ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate(ETFile2,ETFile1);
+}
+
+
+/*
+ * Comparison function for sorting by ascending artist in the ArtistAlbumList.
+ */
+static gint
+ET_Comp_Func_Sort_Artist_Item_By_Ascending_Artist (const GList *AlbumList1,
+                                                   const GList *AlbumList2)
+{
+    const GList *etfilelist1 = NULL;
+    const GList *etfilelist2 = NULL;
+    const ET_File *etfile1 = NULL;
+    const ET_File *etfile2 = NULL;
+    const gchar *etfile1_artist;
+    const gchar *etfile2_artist;
+
+    if (!AlbumList1
+    || !(etfilelist1    = (GList *)AlbumList1->data)
+    || !(etfile1        = (ET_File *)etfilelist1->data)
+    || !(etfile1_artist = ((File_Tag *)etfile1->FileTag->data)->artist) )
+        return -1;
+
+    if (!AlbumList2
+    || !(etfilelist2    = (GList *)AlbumList2->data)
+    || !(etfile2        = (ET_File *)etfilelist2->data)
+    || !(etfile2_artist = ((File_Tag *)etfile2->FileTag->data)->artist) )
+        return 1;
+
+    /*if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+     *    return strcmp(etfile1_artist,etfile2_artist); */
+    //else
+        return strcasecmp(etfile1_artist,etfile2_artist);
+}
+
+/*
+ * Comparison function for sorting by ascending album in the ArtistAlbumList.
+ */
+static gint
+ET_Comp_Func_Sort_Album_Item_By_Ascending_Album (const GList *etfilelist1,
+                                                 const GList *etfilelist2)
+{
+    const ET_File *etfile1;
+    const ET_File *etfile2;
+    const gchar *etfile1_album;
+    const gchar *etfile2_album;
+
+    if (!etfilelist1
+    || !(etfile1        = (ET_File *)etfilelist1->data)
+    || !(etfile1_album  = ((File_Tag *)etfile1->FileTag->data)->album) )
+        return -1;
+
+    if (!etfilelist2
+    || !(etfile2        = (ET_File *)etfilelist2->data)
+    || !(etfile2_album  = ((File_Tag *)etfile2->FileTag->data)->album) )
+        return 1;
+
+    /*if (g_settings_get_boolean (MainSettings, "sort-case-sensitive"))
+     *    return strcmp(etfile1_album,etfile2_album); */
+    //else
+        return strcasecmp(etfile1_album,etfile2_album);
+}
+
+/*
+ * Comparison function for sorting etfile in the ArtistAlbumList.
+ * FIX ME : should use the default sorting!
+ */
+static gint
+ET_Comp_Func_Sort_Etfile_Item_By_Ascending_Filename (const ET_File *ETFile1,
+                                                     const ET_File *ETFile2)
+{
+
+    if (!ETFile1) return -1;
+    if (!ETFile2) return  1;
+
+    return ET_Comp_Func_Sort_File_By_Ascending_Filename(ETFile1,ETFile2);
+}
+
+
+
+
+/***************************
+ * List handling functions *
+ ***************************/
+
+/*
+ * Returns the first item of the "displayed list"
+ */
+GList *ET_Displayed_File_List_First (void)
+{
+    ETCore->ETFileDisplayedList = g_list_first(ETCore->ETFileDisplayedList);
+    return ETCore->ETFileDisplayedList;
+}
+
+/*
+ * Returns the previous item of the "displayed list". When no more item, it returns NULL.
+ */
+GList *ET_Displayed_File_List_Previous (void)
+{
+    if (ETCore->ETFileDisplayedList && ETCore->ETFileDisplayedList->prev)
+        return ETCore->ETFileDisplayedList = ETCore->ETFileDisplayedList->prev;
+    else
+        return NULL;
+}
+
+/*
+ * Returns the next item of the "displayed list".
+ * When no more item, it returns NULL to don't "overwrite" the list.
+ */
+GList *ET_Displayed_File_List_Next (void)
+{
+    if (ETCore->ETFileDisplayedList && ETCore->ETFileDisplayedList->next)
+        return ETCore->ETFileDisplayedList = ETCore->ETFileDisplayedList->next;
+    else
+        return NULL;
+}
+
+/*
+ * Returns the last item of the "displayed list"
+ */
+GList *ET_Displayed_File_List_Last (void)
+{
+    ETCore->ETFileDisplayedList = g_list_last(ETCore->ETFileDisplayedList);
+    return ETCore->ETFileDisplayedList;
+}
+
+/*
+ * Returns the item of the "displayed list" which correspond to the given 'ETFile' (used into browser list).
+ */
+GList *
+ET_Displayed_File_List_By_Etfile (const ET_File *ETFile)
+{
+    GList *etfilelist;
+
+    for (etfilelist = ET_Displayed_File_List_First (); etfilelist != NULL;
+         etfilelist = ET_Displayed_File_List_Next ())
+    {
+        if (ETFile == (ET_File *)etfilelist->data)
+            break;
+    }
+
+    if (etfilelist)
+    {
+        /* To "save" the position like in ET_File_List_Next... (not very good -
+         * FIXME) */
+        ETCore->ETFileDisplayedList = etfilelist;
+    }
+    return etfilelist;
+}
+
+/*
+ * Just returns the current item of the "main list"
+ */
+/*GList *ET_Displayed_File_List_Current (void)
+{
+    return ETCore->ETFileDisplayedList;
+    //return ETCore->ETFileDisplayedListPtr;
+}*/
+
+/*
+ * Renumber the list of displayed files (IndexKey) from 1 to n
+ */
+static void
+ET_Displayed_File_List_Number (void)
+{
+    GList *l = NULL;
+    guint i = 1;
+
+    for (l = g_list_first (ETCore->ETFileDisplayedList); l != NULL;
+         l = g_list_next (l))
+    {
+        ((ET_File *)l->data)->IndexKey = i++;
+    }
+}
+
+/*
+ * Returns the length of the list of displayed files
+ */
+static guint
+ET_Displayed_File_List_Get_Length (void)
+{
+    GList *list = NULL;
+
+    list = g_list_first(ETCore->ETFileDisplayedList);
+    ETCore->ETFileDisplayedList_Length = g_list_length(list);
+    return ETCore->ETFileDisplayedList_Length;
+}
+
+/*
+ * Load the list of displayed files (calculate length, size, ...)
+ * It contains part (filtrated : view by artists and albums) or full ETCore->ETFileList list
+ */
+gboolean ET_Set_Displayed_File_List (GList *ETFileList)
+{
+    GList *l = NULL;
+
+    ETCore->ETFileDisplayedList = g_list_first(ETFileList);
+
+    //ETCore->ETFileDisplayedListPtr = ETCore->ETFileDisplayedList;
+    ETCore->ETFileDisplayedList_Length = ET_Displayed_File_List_Get_Length();
+    ETCore->ETFileDisplayedList_TotalSize     = 0;
+    ETCore->ETFileDisplayedList_TotalDuration = 0;
+
+    // Get size and duration of files in the list
+    for (l = ETCore->ETFileDisplayedList; l != NULL; l = g_list_next (l))
+    {
+        ETCore->ETFileDisplayedList_TotalSize += ((ET_File_Info *)((ET_File *)l->data)->ETFileInfo)->size;
+        ETCore->ETFileDisplayedList_TotalDuration += ((ET_File_Info *)((ET_File 
*)l->data)->ETFileInfo)->duration;
+    }
+
+    /* Sort the file list. */
+    ET_Sort_Displayed_File_List (g_settings_get_enum (MainSettings,
+                                 "sort-mode"));
+
+    // Should renums ETCore->ETFileDisplayedList only!
+    ET_Displayed_File_List_Number();
+
+    return TRUE;
+}
+
+
+
+/*********************
+ * Freeing functions *
+ *********************/
+
+/*
+ * Frees one item of the full main list of files.
+ */
+void
+ET_Free_File_List_Item (ET_File *ETFile)
+{
+    if (ETFile)
+    {
+        /* Frees the lists */
+        if (ETFile->FileNameList)
+        {
+            ET_Free_File_Name_List(ETFile->FileNameList);
+        }
+        if (ETFile->FileNameListBak)
+        {
+            ET_Free_File_Name_List(ETFile->FileNameListBak);
+        }
+        if (ETFile->FileTagList)
+        {
+            ET_Free_File_Tag_List (ETFile->FileTagList);
+        }
+        if (ETFile->FileTagListBak)
+        {
+            ET_Free_File_Tag_List (ETFile->FileTagListBak);
+        }
+        /* Frees infos of ETFileInfo */
+        if (ETFile->ETFileInfo)
+        {
+            ET_Free_File_Info_Item (ETFile->ETFileInfo);
+        }
+
+        g_free(ETFile->ETFileExtension);
+        g_slice_free (ET_File, ETFile);
+    }
+}
+
+
+/*
+ * Frees the full list: GList *FileNameList.
+ */
+static gboolean
+ET_Free_File_Name_List (GList *FileNameList)
+{
+    g_return_val_if_fail (FileNameList != NULL, FALSE);
+
+    FileNameList = g_list_first (FileNameList);
+
+    g_list_free_full (FileNameList, (GDestroyNotify)ET_Free_File_Name_Item);
+
+    return TRUE;
+}
+
+
+/*
+ * Frees a File_Name item.
+ */
+static void
+ET_Free_File_Name_Item (File_Name *FileName)
+{
+    g_return_if_fail (FileName != NULL);
+
+    g_free(FileName->value);
+    g_free(FileName->value_utf8);
+    g_free(FileName->value_ck);
+    g_slice_free (File_Name, FileName);
+}
+
+
+/*
+ * Frees the full list: GList *TagList.
+ */
+static gboolean
+ET_Free_File_Tag_List (GList *FileTagList)
+{
+    GList *l;
+
+    g_return_val_if_fail (FileTagList != NULL, FALSE);
+
+    FileTagList = g_list_first (FileTagList);
+
+    for (l = FileTagList; l != NULL; l = g_list_next (l))
+    {
+        if ((File_Tag *)l->data)
+            ET_Free_File_Tag_Item ((File_Tag *)l->data);
+    }
+
+    g_list_free (FileTagList);
+
+    return TRUE;
+}
+
+
+/*
+ * Frees a File_Info item.
+ */
+static gboolean
+ET_Free_File_Info_Item (ET_File_Info *ETFileInfo)
+{
+    g_return_val_if_fail (ETFileInfo != NULL, FALSE);
+
+    g_free(ETFileInfo->mpc_profile);
+    g_free(ETFileInfo->mpc_version);
+
+    g_slice_free (ET_File_Info, ETFileInfo);
+    return TRUE;
+}
+
+
+/*********************
+ * Copying functions *
+ *********************/
+
+/*
+ * 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"
+ */
+gboolean
+ET_Set_Filename_File_Name_Item (File_Name *FileName,
+                                const gchar *filename_utf8,
+                                const gchar *filename)
+{
+    g_return_val_if_fail (FileName != NULL, FALSE);
+
+    if (filename_utf8 && filename)
+    {
+        FileName->value_utf8 = g_strdup(filename_utf8);
+        FileName->value      = g_strdup(filename);
+        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+    }else if (filename_utf8)
+    {
+        FileName->value_utf8 = g_strdup(filename_utf8);
+        FileName->value      = filename_from_display(filename_utf8);
+        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+    }else if (filename)
+    {
+        FileName->value_utf8 = filename_to_display(filename);;
+        FileName->value      = g_strdup(filename);
+        FileName->value_ck   = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+    }else
+    {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/************************
+ * Displaying functions *
+ ************************/
+
+static void
+et_file_header_fields_free (EtFileHeaderFields *fields)
+{
+    g_free (fields->version);
+    g_free (fields->bitrate);
+    g_free (fields->samplerate);
+    g_free (fields->mode);
+    g_free (fields->size);
+    g_free (fields->duration);
+    g_slice_free (EtFileHeaderFields, fields);
+}
+
+/*
+ * Display information of the file (Position + Header + Tag) to the user interface.
+ * Before doing it, it saves data of the file currently displayed
+ */
+void
+ET_Display_File_Data_To_UI (ET_File *ETFile)
+{
+    EtApplicationWindow *window;
+    const ET_File_Description *ETFileDescription;
+    const gchar *cur_filename_utf8;
+    gchar *msg;
+    EtFileHeaderFields *fields;
+
+    g_return_if_fail (ETFile != NULL &&
+                      ((GList *)ETFile->FileNameCur)->data != NULL);
+                      /* For the case where ETFile is an "empty" structure. */
+
+    cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
+    ETFileDescription = ETFile->ETFileDescription;
+
+    /* Save the current displayed file */
+    ETCore->ETFileDisplayed = ETFile;
+
+    window = ET_APPLICATION_WINDOW (MainWindow);
+
+    /* Display position in list + show/hide icon if file writable/read_only (cur_filename) */
+    et_application_window_file_area_set_file_fields (window, ETFile);
+
+    /* Display filename (and his path) (value in FileNameNew) */
+    ET_Display_Filename_To_UI(ETFile);
+
+    /* Display tag data */
+    et_application_window_tag_area_display_et_file (window, ETFile);
+
+    /* Display controls in tag area */
+    et_application_window_tag_area_display_controls (window, ETFile);
+
+    /* Display file data, header data and file type */
+    switch (ETFileDescription->FileType)
+    {
+#if defined ENABLE_MP3 && defined ENABLE_ID3LIB
+        case MP3_FILE:
+        case MP2_FILE:
+            fields = et_mpeg_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_mpeg_file_header_fields_free (fields);
+            break;
+#endif
+#ifdef ENABLE_OGG
+        case OGG_FILE:
+            fields = et_ogg_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_ogg_file_header_fields_free (fields);
+            break;
+#endif
+#ifdef ENABLE_SPEEX
+        case SPEEX_FILE:
+            fields = et_ogg_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_ogg_file_header_fields_free (fields);
+            break;
+#endif
+#ifdef ENABLE_FLAC
+        case FLAC_FILE:
+            fields = et_flac_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_flac_file_header_fields_free (fields);
+            break;
+#endif
+        case MPC_FILE:
+            fields = et_mpc_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_mpc_file_header_fields_free (fields);
+            break;
+        case MAC_FILE:
+            fields = et_mac_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_mac_file_header_fields_free (fields);
+            break;
+#ifdef ENABLE_MP4
+        case MP4_FILE:
+            fields = et_mp4_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_mp4_file_header_fields_free (fields);
+            break;
+#endif
+#ifdef ENABLE_WAVPACK
+        case WAVPACK_FILE:
+            fields = et_wavpack_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_wavpack_file_header_fields_free (fields);
+            break;
+#endif
+#ifdef ENABLE_OPUS
+        case OPUS_FILE:
+            fields = et_opus_header_display_file_info_to_ui (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_opus_file_header_fields_free (fields);
+            break;
+#endif
+        case UNKNOWN_FILE:
+        default:
+            /* Default displaying. */
+            fields = ET_Display_File_Info_To_UI (ETFile);
+            et_application_window_file_area_set_header_fields (window, fields);
+            et_file_header_fields_free (fields);
+            Log_Print (LOG_ERROR,
+                       "ETFileInfo: Undefined file type %d for file %s.",
+                       ETFileDescription->FileType, cur_filename_utf8);
+            break;
+    }
+
+    msg = g_strdup_printf (_("File: ‘%s’"), cur_filename_utf8);
+    et_application_window_status_bar_message (window, msg, FALSE);
+    g_free (msg);
+}
+
+static void
+ET_Display_Filename_To_UI (const ET_File *ETFile)
+{
+    const gchar *new_filename_utf8;
+    gchar *dirname_utf8;
+    gchar *text;
+
+    g_return_if_fail (ETFile != NULL);
+
+    new_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameNew)->data)->value_utf8;
+
+    /*
+     * Set the path to the file into BrowserEntry (dirbrowser)
+     */
+    dirname_utf8 = g_path_get_dirname(new_filename_utf8);
+    et_application_window_browser_entry_set_text (ET_APPLICATION_WINDOW (MainWindow),
+                                                  dirname_utf8);
+
+    // And refresh the number of files in this directory
+    text = g_strdup_printf(ngettext("One file","%u 
files",ET_Get_Number_Of_Files_In_Directory(dirname_utf8)),ET_Get_Number_Of_Files_In_Directory(dirname_utf8));
+    et_application_window_browser_label_set_text (ET_APPLICATION_WINDOW (MainWindow),
+                                                  text);
+    g_free(dirname_utf8);
+    g_free(text);
+}
+
+
+/*
+ * "Default" way to display File Info to the user interface.
+ */
+static EtFileHeaderFields *
+ET_Display_File_Info_To_UI (const ET_File *ETFile)
+{
+    EtFileHeaderFields *fields;
+    ET_File_Info *info;
+    gchar *time  = NULL;
+    gchar *time1 = NULL;
+    gchar *size  = NULL;
+    gchar *size1 = NULL;
+
+    info = ETFile->ETFileInfo;
+    fields = g_slice_new (EtFileHeaderFields);
+
+    fields->description = _("File");
+
+    /* MPEG, Layer versions */
+    fields->version = g_strdup_printf ("%d, Layer %d", info->version,
+                                       info->layer);
+
+    /* Bitrate */
+    fields->bitrate = g_strdup_printf (_("%d kb/s"), info->bitrate);
+
+    /* Samplerate */
+    fields->samplerate = g_strdup_printf (_("%d Hz"), info->samplerate);
+
+    /* Mode */
+    fields->mode = g_strdup_printf ("%d", info->mode);
+
+    /* Size */
+    size = g_format_size (info->size);
+    size1 = g_format_size (ETCore->ETFileDisplayedList_TotalSize);
+    fields->size = g_strdup_printf ("%s (%s)", size, size1);
+    g_free (size);
+    g_free (size1);
+
+    /* Duration */
+    time = Convert_Duration (info->duration);
+    time1 = Convert_Duration (ETCore->ETFileDisplayedList_TotalDuration);
+    fields->duration = g_strdup_printf ("%s (%s)", time, time1);
+    g_free (time);
+    g_free (time1);
+
+    return fields;
+}
+
+/********************
+ * Saving functions *
+ ********************/
+
+/*
+ * Save information of the file, contained into the entries of the user interface, in the list.
+ * An undo key is generated to be used for filename and tag if there are changed is the same time.
+ * Filename and Tag.
+ */
+void ET_Save_File_Data_From_UI (ET_File *ETFile)
+{
+    const ET_File_Description *ETFileDescription;
+    File_Name *FileName;
+    File_Tag  *FileTag;
+    guint      undo_key;
+    const gchar *cur_filename_utf8;
+
+    g_return_if_fail (ETFile != NULL && ETFile->FileNameCur != NULL
+                      && ETFile->FileNameCur->data != NULL);
+
+    cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
+    ETFileDescription = ETFile->ETFileDescription;
+    undo_key = ET_Undo_Key_New();
+
+
+    /*
+     * Save filename and generate undo for filename
+     */
+    FileName = g_slice_new (File_Name);
+    ET_Initialize_File_Name_Item (FileName);
+    FileName->key = undo_key;
+    ET_Save_File_Name_From_UI(ETFile,FileName); // Used for all files!
+
+    switch (ETFileDescription->TagType)
+    {
+#ifdef ENABLE_MP3
+        case ID3_TAG:
+#endif
+#ifdef ENABLE_OGG
+        case OGG_TAG:
+#endif
+#ifdef ENABLE_FLAC
+        case FLAC_TAG:
+#endif
+#ifdef ENABLE_MP4
+        case MP4_TAG:
+#endif
+#ifdef ENABLE_WAVPACK
+        case WAVPACK_TAG:
+#endif
+#ifdef ENABLE_OPUS
+        case OPUS_TAG:
+#endif
+        case APE_TAG:
+            FileTag = et_application_window_tag_area_create_file_tag (ET_APPLICATION_WINDOW (MainWindow));
+            ET_Copy_File_Tag_Item_Other_Field (ETFile, FileTag);
+            break;
+        case UNKNOWN_TAG:
+        default:
+            FileTag = ET_File_Tag_Item_New ();
+            Log_Print(LOG_ERROR,"FileTag: Undefined tag type %d for file 
%s.",ETFileDescription->TagType,cur_filename_utf8);
+            break;
+    }
+
+    /*
+     * Generate undo for the file and the main undo list.
+     * If no changes detected, FileName and FileTag item are deleted.
+     */
+    ET_Manage_Changes_Of_File_Data(ETFile,FileName,FileTag);
+
+    /* Refresh file into browser list */
+    et_application_window_browser_refresh_file_in_list (ET_APPLICATION_WINDOW (MainWindow),
+                                                        ETFile);
+}
+
+
+/*
+ * Save displayed filename into list if it had been changed. Generates also an history list for undo/redo.
+ *  - ETFile : the current etfile that we want to save,
+ *  - FileName : where is 'temporary' saved the new filename.
+ *
+ * Note : it builds new filename (with path) from strings encoded into file system
+ *        encoding, not UTF-8 (it preserves file system encoding of parent directories).
+ */
+static gboolean
+ET_Save_File_Name_From_UI (const ET_File *ETFile, File_Name *FileName)
+{
+    gchar *filename_new = NULL;
+    gchar *dirname = NULL;
+    gchar *filename;
+    const gchar *filename_utf8;
+    gchar *extension;
+
+    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
+
+    filename_utf8 = et_application_window_file_area_get_filename (ET_APPLICATION_WINDOW (MainWindow));
+    filename = filename_from_display (filename_utf8);
+
+    if (!filename)
+    {
+        // If translation fails...
+        GtkWidget *msgdialog;
+        gchar *filename_escaped_utf8 = g_strescape(filename_utf8, NULL);
+        msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
+                                           GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                           GTK_MESSAGE_ERROR,
+                                           GTK_BUTTONS_CLOSE,
+                                           _("Could not convert filename ‘%s’ to system filename encoding"),
+                                           filename_escaped_utf8);
+        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(msgdialog),_("Try setting the 
environment variable G_FILENAME_ENCODING."));
+        gtk_window_set_title(GTK_WINDOW(msgdialog), _("Filename translation"));
+
+        gtk_dialog_run(GTK_DIALOG(msgdialog));
+        gtk_widget_destroy(msgdialog);
+        g_free(filename_escaped_utf8);
+        return FALSE;
+    }
+
+    // Get the current path to the file
+    dirname = g_path_get_dirname( ((File_Name *)ETFile->FileNameNew->data)->value );
+
+    // Convert filename extension (lower or upper)
+    extension = ET_File_Name_Format_Extension(ETFile);
+
+    // Check length of filename (limit ~255 characters)
+    //ET_File_Name_Check_Length(ETFile,filename);
+
+    // Filename (in file system encoding!)
+    if (filename && strlen(filename)>0)
+    {
+        // Regenerate the new filename (without path)
+        filename_new = g_strconcat(filename,extension,NULL);
+    }else
+    {
+        // Keep the 'last' filename (if a 'blank' filename was entered in the fileentry for ex)...
+        filename_new = g_path_get_basename( ((File_Name *)ETFile->FileNameNew->data)->value );
+    }
+    g_free (filename);
+    g_free (extension);
+
+    // Check if new filename seems to be correct
+    if ( !filename_new || strlen(filename_new) <= strlen(ETFile->ETFileDescription->Extension) )
+    {
+        FileName->value      = NULL;
+        FileName->value_utf8 = NULL;
+        FileName->value_ck   = NULL;
+
+        g_free(filename_new);
+        g_free(dirname);
+        return FALSE;
+    }
+
+    // Convert the illegal characters
+    ET_File_Name_Convert_Character(filename_new); // FIX ME : should be in UTF8?
+
+    /* Set the new filename (in file system encoding). */
+    FileName->value = g_strconcat(dirname,G_DIR_SEPARATOR_S,filename_new,NULL);
+    /* Set the new filename (in UTF-8 encoding). */
+    FileName->value_utf8 = filename_to_display(FileName->value);
+    // Calculates collate key
+    FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+
+    g_free(filename_new);
+    g_free(dirname);
+    return TRUE;
+}
+
+
+/*
+ * Do the same thing of ET_Save_File_Name_From_UI, but without getting the
+ * data from the UI.
+ */
+static gboolean
+ET_Save_File_Name_Internal (const ET_File *ETFile,
+                            File_Name *FileName)
+{
+    gchar *filename_new = NULL;
+    gchar *dirname = NULL;
+    gchar *filename;
+    gchar *extension;
+    gchar *pos;
+
+    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
+
+    // Get the current path to the file
+    dirname = g_path_get_dirname( ((File_Name *)ETFile->FileNameNew->data)->value );
+
+    // Get the name of file (and rebuild it with extension with a 'correct' case)
+    filename = g_path_get_basename( ((File_Name *)ETFile->FileNameNew->data)->value );
+
+    // Remove the extension
+    if ((pos=strrchr(filename, '.'))!=NULL)
+        *pos = 0;
+
+    // Convert filename extension (lower/upper)
+    extension = ET_File_Name_Format_Extension(ETFile);
+
+    // Check length of filename
+    //ET_File_Name_Check_Length(ETFile,filename);
+
+    // Regenerate the new filename (without path)
+    filename_new = g_strconcat(filename,extension,NULL);
+    g_free(extension);
+    g_free(filename);
+
+    // Check if new filename seems to be correct
+    if (filename_new)
+    {
+        // Convert the illegal characters
+        ET_File_Name_Convert_Character(filename_new);
+
+        /* Set the new filename (in file system encoding). */
+        FileName->value = g_strconcat(dirname,G_DIR_SEPARATOR_S,filename_new,NULL);
+        /* Set the new filename (in UTF-8 encoding). */
+        FileName->value_utf8 = filename_to_display(FileName->value);
+        // Calculate collate key
+        FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+
+        g_free(filename_new);
+        g_free(dirname);
+        return TRUE;
+    }else
+    {
+        FileName->value = NULL;
+        FileName->value_utf8 = NULL;
+        FileName->value_ck = NULL;
+
+        g_free(filename_new);
+        g_free(dirname);
+        return FALSE;
+    }
+}
+
+/*
+ * Do the same thing of et_tag_area_create_file_tag without getting the data from the UI.
+ */
+static gboolean
+ET_Save_File_Tag_Internal (ET_File *ETFile, File_Tag *FileTag)
+{
+    File_Tag *FileTagCur;
+
+
+    g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL
+                          && FileTag != NULL, FALSE);
+
+    FileTagCur = (File_Tag *)ETFile->FileTag->data;
+
+    /* Title */
+    if ( FileTagCur->title && g_utf8_strlen(FileTagCur->title, -1)>0 )
+    {
+        FileTag->title = g_strdup(FileTagCur->title);
+        g_strstrip (FileTag->title);
+    } else
+    {
+        FileTag->title = NULL;
+    }
+
+    /* Artist */
+    if ( FileTagCur->artist && g_utf8_strlen(FileTagCur->artist, -1)>0 )
+    {
+        FileTag->artist = g_strdup(FileTagCur->artist);
+        g_strstrip (FileTag->artist);
+    } else
+    {
+        FileTag->artist = NULL;
+    }
+
+       /* Album Artist */
+    if ( FileTagCur->album_artist && g_utf8_strlen(FileTagCur->album_artist, -1)>0 )
+    {
+        FileTag->album_artist = g_strdup(FileTagCur->album_artist);
+        g_strstrip (FileTag->album_artist);
+    } else
+    {
+        FileTag->album_artist = NULL;
+    }
+
+
+    /* Album */
+    if ( FileTagCur->album && g_utf8_strlen(FileTagCur->album, -1)>0 )
+    {
+        FileTag->album = g_strdup(FileTagCur->album);
+        g_strstrip (FileTag->album);
+    } else
+    {
+        FileTag->album = NULL;
+    }
+
+
+    /* Disc Number */
+    if ( FileTagCur->disc_number && g_utf8_strlen(FileTagCur->disc_number, -1)>0 )
+    {
+        FileTag->disc_number = g_strdup(FileTagCur->disc_number);
+        g_strstrip (FileTag->disc_number);
+    } else
+    {
+        FileTag->disc_number = NULL;
+    }
+
+
+    /* Discs Total */
+    if (FileTagCur->disc_total
+        && g_utf8_strlen (FileTagCur->disc_total, -1) > 0)
+    {
+        FileTag->disc_total = et_disc_number_to_string (atoi (FileTagCur->disc_total));
+        g_strstrip (FileTag->disc_total);
+    }
+    else
+    {
+        FileTag->disc_total = NULL;
+    }
+
+
+    /* Year */
+    if ( FileTagCur->year && g_utf8_strlen(FileTagCur->year, -1)>0 )
+    {
+        FileTag->year = g_strdup(FileTagCur->year);
+        g_strstrip (FileTag->year);
+    } else
+    {
+        FileTag->year = NULL;
+    }
+
+
+    /* Track */
+    if ( FileTagCur->track && g_utf8_strlen(FileTagCur->track, -1)>0 )
+    {
+        gchar *tmp_str;
+
+        FileTag->track = et_track_number_to_string (atoi (FileTagCur->track));
+
+        /* This field must contain only digits. */
+        tmp_str = FileTag->track;
+        while (g_ascii_isdigit (*tmp_str)) tmp_str++;
+            *tmp_str = 0;
+        g_strstrip (FileTag->track);
+    } else
+    {
+        FileTag->track = NULL;
+    }
+
+
+    /* Track Total */
+    if ( FileTagCur->track_total && g_utf8_strlen(FileTagCur->track_total, -1)>0 )
+    {
+        FileTag->track_total = et_track_number_to_string (atoi (FileTagCur->track_total));
+        g_strstrip (FileTag->track_total);
+    } else
+    {
+        FileTag->track_total = NULL;
+    }
+
+
+    /* Genre */
+    if ( FileTagCur->genre && g_utf8_strlen(FileTagCur->genre, -1)>0 )
+    {
+        FileTag->genre = g_strdup(FileTagCur->genre);
+        g_strstrip (FileTag->genre);
+    } else
+    {
+        FileTag->genre = NULL;
+    }
+
+
+    /* Comment */
+    if ( FileTagCur->comment && g_utf8_strlen(FileTagCur->comment, -1)>0 )
+    {
+        FileTag->comment = g_strdup(FileTagCur->comment);
+        g_strstrip (FileTag->comment);
+    } else
+    {
+        FileTag->comment = NULL;
+    }
+
+
+    /* Composer */
+    if ( FileTagCur->composer && g_utf8_strlen(FileTagCur->composer, -1)>0 )
+    {
+        FileTag->composer = g_strdup(FileTagCur->composer);
+        g_strstrip (FileTag->composer);
+    } else
+    {
+        FileTag->composer = NULL;
+    }
+
+
+    /* Original Artist */
+    if ( FileTagCur->orig_artist && g_utf8_strlen(FileTagCur->orig_artist, -1)>0 )
+    {
+        FileTag->orig_artist = g_strdup(FileTagCur->orig_artist);
+        g_strstrip (FileTag->orig_artist);
+    } else
+    {
+        FileTag->orig_artist = NULL;
+    }
+
+
+    /* Copyright */
+    if ( FileTagCur->copyright && g_utf8_strlen(FileTagCur->copyright, -1)>0 )
+    {
+        FileTag->copyright = g_strdup(FileTagCur->copyright);
+        g_strstrip (FileTag->copyright);
+    } else
+    {
+        FileTag->copyright = NULL;
+    }
+
+
+    /* URL */
+    if ( FileTagCur->url && g_utf8_strlen(FileTagCur->url, -1)>0 )
+    {
+        FileTag->url = g_strdup(FileTagCur->url);
+        g_strstrip (FileTag->url);
+    } else
+    {
+        FileTag->url = NULL;
+    }
+
+
+    /* Encoded by */
+    if ( FileTagCur->encoded_by && g_utf8_strlen(FileTagCur->encoded_by, -1)>0 )
+    {
+        FileTag->encoded_by = g_strdup(FileTagCur->encoded_by);
+        g_strstrip (FileTag->encoded_by);
+    } else
+    {
+        FileTag->encoded_by = NULL;
+    }
+
+
+    /* Picture */
+    et_file_tag_set_picture (FileTag, FileTagCur->picture);
+
+    return TRUE;
+}
+
+
+/*
+ * Save data contained into File_Tag structure to the file on hard disk.
+ */
+gboolean
+ET_Save_File_Tag_To_HD (ET_File *ETFile, GError **error)
+{
+    const ET_File_Description *ETFileDescription;
+    const gchar *cur_filename;
+    const gchar *cur_filename_utf8;
+    gboolean state;
+    GFile *file;
+    GFileInfo *fileinfo;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+    cur_filename = ((File_Name *)(ETFile->FileNameCur)->data)->value;
+    cur_filename_utf8 = ((File_Name *)(ETFile->FileNameCur)->data)->value_utf8;
+
+    ETFileDescription = ETFile->ETFileDescription;
+
+    /* Store the file timestamps (in case they are to be preserved) */
+    file = g_file_new_for_path (cur_filename);
+    fileinfo = g_file_query_info (file, "time::*", G_FILE_QUERY_INFO_NONE,
+                                  NULL, NULL);
+
+    switch (ETFileDescription->TagType)
+    {
+#ifdef ENABLE_MP3
+        case ID3_TAG:
+            state = id3tag_write_file_tag (ETFile, error);
+            break;
+#endif
+#ifdef ENABLE_OGG
+        case OGG_TAG:
+            state = ogg_tag_write_file_tag (ETFile, error);
+            break;
+#endif
+#ifdef ENABLE_FLAC
+        case FLAC_TAG:
+            state = flac_tag_write_file_tag (ETFile, error);
+            break;
+#endif
+        case APE_TAG:
+            state = ape_tag_write_file_tag (ETFile, error);
+            break;
+#ifdef ENABLE_MP4
+        case MP4_TAG:
+            state = mp4tag_write_file_tag (ETFile, error);
+            break;
+#endif
+#ifdef ENABLE_WAVPACK
+        case WAVPACK_TAG:
+            state = wavpack_tag_write_file_tag (ETFile, error);
+            break;
+#endif
+#ifdef ENABLE_OPUS
+        case OPUS_TAG:
+            state = ogg_tag_write_file_tag (ETFile, error);
+            break;
+#endif
+        case UNKNOWN_TAG:
+        default:
+            Log_Print(LOG_ERROR,"Saving to HD: Undefined function for tag type '%d' (file %s).",
+                ETFileDescription->TagType,cur_filename_utf8);
+            state = FALSE;
+            break;
+    }
+
+    /* Update properties for the file. */
+    if (fileinfo)
+    {
+        if (g_settings_get_boolean (MainSettings,
+                                    "file-preserve-modification-time"))
+        {
+            g_file_set_attributes_from_info (file, fileinfo,
+                                             G_FILE_QUERY_INFO_NONE,
+                                             NULL, NULL);
+        }
+
+        g_object_unref (fileinfo);
+    }
+
+    /* Update the stored file modification time to prevent EasyTAG from warning
+     * that an external program has changed the file. */
+    fileinfo = g_file_query_info (file,
+                                  G_FILE_ATTRIBUTE_TIME_MODIFIED,
+                                  G_FILE_QUERY_INFO_NONE, NULL, NULL);
+
+    if (fileinfo)
+    {
+        ETFile->FileModificationTime = g_file_info_get_attribute_uint64 (fileinfo,
+                                                                         G_FILE_ATTRIBUTE_TIME_MODIFIED);
+        g_object_unref (fileinfo);
+    }
+
+    g_object_unref (file);
+
+    if (state==TRUE)
+    {
+
+        /* Update date and time of the parent directory of the file after
+         * changing the tag value (ex: needed for Amarok for refreshing). Note
+         * that when renaming a file the parent directory is automatically
+         * updated.
+         */
+        if (g_settings_get_boolean (MainSettings,
+                                    "file-update-parent-modification-time"))
+        {
+            gchar *path = g_path_get_dirname (cur_filename);
+            utime (path, NULL);
+            g_free (path);
+        }
+
+        ET_Mark_File_Tag_As_Saved(ETFile);
+        return TRUE;
+    }
+    else
+    {
+        g_assert (error == NULL || *error != NULL);
+
+        return FALSE;
+    }
+}
+
+/*
+ * Function used to update path of filenames into list after renaming a parent directory
+ * (for ex: "/mp3/old_path/file.mp3" to "/mp3/new_path/file.mp3"
+ */
+void
+ET_Update_Directory_Name_Into_File_List (const gchar *last_path,
+                                         const gchar *new_path)
+{
+    GList *filelist;
+    ET_File *file;
+    GList *filenamelist;
+    gchar *filename;
+    gchar *last_path_tmp;
+
+    if (!ETCore->ETFileList || !last_path || !new_path ||
+        strlen(last_path) < 1 || strlen(new_path) < 1 )
+        return;
+
+    // Add '/' to end of path to avoid ambiguity between a directory and a filename...
+    if (last_path[strlen(last_path)-1]==G_DIR_SEPARATOR)
+        last_path_tmp = g_strdup(last_path);
+    else
+        last_path_tmp = g_strconcat(last_path,G_DIR_SEPARATOR_S,NULL);
+
+    for (filelist = g_list_first (ETCore->ETFileList); filelist != NULL;
+         filelist = g_list_next (filelist))
+    {
+        if ((file = filelist->data))
+        {
+            for (filenamelist = file->FileNameList; filenamelist != NULL;
+                 filenamelist = g_list_next (filenamelist))
+            {
+                File_Name *FileName = (File_Name *)filenamelist->data;
+
+                if ( FileName && (filename=FileName->value) )
+                {
+                    // Replace path of filename
+                    if ( strncmp(filename,last_path_tmp,strlen(last_path_tmp))==0 )
+                    {
+                        gchar *filename_tmp;
+
+                        // Create the new filename
+                        filename_tmp = g_strconcat(new_path,
+                                                   (new_path[strlen(new_path)-1]==G_DIR_SEPARATOR) ? "" : 
G_DIR_SEPARATOR_S,
+                                                   &filename[strlen(last_path_tmp)],NULL);
+
+                        /* Replace the filename (in file system encoding). */
+                        g_free(FileName->value);
+                        FileName->value = filename_tmp;
+                        /* Replace the filename (in file system encoding). */
+                        g_free(FileName->value_utf8);
+                        FileName->value_utf8 = filename_to_display(FileName->value);
+                        // Recalculate the collate key
+                        g_free(FileName->value_ck);
+                        FileName->value_ck = g_utf8_collate_key_for_filename(FileName->value_utf8, -1);
+                    }
+                }
+             }
+        }
+    }
+
+    g_free(last_path_tmp);
+}
+
+
+
+/***********************
+ * Undo/Redo functions *
+ ***********************/
+
+/*
+ * Check if 'FileName' and 'FileTag' differ with those of 'ETFile'.
+ * Manage undo feature for the ETFile and the main undo list.
+ */
+gboolean ET_Manage_Changes_Of_File_Data (ET_File *ETFile, File_Name *FileName, File_Tag *FileTag)
+{
+    gboolean undo_added = FALSE;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    /*
+     * Detect changes of filename and generate the filename undo list
+     */
+    if (FileName)
+    {
+        if ( ETFile->FileNameNew && ET_Detect_Changes_Of_File_Name( (File_Name 
*)(ETFile->FileNameNew)->data,FileName )==TRUE )
+        {
+            ET_Add_File_Name_To_List(ETFile,FileName);
+            undo_added |= TRUE;
+        }else
+        {
+            ET_Free_File_Name_Item(FileName);
+        }
+    }
+
+    /*
+     * Detect changes in tag data and generate the tag undo list
+     */
+    if (FileTag)
+    {
+        if ( ETFile->FileTag && ET_Detect_Changes_Of_File_Tag( (File_Tag *)(ETFile->FileTag)->data,FileTag 
)==TRUE )
+        {
+            ET_Add_File_Tag_To_List(ETFile,FileTag);
+            undo_added |= TRUE;
+        }else
+        {
+            ET_Free_File_Tag_Item(FileTag);
+        }
+    }
+
+    /*
+     * Generate main undo (file history of modifications)
+     */
+    if (undo_added)
+        ET_Add_File_To_History_List(ETFile);
+
+    //return TRUE;
+    return undo_added;
+}
+
+
+/*
+ * Compares two File_Name items :
+ *  - returns TRUE if there aren't the same
+ *  - else returns FALSE
+ */
+static gboolean
+ET_Detect_Changes_Of_File_Name (const File_Name *FileName1,
+                                const File_Name *FileName2)
+{
+    const gchar *filename1_ck;
+    const gchar *filename2_ck;
+
+    if (!FileName1 && !FileName2) return FALSE;
+    if (FileName1 && !FileName2) return TRUE;
+    if (!FileName1 && FileName2) return TRUE;
+
+    /* Both FileName1 and FileName2 are != NULL. */
+    if (!FileName1->value && !FileName2->value) return FALSE;
+    if (FileName1->value && !FileName2->value) return TRUE;
+    if (!FileName1->value && FileName2->value) return TRUE;
+
+    /* Compare collate keys (with FileName->value converted to UTF-8 as it
+     * contains raw data). */
+    filename1_ck = FileName1->value_ck;
+    filename2_ck = FileName2->value_ck;
+
+    /* Filename changed ? (we check path + file). */
+    if (strcmp (filename1_ck, filename2_ck) != 0)
+    {
+        return TRUE;
+    }
+    else
+    {
+        return FALSE;
+    }
+}
+
+/*
+ * Add a FileName item to the history list of ETFile
+ */
+static gboolean
+ET_Add_File_Name_To_List (ET_File *ETFile, File_Name *FileName)
+{
+    GList *cut_list = NULL;
+
+    g_return_val_if_fail (ETFile != NULL && FileName != NULL, FALSE);
+
+    /* How it works : Cut the FileNameList list after the current item,
+     * and appends it to the FileNameListBak list for saving the data.
+     * Then appends the new item to the FileNameList list */
+    if (ETFile->FileNameList)
+    {
+        cut_list = ETFile->FileNameNew->next; // Cut after the current item...
+        ETFile->FileNameNew->next = NULL;
+    }
+    if (cut_list)
+        cut_list->prev = NULL;
+
+    /* Add the new item to the list */
+    ETFile->FileNameList = g_list_append(ETFile->FileNameList,FileName);
+    /* Set the current item to use */
+    ETFile->FileNameNew  = g_list_last(ETFile->FileNameList);
+    /* Backup list */
+    /* FIX ME! Keep only the saved item */
+    ETFile->FileNameListBak = g_list_concat(ETFile->FileNameListBak,cut_list);
+
+    return TRUE;
+}
+
+/*
+ * Add a FileTag item to the history list of ETFile
+ */
+static gboolean
+ET_Add_File_Tag_To_List (ET_File *ETFile, File_Tag *FileTag)
+{
+    GList *cut_list = NULL;
+
+    g_return_val_if_fail (ETFile != NULL && FileTag != NULL, FALSE);
+
+    if (ETFile->FileTag)
+    {
+        cut_list = ETFile->FileTag->next; // Cut after the current item...
+        ETFile->FileTag->next = NULL;
+    }
+    if (cut_list)
+        cut_list->prev = NULL;
+
+    /* Add the new item to the list */
+    ETFile->FileTagList = g_list_append(ETFile->FileTagList,FileTag);
+    /* Set the current item to use */
+    ETFile->FileTag     = g_list_last(ETFile->FileTagList);
+    /* Backup list */
+    ETFile->FileTagListBak = g_list_concat(ETFile->FileTagListBak,cut_list);
+
+    return TRUE;
+}
+
+/*
+ * Add a ETFile item to the main undo list of files
+ */
+static gboolean
+ET_Add_File_To_History_List (ET_File *ETFile)
+{
+    ET_History_File *ETHistoryFile;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    ETHistoryFile = g_slice_new0 (ET_History_File);
+    ETHistoryFile->ETFile = ETFile;
+
+    /* The undo list must contains one item before the 'first undo' data */
+    if (!ETCore->ETHistoryFileList)
+    {
+        ETCore->ETHistoryFileList = g_list_append (ETCore->ETHistoryFileList,
+                                                   g_slice_new0 (ET_History_File));
+    }
+
+    /* Add the item to the list (cut end of list from the current element) */
+    ETCore->ETHistoryFileList = g_list_append(ETCore->ETHistoryFileList,ETHistoryFile);
+    ETCore->ETHistoryFileList = g_list_last(ETCore->ETHistoryFileList);
+
+    return TRUE;
+}
+
+
+/*
+ * Applies one undo to the ETFile data (to reload the previous data).
+ * Returns TRUE if an undo had been applied.
+ */
+gboolean ET_Undo_File_Data (ET_File *ETFile)
+{
+    gboolean has_filename_undo_data = FALSE;
+    gboolean has_filetag_undo_data  = FALSE;
+    guint    filename_key, filetag_key, undo_key;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    /* Find the valid key */
+    if (ETFile->FileNameNew->prev && ETFile->FileNameNew->data)
+        filename_key = ((File_Name *)ETFile->FileNameNew->data)->key;
+    else
+        filename_key = 0;
+    if (ETFile->FileTag->prev && ETFile->FileTag->data)
+        filetag_key = ((File_Tag *)ETFile->FileTag->data)->key;
+    else
+        filetag_key = 0;
+    // The key to use
+    undo_key = MAX(filename_key,filetag_key);
+
+    /* Undo filename */
+    if (ETFile->FileNameNew->prev && ETFile->FileNameNew->data
+    && (undo_key==((File_Name *)ETFile->FileNameNew->data)->key))
+    {
+        ETFile->FileNameNew = ETFile->FileNameNew->prev;
+        has_filename_undo_data = TRUE; // To indicate that an undo has been applied
+    }
+
+    /* Undo tag data */
+    if (ETFile->FileTag->prev && ETFile->FileTag->data
+    && (undo_key==((File_Tag *)ETFile->FileTag->data)->key))
+    {
+        ETFile->FileTag = ETFile->FileTag->prev;
+        has_filetag_undo_data  = TRUE;
+    }
+
+    return has_filename_undo_data | has_filetag_undo_data;
+}
+
+
+/*
+ * Returns TRUE if file contains undo data (filename or tag)
+ */
+gboolean
+ET_File_Data_Has_Undo_Data (const ET_File *ETFile)
+{
+    gboolean has_filename_undo_data = FALSE;
+    gboolean has_filetag_undo_data  = FALSE;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    if (ETFile->FileNameNew && ETFile->FileNameNew->prev) has_filename_undo_data = TRUE;
+    if (ETFile->FileTag && ETFile->FileTag->prev)         has_filetag_undo_data  = TRUE;
+
+    return has_filename_undo_data | has_filetag_undo_data;
+}
+
+
+/*
+ * Applies one redo to the ETFile data. Returns TRUE if a redo had been applied.
+ */
+gboolean ET_Redo_File_Data (ET_File *ETFile)
+{
+    gboolean has_filename_redo_data = FALSE;
+    gboolean has_filetag_redo_data  = FALSE;
+    guint    filename_key, filetag_key, undo_key;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    /* Find the valid key */
+    if (ETFile->FileNameNew->next && ETFile->FileNameNew->next->data)
+        filename_key = ((File_Name *)ETFile->FileNameNew->next->data)->key;
+    else
+        filename_key = (guint)~0; // To have the max value for guint
+    if (ETFile->FileTag->next && ETFile->FileTag->next->data)
+        filetag_key = ((File_Tag *)ETFile->FileTag->next->data)->key;
+    else
+        filetag_key = (guint)~0; // To have the max value for guint
+    // The key to use
+    undo_key = MIN(filename_key,filetag_key);
+
+    /* Redo filename */
+    if (ETFile->FileNameNew->next && ETFile->FileNameNew->next->data
+    && (undo_key==((File_Name *)ETFile->FileNameNew->next->data)->key))
+    {
+        ETFile->FileNameNew = ETFile->FileNameNew->next;
+        has_filename_redo_data = TRUE; // To indicate that a redo has been applied
+    }
+
+    /* Redo tag data */
+    if (ETFile->FileTag->next && ETFile->FileTag->next->data
+    && (undo_key==((File_Tag *)ETFile->FileTag->next->data)->key))
+    {
+        ETFile->FileTag = ETFile->FileTag->next;
+        has_filetag_redo_data  = TRUE;
+    }
+
+    return has_filename_redo_data | has_filetag_redo_data;
+}
+
+
+/*
+ * Returns TRUE if file contains redo data (filename or tag)
+ */
+gboolean
+ET_File_Data_Has_Redo_Data (const ET_File *ETFile)
+{
+    gboolean has_filename_redo_data = FALSE;
+    gboolean has_filetag_redo_data  = FALSE;
+
+    g_return_val_if_fail (ETFile != NULL, FALSE);
+
+    if (ETFile->FileNameNew && ETFile->FileNameNew->next) has_filename_redo_data = TRUE;
+    if (ETFile->FileTag && ETFile->FileTag->next)         has_filetag_redo_data  = TRUE;
+
+    return has_filename_redo_data | has_filetag_redo_data;
+}
+
+
+/*
+ * Execute one 'undo' in the main undo list (it selects the last ETFile changed,
+ * before to apply an undo action)
+ */
+ET_File *ET_Undo_History_File_Data (void)
+{
+    ET_File *ETFile;
+    const ET_History_File *ETHistoryFile;
+
+    g_return_val_if_fail (ETCore->ETHistoryFileList != NULL ||
+                          ET_History_File_List_Has_Undo_Data (), NULL);
+
+    ETHistoryFile = (ET_History_File *)ETCore->ETHistoryFileList->data;
+    ETFile        = (ET_File *)ETHistoryFile->ETFile;
+    ET_Displayed_File_List_By_Etfile(ETFile);
+    ET_Undo_File_Data(ETFile);
+
+    if (ETCore->ETHistoryFileList->prev)
+        ETCore->ETHistoryFileList = ETCore->ETHistoryFileList->prev;
+    return ETFile;
+}
+
+
+/*
+ * Returns TRUE if undo file list contains undo data
+ */
+gboolean ET_History_File_List_Has_Undo_Data (void)
+{
+    if (ETCore->ETHistoryFileList && ETCore->ETHistoryFileList->prev)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+/*
+ * Execute one 'redo' in the main undo list
+ */
+ET_File *ET_Redo_History_File_Data (void)
+{
+    ET_File *ETFile;
+    ET_History_File *ETHistoryFile;
+
+    if (!ETCore->ETHistoryFileList || !ET_History_File_List_Has_Redo_Data()) return NULL;
+
+    ETHistoryFile = (ET_History_File *)ETCore->ETHistoryFileList->next->data;
+    ETFile        = (ET_File *)ETHistoryFile->ETFile;
+    ET_Displayed_File_List_By_Etfile(ETFile);
+    ET_Redo_File_Data(ETFile);
+
+    if (ETCore->ETHistoryFileList->next)
+        ETCore->ETHistoryFileList = ETCore->ETHistoryFileList->next;
+    return ETFile;
+}
+
+
+/*
+ * Returns TRUE if undo file list contains redo data
+ */
+gboolean ET_History_File_List_Has_Redo_Data (void)
+{
+    if (ETCore->ETHistoryFileList && ETCore->ETHistoryFileList->next)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+
+
+
+/**********************
+ * Checking functions *
+ **********************/
+
+
+/*
+ * Ckecks if the current files had been changed but not saved.
+ * Returns TRUE if the file has been saved.
+ * Returns FALSE if some changes haven't been saved.
+ */
+gboolean
+ET_Check_If_File_Is_Saved (const ET_File *ETFile)
+{
+    File_Tag  *FileTag     = NULL;
+    File_Name *FileNameNew = NULL;
+
+    g_return_val_if_fail (ETFile != NULL, TRUE);
+
+    if (ETFile->FileTag)
+        FileTag     = ETFile->FileTag->data;
+    if (ETFile->FileNameNew)
+        FileNameNew = ETFile->FileNameNew->data;
+
+    // Check if the tag has been changed
+    if ( FileTag && FileTag->saved != TRUE )
+        return FALSE;
+
+    // Check if name of file has been changed
+    if ( FileNameNew && FileNameNew->saved != TRUE )
+        return FALSE;
+
+    // No changes
+    return TRUE;
+}
+
+
+/*
+ * Ckecks if some files, in the list, had been changed but not saved.
+ * Returns TRUE if all files have been saved.
+ * Returns FALSE if some changes haven't been saved.
+ */
+gboolean ET_Check_If_All_Files_Are_Saved (void)
+{
+    /* Check if some files haven't been saved, if didn't nochange=0 */
+    if (!ETCore->ETFileList)
+    {
+        return TRUE;
+    }else
+    {
+        GList *l;
+
+        for (l = g_list_first (ETCore->ETFileList); l != NULL;
+             l = g_list_next (l))
+        {
+            if (ET_Check_If_File_Is_Saved ((ET_File *)l->data) == FALSE)
+                return FALSE;
+        }
+        return TRUE;
+    }
+}
+
+
+
+
+/*******************
+ * Extra functions *
+ *******************/
+
+/*
+ * Set to TRUE the value of 'FileTag->saved' for the File_Tag item passed in parameter.
+ * And set ALL other values of the list to FALSE.
+ */
+static void
+Set_Saved_Value_Of_File_Tag (File_Tag *FileTag, gboolean saved)
+{
+    if (FileTag) FileTag->saved = saved;
+}
+
+static void
+ET_Mark_File_Tag_As_Saved (ET_File *ETFile)
+{
+    File_Tag *FileTag;
+    GList *FileTagList;
+
+    FileTag     = (File_Tag *)ETFile->FileTag->data;    // The current FileTag, to set to TRUE
+    FileTagList = ETFile->FileTagList;
+    g_list_foreach(FileTagList,(GFunc)Set_Saved_Value_Of_File_Tag,FALSE); // All other FileTag set to FALSE
+    FileTag->saved = TRUE; // The current FileTag set to TRUE
+}
+
+
+void ET_Mark_File_Name_As_Saved (ET_File *ETFile)
+{
+    File_Name *FileNameNew;
+    GList *FileNameList;
+
+    FileNameNew  = (File_Name *)ETFile->FileNameNew->data;    // The current FileName, to set to TRUE
+    FileNameList = ETFile->FileNameList;
+    g_list_foreach(FileNameList,(GFunc)Set_Saved_Value_Of_File_Tag,FALSE);
+    FileNameNew->saved = TRUE;
+}
+
+
+/*
+ * et_core_read_file_info:
+ * @file: a file from which to read information
+ * @ETFileInfo: (out caller-allocates): a file information structure
+ * @error: a #GError to provide information on erros, or %NULL to ignore
+ *
+ * Fille @ETFileInfo with information about the file. Currently, this only
+ * fills the file size.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ */
+static gboolean
+et_core_read_file_info (GFile *file,
+                        ET_File_Info *ETFileInfo,
+                        GError **error)
+{
+    GFileInfo *info;
+
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+    g_return_val_if_fail (file != NULL && ETFileInfo != NULL, FALSE);
+
+    info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE,
+                              G_FILE_QUERY_INFO_NONE, NULL, error);
+
+    if (!info)
+    {
+        g_assert (error == NULL || *error != NULL);
+        return FALSE;
+    }
+
+    ETFileInfo->version    = 0;
+    ETFileInfo->bitrate    = 0;
+    ETFileInfo->samplerate = 0;
+    ETFileInfo->mode       = 0;
+    ETFileInfo->size = g_file_info_get_size (info);
+    ETFileInfo->duration   = 0;
+
+    g_assert (error == NULL || *error == NULL);
+    g_object_unref (info);
+
+    return TRUE;
+}
+
+/*
+ * This function generates a new filename using path of the old file and the
+ * new name.
+ * - ETFile -> old_file_name : "/path_to_file/old_name.ext"
+ * - new_file_name_utf8      : "new_name.ext"
+ * Returns "/path_to_file/new_name.ext" into allocated data (in UTF-8)!
+ * Notes :
+ *   - filenames (basemane) musn't exceed 255 characters (i.e. : "new_name.ext")
+ *   - ogg filename musn't exceed 255-6 characters as we use mkstemp
+ */
+#if 1
+gchar *
+ET_File_Name_Generate (const ET_File *ETFile,
+                       const gchar *new_file_name_utf8)
+{
+    gchar *dirname_utf8;
+
+    if (ETFile && ETFile->FileNameNew->data && new_file_name_utf8
+    && (dirname_utf8=g_path_get_dirname(((File_Name *)ETFile->FileNameNew->data)->value_utf8)) )
+    {
+        gchar *extension;
+        gchar *new_file_name_path_utf8;
+
+        // Convert filename extension (lower/upper)
+        extension = ET_File_Name_Format_Extension(ETFile);
+
+        // Check length of filename (limit ~255 characters)
+        //ET_File_Name_Check_Length(ETFile,new_file_name_utf8);
+
+        // If filemame starts with /, it's a full filename with path but without extension
+        if (g_path_is_absolute(new_file_name_utf8))
+        {
+            // We just add the extension
+            new_file_name_path_utf8 = g_strconcat(new_file_name_utf8,extension,NULL);
+        }else
+        {
+            // New path (with filename)
+            if ( strcmp(dirname_utf8,G_DIR_SEPARATOR_S)==0 ) // Root directory?
+                new_file_name_path_utf8 = g_strconcat(dirname_utf8,new_file_name_utf8,extension,NULL);
+            else
+                new_file_name_path_utf8 = 
g_strconcat(dirname_utf8,G_DIR_SEPARATOR_S,new_file_name_utf8,extension,NULL);
+        }
+
+        g_free (dirname_utf8);
+        g_free(extension);
+        return new_file_name_path_utf8; // in UTF-8
+    }else
+    {
+        return NULL;
+    }
+}
+#else
+/* FOR TESTING */
+/* Returns filename in file system encoding */
+gchar *ET_File_Name_Generate (ET_File *ETFile, gchar *new_file_name_utf8)
+{
+    gchar *dirname;
+
+    if (ETFile && ETFile->FileNameNew->data && new_file_name_utf8
+    && (dirname=g_path_get_dirname(((File_Name *)ETFile->FileNameNew->data)->value)) )
+    {
+        gchar *extension;
+        gchar *new_file_name_path;
+        gchar *new_file_name;
+
+        new_file_name = filename_from_display(new_file_name_utf8);
+
+        // Convert filename extension (lower/upper)
+        extension = ET_File_Name_Format_Extension(ETFile);
+
+        // Check length of filename (limit ~255 characters)
+        //ET_File_Name_Check_Length(ETFile,new_file_name_utf8);
+
+        // If filemame starts with /, it's a full filename with path but without extension
+        if (g_path_is_absolute(new_file_name))
+        {
+            // We just add the extension
+            new_file_name_path = g_strconcat(new_file_name,extension,NULL);
+        }else
+        {
+            // New path (with filename)
+            if ( strcmp(dirname,G_DIR_SEPARATOR_S)==0 ) // Root directory?
+                new_file_name_path = g_strconcat(dirname,new_file_name,extension,NULL);
+            else
+                new_file_name_path = g_strconcat(dirname,G_DIR_SEPARATOR_S,new_file_name,extension,NULL);
+        }
+
+        g_free(dirname);
+        g_free(new_file_name);
+        g_free(extension);
+        return new_file_name_path; // in file system encoding
+    }else
+    {
+        return NULL;
+    }
+}
+#endif
+
+
+/* Convert filename extension (lower/upper/no change). */
+static gchar *
+ET_File_Name_Format_Extension (const ET_File *ETFile)
+{
+    EtFilenameExtensionMode mode;
+
+    mode = g_settings_get_enum (MainSettings, "rename-extension-mode");
+
+    switch (mode)
+    {
+        /* FIXME: Should use filename encoding, not UTF-8! */
+        case ET_FILENAME_EXTENSION_LOWER_CASE:
+            return g_utf8_strdown (ETFile->ETFileDescription->Extension, -1);
+        case ET_FILENAME_EXTENSION_UPPER_CASE:
+            return g_utf8_strup (ETFile->ETFileDescription->Extension, -1);
+        case ET_FILENAME_EXTENSION_NO_CHANGE:
+        default:
+            return g_strdup (ETFile->ETFileExtension);
+    };
+}
+
+
+/*
+ * Used to replace the illegal characters in the filename
+ * Paremeter 'filename' musn't contain the path, else directories separators would be replaced!
+ */
+gboolean ET_File_Name_Convert_Character (gchar *filename_utf8)
+{
+    gchar *character;
+
+    g_return_val_if_fail (filename_utf8 != NULL, FALSE);
+
+    // Convert automatically the directory separator ('/' on LINUX and '\' on WIN32) to '-'.
+    while ( (character=g_utf8_strchr(filename_utf8, -1, G_DIR_SEPARATOR))!=NULL )
+        *character = '-';
+
+#ifdef G_OS_WIN32
+    /* Convert character '\' on WIN32 to '-'. */
+    while ( (character=g_utf8_strchr(filename_utf8, -1, '\\'))!=NULL )
+        *character = '-';
+    /* Convert character '/' on WIN32 to '-'. May be converted to '\' after. */
+    while ( (character=g_utf8_strchr(filename_utf8, -1, '/'))!=NULL )
+        *character = '-';
+#endif /* G_OS_WIN32 */
+
+    /* Convert other illegal characters on FAT32/16 filesystems and ISO9660 and
+     * Joliet (CD-ROM filesystems). */
+    if (g_settings_get_boolean (MainSettings, "rename-replace-illegal-chars"))
+    {
+        // Commented as we display unicode values as "\351" for "é"
+        //while ( (character=g_utf8_strchr(filename_utf8, -1, '\\'))!=NULL )
+        //    *character = ',';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, ':'))!=NULL )
+            *character = '-';
+        //while ( (character=g_utf8_strchr(filename_utf8, -1, ';'))!=NULL )
+        //    *character = '-';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '*'))!=NULL )
+            *character = '+';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '?'))!=NULL )
+            *character = '_';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '\"'))!=NULL )
+            *character = '\'';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '<'))!=NULL )
+            *character = '(';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '>'))!=NULL )
+            *character = ')';
+        while ( (character=g_utf8_strchr(filename_utf8, -1, '|'))!=NULL )
+            *character = '-';
+    }
+    return TRUE;
+}
+
+
+/*
+ * Returns the number of file in the directory of the selected file.
+ * Parameter "path" should be in UTF-8
+ */
+guint
+ET_Get_Number_Of_Files_In_Directory (const gchar *path_utf8)
+{
+    gchar *path_key;
+    GList *l;
+    guint  count = 0;
+
+    g_return_val_if_fail (path_utf8 != NULL, count);
+
+    path_key = g_utf8_collate_key (path_utf8, -1);
+
+    for (l = g_list_first (ETCore->ETFileList); l != NULL; l = g_list_next (l))
+    {
+        ET_File *ETFile = (ET_File *)l->data;
+        const gchar *cur_filename_utf8 = ((File_Name *)((GList *)ETFile->FileNameCur)->data)->value_utf8;
+        gchar *dirname_utf8      = g_path_get_dirname(cur_filename_utf8);
+        gchar *dirname_key = g_utf8_collate_key (dirname_utf8, -1);
+
+        if (strcmp (dirname_utf8, path_utf8) == 0)
+        {
+            count++;
+        }
+
+        g_free (dirname_utf8);
+        g_free (dirname_key);
+    }
+
+    g_free (path_key);
+
+    return count;
+}
+
+/*
+ * Set appropriate sort order for the given column_id
+ */
+static void
+set_sort_order_for_column_id (gint column_id, GtkTreeViewColumn *column,
+                              EtSortMode sort_type)
+{
+    EtApplicationWindow *window;
+    EtSortMode current_mode;
+
+    window = ET_APPLICATION_WINDOW (MainWindow);
+
+    /* Removing the sort indicator for the currently selected treeview
+     * column. */
+    current_mode = g_settings_get_enum (MainSettings, "sort-mode");
+
+    if (current_mode < ET_SORT_MODE_ASCENDING_CREATION_DATE)
+    {
+        gtk_tree_view_column_set_sort_indicator (et_application_window_browser_get_column_for_column_id 
(window, current_mode / 2),
+                                                 FALSE);
+    }
+
+    if (sort_type < ET_SORT_MODE_ASCENDING_CREATION_DATE)
+    {
+        gtk_tree_view_column_clicked (et_application_window_browser_get_column_for_column_id (window, 
column_id));
+
+        if (sort_type % 2 == 0)
+        {
+            /* GTK_SORT_ASCENDING */
+            if (et_application_window_browser_get_sort_order_for_column_id (window, column_id)
+                == GTK_SORT_DESCENDING)
+            {
+                gtk_tree_view_column_set_sort_order (column,
+                                                     GTK_SORT_ASCENDING);
+            }
+        }
+        else
+        {
+            /* GTK_SORT_DESCENDING */
+            if (et_application_window_browser_get_sort_order_for_column_id (window, column_id)
+                == GTK_SORT_ASCENDING)
+            {
+                gtk_tree_view_column_set_sort_order (column,
+                                                     GTK_SORT_DESCENDING);
+            }
+        }
+    }
+}
diff --git a/src/file.h b/src/file.h
new file mode 100644
index 0000000..3a08f31
--- /dev/null
+++ b/src/file.h
@@ -0,0 +1,181 @@
+/* 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_H_
+#define ET_FILE_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#include "core_types.h"
+#include "file_description.h"
+#include "file_tag.h"
+#include "setting.h"
+
+/*
+ * Description of each item of the FileNameList list
+ */
+typedef struct
+{
+    guint key;
+    gboolean saved;        /* Set to TRUE if this filename had been saved */
+    gchar *value;          /* The filename containing the full path and the extension of the file */
+    gchar *value_utf8;     /* Same than "value", but converted to UTF-8 to avoid multiple call to the 
convertion function */
+    gchar *value_ck;       /* Collate key of "value_utf8" to speed up comparaison */
+} File_Name;
+
+/*
+ * Description of each item of the ETFileList list
+ */
+typedef struct
+{
+    guint IndexKey;           /* Value used to display the position in the list (and in the BrowserList) - 
Must be renumered after resorting the list - This value varies when resorting list */
+
+    guint ETFileKey;          /* Primary key to identify each item of the list (no longer used?) */
+
+    time_t FileModificationTime;            /* Save modification time of the file */
+
+    const ET_File_Description *ETFileDescription;
+    gchar               *ETFileExtension;   /* Real extension of the file (keeping the case) (should be 
placed in ETFileDescription?) */
+    ET_File_Info        *ETFileInfo;        /* Header infos: bitrate, duration, ... */
+
+    GList *FileNameCur;       /* Points to item of FileNameList that represents the current value of 
filename state (i.e. file on hard disk) */
+    GList *FileNameNew;       /* Points to item of FileNameList that represents the new value of filename 
state */
+    GList *FileNameList; /* Contains the history of changes about the filename. */
+    GList *FileNameListBak;   /* Contains items of FileNameList removed by 'undo' procedure but have data 
currently saved (for example, when you save your last changes, make some 'undo', then make new changes) */
+
+    GList *FileTag;           /* Points to the current item used of FileTagList */
+    GList *FileTagList;       /* Contains the history of changes about file tag data */
+    GList *FileTagListBak;    /* Contains items of FileTagList removed by 'undo' procedure but have data 
currently saved */
+} ET_File;
+
+/*
+ * Description of each item of the ETHistoryFileList list
+ */
+typedef struct
+{
+    ET_File *ETFile;           /* Pointer to item of ETFileList changed */
+} ET_History_File;
+
+GList   *ET_Add_File_To_File_List        (gchar *filename);
+gboolean ET_Remove_File_From_File_List   (ET_File *ETFile);
+gboolean ET_Free_File_List (void);
+
+gboolean ET_Create_Artist_Album_File_List      (void);
+gboolean ET_Free_Artist_Album_File_List (void);
+gboolean ET_Remove_File_From_File_List         (ET_File *ETFile);
+
+gboolean ET_Check_If_File_Is_Saved (const ET_File *ETFile);
+gboolean ET_Check_If_All_Files_Are_Saved (void);
+
+ET_File      *ET_File_Item_New       (void);
+File_Name    *ET_File_Name_Item_New  (void);
+void      ET_Free_File_List_Item (ET_File *ETFile);
+
+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);
+
+/* 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);
+GList   *ET_Displayed_File_List_Next        (void);
+GList   *ET_Displayed_File_List_Last        (void);
+GList *ET_Displayed_File_List_By_Etfile (const ET_File *ETFile);
+
+gboolean ET_Set_Displayed_File_List         (GList *ETFileList);
+gboolean ET_Free_Displayed_File_List (void);
+
+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);
+gboolean ET_File_Data_Has_Redo_Data (const ET_File *ETFile);
+
+ET_File *ET_Undo_History_File_Data          (void);
+ET_File *ET_Redo_History_File_Data          (void);
+gboolean ET_History_File_List_Has_Undo_Data (void);
+gboolean ET_History_File_List_Has_Redo_Data (void);
+gboolean ET_Free_History_File_List (void);
+
+gboolean ET_Manage_Changes_Of_File_Data          (ET_File *ETFile, File_Name *FileName, File_Tag *FileTag);
+void     ET_Mark_File_Name_As_Saved              (ET_File *ETFile);
+void ET_Update_Directory_Name_Into_File_List (const gchar *last_path, const gchar *new_path);
+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);
+
+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);
+gint ET_Comp_Func_Sort_File_By_Descending_Filename (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Creation_Date (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Creation_Date (const ET_File *ETFile1, const ET_File *ETFile2);
+gint et_comp_func_sort_file_by_ascending_disc_number (const ET_File *ETFile1,
+                                                      const ET_File *ETFile2);
+gint et_comp_func_sort_file_by_descending_disc_number (const ET_File *ETFile1,
+                                                       const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Track_Number (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Track_Number (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Title (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Title (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Album_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Album_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Album (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Album (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Year (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Year (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Genre (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Genre (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Comment (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Comment (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Composer (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Composer (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Orig_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Orig_Artist (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Copyright (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Copyright (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Url (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Url (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_Encoded_By (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_Encoded_By (const ET_File *ETFile1, const ET_File *ETFile2);
+
+gint ET_Comp_Func_Sort_File_By_Ascending_File_Type (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_File_Type (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_File_Size (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_File_Size (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_File_Duration (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_File_Duration (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_File_Bitrate (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_File_Bitrate (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Ascending_File_Samplerate (const ET_File *ETFile1, const ET_File *ETFile2);
+gint ET_Comp_Func_Sort_File_By_Descending_File_Samplerate (const ET_File *ETFile1, const ET_File *ETFile2);
+
+G_END_DECLS
+
+#endif /* !ET_FILE_H_ */


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