Update of /cvsroot/gtkpod/gtkpod/src
In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv30358/src

Modified Files:
        Makefile.am display_itdb.h display_tracks.c file.c file.h 
        file_itunesdb.c misc.c misc.h misc_conversion.c misc_track.c 
        prefs.c prefs_window.c repository.c syncdir.c tools.c 
Added Files:
        file_convert.c file_convert.h flacfile.c flacfile.h oggfile.c 
        oggfile.h 
Log Message:
        * scripts/convert-flac2mp3.sh
          scripts/convert-ogg2mp3.sh
          src/file_convert.[ch]
          src/flacfile.[ch]
          src/oggfile.[ch]: new files for patch mentioned below

          configure.in
          gtkpod.glade
          scripts/Makefile.am
          src/Makefile.am
          src/display_itdb.h
          src/display_tracks.c
          src/file.c
          src/file.h
          src/file_itunesdb.c
          src/misc.c
          src/misc.h
          src/misc_conversion.c
          src/misc_track.c
          src/prefs.c
          src/prefs_window.c
          src/repository.c
          src/syncdir.c
          src/tools.c: combined patch by Marc d[r]eadlock and Simon
          Naunton for on-the fly conversion of FLAC and OGG files
          during export to the iPod, plus some patches thrown in by
          myself. Thanks for the contribution!



--- NEW FILE: file_convert.c ---
#ifdef HAVE_CONFIG_H
#   include <config.h>
#endif
/*
 * TODO:
 *  - see threaded version (conversion launched when adding the file)
 *
 *  ++dump child_stdout if file name not found or file not found 
 *
 *  - redirect stderr display into "debug info" ?? (as in k3b) ??
 *
 *  - what happend if "conversion" change ? i.e. if ogg was converted into mp3 
and is now with flac
 *
 *  - how abort this ? we should kill the child_pid ?
 *  - fix non-converted files, i.e. remove them from DB ? or it is currently ok
 *  - fix the g_return_if_fail( <cond>, NULL) into conv_error(xxx) ?
 *
 *  - check memory leak(s): check allocated/free'd stuff (especially on errors)
 *
 */

/*
 * HOWTO add new conversions:
 *  - new xxxfile.[ch] (modify also Makefile.am and configure.in if lib needed)
 *  - new path_conv_xxx in 
 *       gtkpod.glade
 *       prefs_window.c: path_button_names, path_key_names, path_entry_names
 *  - modify file_convert.c::file_convert_pre_copy() to add the new type in 
switch(converter->type)
 */

#include <string.h>
#include "file_convert.h"
#include "display_itdb.h"
#include <glib.h>
#include <sys/wait.h>       /* for WIF... macros */
#include <glib.h>
#include <glib/gstdio.h>    /* g_unlink (which is currently #define unlink) */
#include <unistd.h>         /* unlink not included in glib/gstdio (strange) */
#include "prefs.h"
#include "misc.h"           /* T_item */
#include "misc_track.h"     /* track_get_item_pointer */

#define DEBUG_CONV
#ifdef DEBUG_CONV
#   define _TO_STR(x) #x
#   define TO_STR(x) _TO_STR(x)
#   define debug(...) do { fprintf(stderr,  __FILE__ ":" TO_STR(__LINE__) ":" 
__VA_ARGS__); } while(0)
#else
#   define debug(...)
#endif

#define conv_error(...) g_error_new(G_FILE_ERROR, 0, __VA_ARGS__)


/* Internal functions */
static GError *execute_conv(gchar **argv,Track *track);
static gchar *get_filename_from_stdout(TrackConv *converter);
static gchar *checking_converted_file (TrackConv *converter, Track *track);
#if 0
static gchar **cmdline_to_argv(const gchar *cmdline, Track *track); /* TODO: 
could be extern for other needs */
#endif


/* Functions */

/*
 * file_convert_pre_copy()
 * converts a track by launching the external command given in the prefs 
 *
 */
extern GError *file_convert_pre_copy(Track *track)
{   
    ExtraTrackData *etr=NULL;
    TrackConv *converter=NULL;          /* the converter struct */
    GError *error=NULL;                 /* error if any */
    const gchar *type=NULL;             /* xxx (ogg) */
    gchar *conv_str=NULL;               /* path_conv_xxx or ext_conv_xxx */
    gchar *convert_command=NULL;        /* from prefs */
    gchar **argv;                       /* for conversion external process */

    /* sanity checks */ 
    g_return_val_if_fail (track,NULL);
    etr=track->userdata;
    g_return_val_if_fail (etr,NULL);
    converter=etr->conv;
    g_return_val_if_fail (converter,NULL);


    /* Find the correct script for conversion */
    switch (converter->type) {
        case FILE_TYPE_UNKNOWN:
        case FILE_TYPE_MP3:
        case FILE_TYPE_M4A:
        case FILE_TYPE_M4P:
        case FILE_TYPE_M4B:
        case FILE_TYPE_WAV:
        case FILE_TYPE_M4V:
        case FILE_TYPE_MP4:
        case FILE_TYPE_MOV:
        case FILE_TYPE_MPG:
        case FILE_TYPE_M3U:
        case FILE_TYPE_PLS:
        case FILE_TYPE_IMAGE:
        case FILE_TYPE_DIRECTORY:
            return NULL; /*FIXME: error? */
            break;
        case FILE_TYPE_OGG:
            type="ogg";/*FIXME: get it directly for type. */
            break;
        case FILE_TYPE_FLAC:
            type="flac";/*FIXME: get it directly for type. */
            break;
    }
    conv_str=g_strdup_printf("path_conv_%s",type);
    convert_command=prefs_get_string (conv_str);
    g_free(conv_str);
 
    debug("convert_command:%s\n",convert_command);
    /* Check that everything is ok before continuing */
    if (!convert_command ||
        strlen(convert_command)==0) {
        return conv_error(_("No command found to convert `%s'.\n"
                            "Please fill the On-the-fly conversion settings for 
%s in the Tools preferences"),
                          etr->pc_path_locale,
                          type);
    }
    /* FIXME: check that %s is present (at least) */
    
    /* Build the command args */
    argv = g_malloc0(sizeof(gchar*) * 3);
    argv[0] = convert_command;
    argv[1] = etr->pc_path_locale;

    /* Convert the file */

    error=execute_conv (argv, track); /* frees all cmdline strings */

    return error;
}

/*
 * file_convert_wait_for_conversion()
 *
 * Waiting for converter process to end, then analyse its stdout in order to 
find the filename created.
 * FIXME: check converted file extension sounds good. 
 *
 */
extern GError *file_convert_wait_for_conversion(Track *track)
{
    ExtraTrackData *etr=NULL;
    TrackConv *converter=NULL;
    gint exit_status;
    GPid wait;
    gchar *error_msg=NULL;
    GError *error=NULL;

    /* sanity checks */ 
    g_return_val_if_fail (track,NULL);
    etr=track->userdata;
    g_return_val_if_fail (etr,NULL);
    converter=etr->conv;
    g_return_val_if_fail (converter,NULL);
    g_return_val_if_fail (converter->child_pid>0, NULL);

    debug("Waiting for child (PID=%d)\n",converter->child_pid);

    /* Waiting for PID and checking Return code */
    wait=waitpid(converter->child_pid,&exit_status,0);
    if (wait == -1)  {
        error_msg=g_strdup ("Weird waitpid sent -1 ! Please report.\n");
    } else {
        if (WIFEXITED(exit_status)){
            debug("seems to be %s: 
%d...\n",WEXITSTATUS(exit_status)==0?"ok":"ko", WEXITSTATUS(exit_status));
            switch (WEXITSTATUS(exit_status)) {
                case 0: /* OK */ break;
                case 1: error_msg = g_strdup_printf ("Input file not found"); 
break;
                case 2: error_msg = g_strdup_printf ("Output file could not be 
created"); break;
                case 3: error_msg = g_strdup_printf ("Cannot get info for 
file"); break;
                case 4: error_msg = g_strdup_printf ("Cannot exec decoding"); 
break;
                case 5: error_msg = g_strdup_printf ("Cannot exec encoding"); 
break;
                case 6: error_msg = g_strdup_printf ("Conversion failed"); 
break;
                default:
                    error_msg = g_strdup_printf ("Unknow script exit status:%d 
",WEXITSTATUS(exit_status));
            }
        }else if (WIFSIGNALED(exit_status)) {
            debug(":0x%X -> %d\n",exit_status,WTERMSIG(exit_status));
            error_msg = g_strdup_printf ("Execution failed. Received signal %d 
(%s)",
                                         
WTERMSIG(exit_status),(error?error->message:""));
        }else if (WIFSTOPPED(exit_status)) {
            debug(":0x%X -> %d\n",exit_status,WSTOPSIG(exit_status));
            error_msg = g_strdup_printf ("Execution stopped. Received signal %d 
(%s)",
                                         
WSTOPSIG(exit_status),(error?error->message:""));
        }else if (WIFCONTINUED(exit_status)) {
            /* FIXME: strange to be here no?? */
            debug(":0x%X -> SIGCONT\n",exit_status);
            error_msg = g_strdup_printf ("Execution continued. Received signal 
SIGCONT (%s)",
                                         (error?error->message:""));
        } else {
            error_msg = g_strdup_printf ("Execution failed (%s)",
                                         (error?error->message:""));
        }
    }
    debug("Error: %s\n",(error_msg?error_msg:"N/A"));

    /* Getting filename from child's STDOUT */
    if (!error_msg)
        error_msg = get_filename_from_stdout (converter);

    /* Checking file exists */
    if (!error_msg)
        error_msg = checking_converted_file (converter, track);

    /* Checking errors */
    if (error_msg){
        error=conv_error(_("Cannot convert '%s'.\nExecuting `%s'\nGave error: 
%s\n\n"),
                         etr->pc_path_locale,
                         converter->command_line,
                         error_msg);
        g_free (error_msg);
    }
    /* Freeing data */
    if (converter->child_pid) {
        g_spawn_close_pid(converter->child_pid);
        converter->child_pid=0;
    }
    g_free (converter->command_line);
    converter->command_line=NULL;

    /* It's finally over */
    return error;
}


/*
 * file_convert_post_copy()
 * 
 * Remove files created by file_convert_pre_copy() if necessary (TODO).
 *
 */
extern GError * file_convert_post_copy(Track *track)
{
    GError *error=NULL;
    ExtraTrackData *etr=NULL;
    TrackConv *converter=NULL;

    /* sanity checks */ 
    g_return_val_if_fail (track,NULL);
    etr=track->userdata;
    g_return_val_if_fail (etr,NULL);
    converter=etr->conv;
    g_return_val_if_fail (converter,NULL);
    g_return_val_if_fail (converter->converted_file, NULL);

    debug("file_convert_post_copy(%s)\n",converter->converted_file);
    /*TODO: check prefs to not remove file */
    g_unlink (converter->converted_file);
    g_free (converter->converted_file);
    converter->converted_file=NULL;
    /*FIXME: restore track->size ????? */
    return error; 
}






/* 
 *
 *
 * Implementation of Internal functions 
 *
 *
 */






/*
 * Call the external command given in @tokens for the given @track
 */
static GError *execute_conv(gchar **argv,Track *track)
{
    ExtraTrackData *etr=NULL;
    TrackConv *converter=NULL;
    GError *error=NULL;
    gchar *command_line=NULL;
    GError *spawn_error=NULL;
    guint i=0;
    GPid child_pid;
    gint child_stdout;

    /* sanity checks */ 
    g_return_val_if_fail (track,NULL);
    etr=track->userdata;
    g_return_val_if_fail (etr,NULL);
    converter=etr->conv;
    g_return_val_if_fail (converter,NULL);

    g_return_val_if_fail (argv!=NULL, NULL);

    /* Building command_line string (for output only) */
    for(i=0; argv[i]!=NULL; ++i) 
    {
        gchar *p=command_line;
        if (!p) 
            command_line=g_strdup(argv[i]);                      /* program 
name (1st token) */
        else {
            command_line=g_strdup_printf("%s \"%s\"",p,argv[i]); /* arg (other 
tokens) */
            g_free(p);
        }
    }

    debug("Executing `%s'\n",command_line);

    /* Launching conversion */
    if (g_spawn_async_with_pipes(NULL,                      /* working dir 
(inherit parent) FIXME: use 'track' dir  */
                                 argv,                      /* argv  FIXME: 
check if windows issue with argv[0] */
                                 NULL,                      /* envp */
                                 G_SPAWN_SEARCH_PATH |      /* flags: use 
user's $PATH */
                                 G_SPAWN_DO_NOT_REAP_CHILD, /*        keep 
child alive (for waidpid, g_spwan_close_pid)  */
                                 NULL,                      /* child_setup 
function */
                                 NULL,                      /* user_data */
                                 &child_pid,                /* child's PID */
                                 NULL,                      /* child's stdin */
                                 &child_stdout,             /* child's stdout */
                                 NULL,                      /* child's stderr 
FIXME: get this for "debug"    (result?) */
                                 &spawn_error)==FALSE){     /* error */
        debug("error: error:%p (message:%s)",error, 
(error?error->message:"NoErrorMessage"));
        error = conv_error(_("Cannot convert '%s'.\nExecuting `%s'\nGave error: 
%s\n\n"),
                             etr->pc_path_locale,
                             command_line,
                             
(spawn_error&&spawn_error->message)?spawn_error->message:"no explanation. 
Please report.");
        if (spawn_error)
            g_free (spawn_error);   /* FIXME: memory leak i guess (at least for 
message if any). */
        g_free (command_line);
    } else {
        converter->child_pid=child_pid;
        converter->child_stdout=child_stdout;
        converter->command_line=command_line;
    }

    /* Freeing data */
    for(i=0; argv[i]!=NULL; ++i){
        g_free (argv[i]);
    }
    g_free (argv);

    return error;
}

/*
 * get_filename_from_stdout()
 */
static gchar *get_filename_from_stdout(TrackConv *converter)
{
    gchar *error=0;
    if (converter->child_stdout<=0) {
        error = g_strdup_printf ("Strange child_stdout: 
%d\n",converter->child_stdout);
    } else {
        /* find a filename (max size: PATH_MAX) at the end of the STDOUT */
        lseek(converter->child_stdout, PATH_MAX, SEEK_END); /* don't care of 
error: we assume it's ok, i.e. we're near the end of the stdout */
        gchar buffer[PATH_MAX+1];
        memset(buffer,0x0,sizeof(buffer));
        if (read(converter->child_stdout, buffer,  PATH_MAX) <= 0) {
            error = g_strdup_printf ("Cannot read in child_stdout 
(%d)\n",converter->child_stdout);
        } else {
            /* find the filename on a line, i.e. after a \n */
            char *end=buffer+strlen(buffer)-1;
            char *begin=rindex(buffer, '\n');       
            if (begin==end) {                /* if STDOUT ends with \n, */
                *end='\0';                   /*    eat this one  */
                begin=rindex(buffer, '\n');  /*    and re-search for a \n */
            }
            if (!begin) 
                begin=buffer;
            else 
                begin++;
            debug("File found: `%s'\n",begin);
            converter->converted_file=g_strdup (begin);
        }
        close (converter->child_stdout);
        converter->child_stdout=-1;
    }
    return error;
}


/*
 *  checking_converted_file()
 */
static gchar *checking_converted_file (TrackConv *converter, Track *track)
{
    gchar *error=NULL;
    struct stat stat_file;             
    /* Fix some stuff for the iPod */
    if (g_file_test(converter->converted_file,G_FILE_TEST_EXISTS) &&
        stat(converter->converted_file,&stat_file)==0){
        converter->old_size=track->size;            /* save real original size 
*/
        track->size=stat_file.st_size;              /* faking size for iPod */
    } else {
        error = g_strdup_printf (_("Converted file `%s' is not found !\n"),
                                    converter->converted_file);
    }
    return error;
}


#if 0
/*
 * cmdline_to_argv()
 *
 * Parses a string and split it into a decent argv (that should be freed) 
 *        while replacing %<x> with their value from the track
 */
static gchar **cmdline_to_argv(const gchar *cmdline, Track *track)
{
    gint  size=1;
    gchar **argv=g_malloc(size*sizeof(gchar *));
    gchar *copy=g_strdup (cmdline);
    gchar *ptr=copy;
    gint  argc=0;
    gchar ptr_plus_index_less_1='\0';
    guint index=0;
    gint  finished=0;
    debug("cmdline_to_argv(\"%s\",%p)\n",cmdline, track);
    while (!finished) {
        /* Percent sign */
        if (*(ptr+index)=='%' && *(ptr+index+1)!='\0'){  
            T_item item = char_to_T (*(ptr+index+1));
            if (item != -1) {
                gchar *tmp;
                const gchar *value=track_get_item (track, item);
                gchar *basename=NULL;
                ptr[index]='\0';
                if (value && ptr_plus_index_less_1 != '\0' && *(ptr+index+1) == 
's') {
                    /* relative path to file: keep only basename */
                    basename=g_path_get_basename (value);
                    value=basename;
                }
                tmp=g_strdup_printf ("%s%s%s", ptr, value?value:"", 
ptr+index+2);
                g_free (ptr);
                ptr=tmp;
                if (value && strlen (value)) {
                    index+=strlen(value);
                    ptr_plus_index_less_1=*(ptr+index-1);
                }
                if (basename)
                    g_free (basename);
            } else {
                /* no item found. Skipping */    /* FIXME: %% should be '%' no 
? */
                debug("No item\n");
                ptr_plus_index_less_1=*(ptr+index);
                ++index;
            }

        /* Blank sign */
        } else if (*(ptr+index)==' ' || *(ptr+index) == '\0') {
            gchar *tmp;
            finished = *(ptr+index)=='\0';
            /* Blank: new token to be put in argv */
            if ((argc+1) >= size) { 
                size*=2;
                argv=g_realloc(argv, size*sizeof(gchar *));
                if (!argv)
                    return NULL;/* FIXME: memory Leak ! */
            }
            ptr[index]='\0';
            while (*(ptr+index+1)==' ')
                ++index;
            argv[argc++]=g_strdup (ptr);
            tmp=g_strdup (ptr+index+1);
            g_free (ptr);
            ptr_plus_index_less_1='\0';
            ptr=tmp;
            index=0;

        /* Normal char */
        } else {                            
            ptr_plus_index_less_1=*(ptr+index);
            ++index;
        }
    }
    g_free (ptr);

    if (argc) { /*FIXME: if argc == 1 we have no parameters  */
        argv[argc]=NULL;
    } else {
        g_free (argv);
        argv=NULL;
    }
    /*if (argc+1 > size) */
    /*    argv=g_realloc (argv, (argc+1) * sizeof(gchar *)); // not really 
usefull ... */
    debug("cmdline_to_argv() -> %p / %d\n",argv,argc);
    return argv;
}
#endif

--- NEW FILE: file_convert.h ---
#ifndef __FILE_CONVERT_H_
#define __FILE_CONVERT_H_

#ifdef HAVE_CONFIG_H
#   include <config.h>
#endif

#include <gtk/gtk.h>
#include "display_itdb.h"


extern GError *file_convert_pre_copy(Track *track);
extern GError *file_convert_post_copy(Track *track);
extern GError *file_convert_wait_for_conversion(Track *track);

/* extern gchar **cmdline_to_argv(const gchar *cmdline, Track *track); */

#endif

--- NEW FILE: flacfile.c ---
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "charset.h"
#include "itdb.h"
#include "misc.h"
#include "flacfile.h"

/* Info on how to implement new file formats: see mp3file.c for more info */

#ifdef HAVE_FLAC

#include <sys/types.h>
#include <sys/param.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <FLAC/metadata.h>
#include "prefs.h"

Track *flac_get_file_info (gchar *flacFileName)
{
    Track *track = NULL;
    FLAC__StreamMetadata stream_data;
    FLAC__StreamMetadata *tags;

    if(!FLAC__metadata_get_streaminfo (flacFileName, &stream_data))
    {
        gchar *filename = NULL;
        filename = charset_to_utf8 (flacFileName);

        gtkpod_warning (_("'%s' does not appear to be an FLAC audio file.\n"),
                        filename);
        g_free (filename);
    }
    else
    {
        ExtraTrackData *etr = NULL;

        track = gp_track_new ();
        track->description = g_strdup ("FLAC audio file");

        track->bitrate = stream_data.data.stream_info.bits_per_sample/1000;
        track->samplerate = stream_data.data.stream_info.sample_rate;
        track->tracklen = stream_data.data.stream_info.total_samples / 
(stream_data.data.stream_info.sample_rate / 1000);

        if (prefs_get_int("readtags")) 
        {
            if (!FLAC__metadata_get_tags (flacFileName, &tags)) 
            {
                gchar *filename = NULL;
                filename = charset_to_utf8 (flacFileName);
                gtkpod_warning (_("Error retrieving tags for '%s'.\n"),
                                filename);
                g_free (filename);
                /* FIXME: should NULL be returned if no tags? */
            }
            else {
                gint i;

                for (i = 0 ; i < tags->data.vorbis_comment.num_comments ; i++) 
                {
                    gchar *tag = 
(gchar*)tags->data.vorbis_comment.comments[i].entry;

                    if (g_ascii_strncasecmp("ARTIST=", tag, 7) == 0) {
                        track->artist = charset_to_utf8 (tag + 7);
                    }
                    if (g_ascii_strncasecmp("ALBUM=", tag, 6) == 0) {
                        track->album = charset_to_utf8 (tag + 6);
                    }
                    if (g_ascii_strncasecmp("TITLE=", tag, 6) == 0) {
                        track->title = charset_to_utf8 (tag + 6);
                    }
                    if (g_ascii_strncasecmp("GENRE=", tag, 6) == 0) {
                        track->genre = charset_to_utf8 (tag + 6);
                    }
                    if (g_ascii_strncasecmp("YEAR=", tag, 5) == 0) {
                        track->year = atoi (tag + 5);
                    }
                    if (g_ascii_strncasecmp("TRACKNUMBER=", tag, 12) == 0) {
                        track->track_nr = atoi (tag + 12);
                    }
                    if (g_ascii_strncasecmp("COMPOSER=", tag, 9) == 0) {
                        track->composer = charset_to_utf8 (tag + 9);
                    }
                    if (g_ascii_strncasecmp("COMMENT=", tag, 8) == 0) {
                        track->comment = charset_to_utf8 (tag + 8);
                    }
                    if (g_ascii_strncasecmp("TRACKS=", tag, 7) == 0) {
                        track->tracks = atoi (tag  + 7);
                    }
                    if (g_ascii_strncasecmp("CNDR=", tag, 5) == 0) {
                        track->cd_nr = atoi (tag + 5);
                    }
                    if (g_ascii_strncasecmp("CDS=", tag, 4) == 0) {
                        track->cds = atoi (tag  + 4);
                    }
                }
            }

            FLAC__metadata_object_delete (tags);
        }
        etr = track->userdata;
        etr->conv = g_new0(TrackConv, 1);
        etr->conv->type = FILE_TYPE_FLAC; /* FIXME: is it useful? */
        /* TODO: immediate conversion if thread ? */
    }

    return track;
}

gboolean flac_write_file_info (gchar *flacFileName, Track *track)
{
    gboolean result = FALSE;
    gtkpod_warning ("Not supported yet\n"); /* FIXME: */
    return result;
}

#else
/* We don't support FLAC without the FLAC library */
Track *flac_get_file_info (gchar *name)
{
    gtkpod_warning (_("Import of '%s' failed: FLAC not supported without the 
FLAC library. You must compile the gtkpod source together with the FLAC 
library.\n"), name);
    return NULL;
}

gboolean flac_write_file_info (gchar *filename, Track *track)
{
    gtkpod_warning (_("FLAC metadata update for '%s' failed: FLAC not supported 
without the FLAC library. You must compile the gtkpod source together with the 
FLAC library.\n"), filename);
    return FALSE;
}
#endif

--- NEW FILE: flacfile.h ---
/* Time-stamp: <2005-01-07 23:51:33 jcs>
|
|  Copyright (C) 2002-2003 Jorg Schuler <jcsjcs at users.sourceforge.net>
|  Part of the gtkpod project.
|
|  URL: http://gtkpod.sourceforge.net/
|
|  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|  iTunes and iPod are trademarks of Apple
|
|  This product is not supported/written/published by Apple!
|
|  $Id: flacfile.h,v 1.1 2007/01/16 09:44:59 jcsjcs Exp $
*/

#ifndef FLACFILEH_INCLUDED
#define FLACFILEH_INCLUDED 1

#include "itdb.h"

gboolean flac_write_file_info (gchar *filename, Track *track);
Track *flac_get_file_info (gchar *flacFileName);
#endif

--- NEW FILE: oggfile.c ---
/* Time-stamp: <2007-01-16 14:08:05 jcs>
|
|  Copyright (C) 2007 Marc d[r]eadlock <m.dreadlock at gmail com>
|  Part of the gtkpod project.
| 
|  URL: http://www.gtkpod.org/
|  URL: http://gtkpod.sourceforge.net/
|
|  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|  iTunes and iPod are trademarks of Apple
|
|  This product is not supported/written/published by Apple!
|
|  $Id: oggfile.c,v 1.1 2007/01/16 09:45:00 jcsjcs Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "charset.h"
#include "itdb.h"
#include "misc.h"
#include "oggfile.h"

/* Info on how to implement new file formats: see mp3file.c for more info */

#ifdef HAVE_LIBVORBISFILE
/* Ogg/Vorbis library (www.xiph.org) */
#include <sys/types.h>
#include <sys/param.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "vorbis/vorbisfile.h"
#include "prefs.h"

Track *ogg_get_file_info (gchar *oggFileName)
{
    Track *track = NULL;
    FILE *file= NULL;

    file=fopen(oggFileName, "rb");
    
    if (file == NULL)
    {
        gchar *filename = charset_to_utf8 (oggFileName);
        gtkpod_warning (
            _("Could not open '%s' for reading.\n"),
            filename);
        g_free (filename);
    }
    else
    {
        OggVorbis_File oggFile;
        if (ov_open(file, &oggFile, NULL , 0)!=0)
        {
            gchar *filename=NULL;
            filename= charset_to_utf8 (oggFileName);
            gtkpod_warning (_("'%s' does not appear to be an ogg audio 
file.\n"),
                            filename);
            g_free (filename);
            fclose(file);
        }
        else
        {
            TrackConv *aConv=NULL;
            ExtraTrackData *etr=NULL;
            track = gp_track_new ();
            track->description = g_strdup ("OGG audio file");
            vorbis_info *vi=ov_info(&oggFile,-1);
            /*FIXME: if (!vi) */
            track->bitrate=vi->bitrate_nominal/1000;
            track->samplerate=vi->rate;
            track->tracklen=(ov_time_total(&oggFile,-1))*1000; /* in seconds */
            if (prefs_get_int("readtags"))
            {
                vorbis_comment *vc=ov_comment(&oggFile,-1);
                if (vc) {
                    char *str;
                    if ((str=vorbis_comment_query(vc,"artist",0))!=NULL){
                        track->artist=charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"album",0))!=NULL){
                        track->album=charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"title",0))!=NULL){
                        track->title=charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"genre",0))!=NULL){
                        track->genre=charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"year",0))!=NULL){
                        track->year=atoi(str);
                    }
                    if ((str=vorbis_comment_query(vc,"tracknumber",0))!=NULL){
                        track->track_nr = atoi(str);
                    }
                    if ((str=vorbis_comment_query(vc,"composer",0))!=NULL){
                        track->composer = charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"comment",0))!=NULL){
                        track->comment = charset_to_utf8(str);
                    }
                    if ((str=vorbis_comment_query(vc,"tracks",0))!=NULL){
                        track->tracks = atoi(str);
                    }
                    if ((str=vorbis_comment_query(vc,"cdnr",0))!=NULL){
                        track->cd_nr = atoi(str);
                    }
                    if ((str=vorbis_comment_query(vc,"cds",0))!=NULL){
                        track->cds = atoi(str);
                    }
                }
                    
            }
            ov_clear(&oggFile); /* performs the fclose(file); */
            etr=track->userdata;
            aConv=g_new0(TrackConv, 1);
            etr->conv=aConv;
            aConv->type=FILE_TYPE_OGG;/* track->type; FIXME: is it usefull ?*/
            /* TODO: immediate conversion if thread ? */
        }
    }
    
    return track;
}

gboolean ogg_write_file_info (gchar *oggFileName, Track *track)
{
    gboolean result=FALSE;
    /*FIXME: seems to be not easy with common API. all other projects 
     * are using vcedit.ch from vorbis-tools (vorbiscomment). Maybe 
     * using a library could help. LibTag looks good... */
    printf("Not supported yet\n");
    return result;
}

#else
/* We don't support ogg without the vorbisfile library */
Track *ogg_get_file_info (gchar *name)
{
    gtkpod_warning (_("Import of '%s' failed: ogg not supported without the ogg 
library. You must compile the gtkpod source together with the ogg library.\n"), 
name);
    return NULL;
}

gboolean ogg_write_file_info (gchar *filename, Track *track)
{
    gtkpod_warning (_("ogg metadata update for '%s' failed: ogg not supported 
without the ogg library. You must compile the gtkpod source together with the 
ogg library.\n"), filename);
    return FALSE;
}
#endif

--- NEW FILE: oggfile.h ---
/* Time-stamp: <2005-01-07 23:51:33 jcs>
|
|  Copyright (C) 2002-2003 Jorg Schuler <jcsjcs at users.sourceforge.net>
|  Part of the gtkpod project.
|
|  URL: http://gtkpod.sourceforge.net/
|
|  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|  iTunes and iPod are trademarks of Apple
|
|  This product is not supported/written/published by Apple!
|
|  $Id: oggfile.h,v 1.1 2007/01/16 09:45:00 jcsjcs Exp $
*/

#ifndef OGGFILEH_INCLUDED
#define OGGFILEH_INCLUDED 1

#include "itdb.h"

gboolean ogg_write_file_info (gchar *filename, Track *track);
Track *ogg_get_file_info (gchar *name);
#endif

Index: Makefile.am
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/Makefile.am,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -d -r1.59 -r1.60
--- Makefile.am 22 Nov 2006 15:54:37 -0000      1.59
+++ Makefile.am 16 Jan 2007 09:44:59 -0000      1.60
@@ -59,7 +59,10 @@
     sha1.c sha1.h \
     syncdir.c syncdir.h \
     tools.c tools.h \
-    wavfile.c wavfile.h
+    wavfile.c wavfile.h \
+    oggfile.c oggfile.h \
+    flacfile.c flacfile.h \
+    file_convert.c file_convert.h
 
 gtkpod_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) @LIBOBJS@
 

Index: display_itdb.h
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/display_itdb.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- display_itdb.h      17 Nov 2006 07:40:47 -0000      1.36
+++ display_itdb.h      16 Jan 2007 09:44:59 -0000      1.37
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-17 16:33:11 jcs>
+/* Time-stamp: <2007-01-16 14:08:07 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -36,6 +36,7 @@
 
 #include <gtk/gtk.h>
 #include "itdb.h"
+#include "file.h"
 
 struct itdbs_head
 {
@@ -63,6 +64,17 @@
 
 typedef struct
 {
+    gchar   *converted_file;        /* PC filename of the "mp3" file 
+                                       != NULL if the file exists   */
+    gint32   old_size;              /* size of the original file    */
+    FileType type;                  /* type of the original file    */
+    GPid     child_pid;             /* PID of conversion process    */
+    gint     child_stdout;          /* STDOUT of conversion process */
+    gchar   *command_line;          /* used for conversion */
+} TrackConv;
+
+typedef struct
+{
   gint32  oldsize;        /* used when updating tracks: size on iPod */
   gchar   *year_str;      /* year as string -- always identical to year */
   gchar   *pc_path_locale;/* path on PC (local encoding)             */
@@ -75,6 +87,7 @@
   gchar   *charset;       /* charset used for ID3 tags               */
   gint32  sortindex;      /* used for stable sorting (current order) */
   gboolean tchanged;      /* temporary use, e.g. in detail.c         */
+  TrackConv *conv;        /* to convert file */
 } ExtraTrackData;
 
 /* types for iTunesDB */

Index: display_tracks.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/display_tracks.c,v
retrieving revision 1.114
retrieving revision 1.115
diff -u -d -r1.114 -r1.115
--- display_tracks.c    26 Nov 2006 05:49:48 -0000      1.114
+++ display_tracks.c    16 Jan 2007 09:44:59 -0000      1.115
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-26 14:48:28 jcs>
+/* Time-stamp: <2007-01-16 18:29:49 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -1643,7 +1643,7 @@
 
 void tm_adopt_order_in_sorttab (void)
 {
-    if (prefs_get_int("tm_sort_") == SORT_NONE)
+    if (prefs_get_int("tm_sort") == SORT_NONE)
     {
        GList *gl, *tracks = NULL;
 
@@ -1665,7 +1665,7 @@
     {
        GtkTreeModel *model= gtk_tree_view_get_model (track_treeview);
 
-       prefs_set_int("tm_sort_", SORT_NONE);
+       prefs_set_int("tm_sort", SORT_NONE);
        if (!BROKEN_GTK_TREE_SORT)
        {
 /* no need to comment this out -- searching still works, but for lack
@@ -1784,7 +1784,7 @@
     }
     else
     {
-       prefs_set_int("tm_sort_", order);
+       prefs_set_int("tm_sort", order);
     }
     prefs_set_int("tm_sortcol", newcol);
 
@@ -2184,7 +2184,7 @@
                    (gpointer)0);
 
   /* initialize sorting */
-  tm_sort (prefs_get_int("tm_sortcol"), prefs_get_int("tm_sort_"));
+  tm_sort (prefs_get_int("tm_sortcol"), prefs_get_int("tm_sort"));
   /* set correct column for typeahead */
   if (prefs_get_int_value (TM_PREFS_SEARCH_COLUMN, &col))
   {
@@ -2281,7 +2281,7 @@
            fprintf (stderr, "Programming error: disable_count < 0\n");
        if (disable_count == 0 && track_treeview)
        {
-           if ((prefs_get_int("tm_sort_") != SORT_NONE) &&
+           if ((prefs_get_int("tm_sort") != SORT_NONE) &&
                sorting_disabled())
            {
                /* Re-enable sorting */
@@ -2298,7 +2298,7 @@
                    gtk_tree_sortable_set_sort_column_id (
                        GTK_TREE_SORTABLE (model),
                        prefs_get_int("tm_sortcol"),
-                       prefs_get_int("tm_sort_"));
+                       prefs_get_int("tm_sort"));
                }
            }
        }
@@ -2307,7 +2307,7 @@
     {
        if (disable_count == 0 && track_treeview)
        {
-           if ((prefs_get_int("tm_sort_") != SORT_NONE) &&
+           if ((prefs_get_int("tm_sort") != SORT_NONE) &&
                sorting_disabled ())
            {
                /* Disable sorting */
@@ -2324,7 +2324,7 @@
                    gtk_tree_sortable_set_sort_column_id (
                        GTK_TREE_SORTABLE (model),
                        GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
-                       prefs_get_int("tm_sort_"));
+                       prefs_get_int("tm_sort"));
                }
            }
        }

Index: file.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/file.c,v
retrieving revision 1.192
retrieving revision 1.193
diff -u -d -r1.192 -r1.193
--- file.c      26 Nov 2006 05:49:48 -0000      1.192
+++ file.c      16 Jan 2007 09:44:59 -0000      1.193
@@ -53,7 +53,8 @@
 #include "mp4file.h"
 #include "prefs.h"
 #include "wavfile.h"
-
+#include "oggfile.h"
+#include "flacfile.h"
 
 static const gchar *imageext[] =
 {".jpg", ".jpeg", ".png", ".pbm", ".pgm", ".ppm", ".tif", ".tiff",
@@ -95,6 +96,8 @@
     case FILE_TYPE_PLS:
     case FILE_TYPE_IMAGE:
     case FILE_TYPE_DIRECTORY:
+    case FILE_TYPE_OGG:
+    case FILE_TYPE_FLAC:
        g_free (track);
        g_return_val_if_reached (NULL);
     }
@@ -138,6 +141,8 @@
 
        else if (g_strcasecmp (suf, ".m3u") == 0) type = FILE_TYPE_M3U;
        else if (g_strcasecmp (suf, ".pls") == 0) type = FILE_TYPE_PLS;
+        else if (g_strcasecmp (suf, ".ogg") == 0) type = FILE_TYPE_OGG;
+        else if (g_strcasecmp (suf, ".flac") == 0) type = FILE_TYPE_FLAC;
 
        else
        {
@@ -253,6 +258,8 @@
        case FILE_TYPE_MP4:
        case FILE_TYPE_MOV:
        case FILE_TYPE_MPG:
+        case FILE_TYPE_OGG:
+        case FILE_TYPE_FLAC:
        case FILE_TYPE_IMAGE:
        case FILE_TYPE_DIRECTORY:
            gtkpod_warning (_("'%s' is a not a known playlist file.\n\n"),
@@ -348,6 +355,8 @@
        case FILE_TYPE_MP4:
        case FILE_TYPE_MOV:
        case FILE_TYPE_MPG:
+       case FILE_TYPE_OGG:
+        case FILE_TYPE_FLAC:
        case FILE_TYPE_IMAGE:
            break;
        }
@@ -1090,6 +1099,22 @@
            nti->mediatype = 0x00000001;
        }
        break;
+    case FILE_TYPE_OGG:
+        nti = ogg_get_file_info (name);
+        /* Set unk208 to audio */
+        if (nti)
+        {
+            nti->mediatype = 0x00000001;
+        }
+        break;
+    case FILE_TYPE_FLAC:
+        nti = flac_get_file_info (name);
+        /* Set unk208 to audio */
+        if (nti)
+        {
+            nti->mediatype = 0x00000001;
+        }
+        break;
     case FILE_TYPE_M4V:
     case FILE_TYPE_MP4:
        /* I don't know if .m4v and .mp4 can simply be handled like
@@ -1720,6 +1745,8 @@
   case FILE_TYPE_MP4:
   case FILE_TYPE_MOV:
   case FILE_TYPE_MPG:
+  case FILE_TYPE_OGG:
+  case FILE_TYPE_FLAC:
   case FILE_TYPE_IMAGE:
   case FILE_TYPE_UNKNOWN:
   case FILE_TYPE_DIRECTORY:
@@ -1905,6 +1932,10 @@
        return mp4_write_file_info (name, track);
     case FILE_TYPE_WAV:
        return wav_write_file_info (name, track);
+    case FILE_TYPE_OGG:
+        return ogg_write_file_info (name, track);
+    case FILE_TYPE_FLAC:
+        return flac_write_file_info (name, track);
     case FILE_TYPE_M4V:
     case FILE_TYPE_MP4:
     case FILE_TYPE_MOV:
@@ -2221,6 +2252,8 @@
        case FILE_TYPE_M4B:
            result = mp4_read_soundcheck (path, track);
            break;
+        case FILE_TYPE_OGG: /* FIXME */
+        case FILE_TYPE_FLAC: /* FIXME */
        case FILE_TYPE_WAV: /* FIXME */
        case FILE_TYPE_M4V:
        case FILE_TYPE_MP4:

Index: file.h
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/file.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- file.h      1 Sep 2006 13:18:42 -0000       1.55
+++ file.h      16 Jan 2007 09:44:59 -0000      1.56
@@ -53,6 +53,8 @@
     FILE_TYPE_MOV,
     FILE_TYPE_MPG,
     FILE_TYPE_M3U,
+    FILE_TYPE_OGG,
+    FILE_TYPE_FLAC,
     FILE_TYPE_PLS,
     FILE_TYPE_IMAGE,
     FILE_TYPE_DIRECTORY

Index: file_itunesdb.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/file_itunesdb.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -d -r1.103 -r1.104
--- file_itunesdb.c     22 Nov 2006 15:54:37 -0000      1.103
+++ file_itunesdb.c     16 Jan 2007 09:44:59 -0000      1.104
@@ -46,6 +46,12 @@
 #include "tools.h"
 #include "ipod_init.h"
 #include "lastfm.h"
+#include "file_convert.h"
+
+#define _TO_STR(x) #x
+#define TO_STR(x) _TO_STR(x)
+#define debug(s) printf(__FILE__":" TO_STR(__LINE__) ":" s)
+#define debugx(s,...) printf(__FILE__":" TO_STR(__LINE__) ":" s,__VA_ARGS__)
 
 /*------------------------------------------------------------------*\
  *                                                                  *
@@ -415,6 +421,7 @@
     else
        offline = FALSE;
 
+
     block_widgets ();
     if (offline || (type & GP_ITDB_TYPE_LOCAL))
     { /* offline or local database - requires extended info */
@@ -775,7 +782,6 @@
     if (new_itdb)
     {
        gp_replace_itdb (old_itdb, new_itdb);
-
        /* take care of autosync... */
        sync_all_playlists (new_itdb);
 
@@ -1177,8 +1183,27 @@
     g_return_val_if_fail (track, NULL);
     etr = track->userdata;
     g_return_val_if_fail (etr, NULL);
+    gchar *file_to_transfer=etr->pc_path_locale;
 
-    itdb_cp_track_to_ipod (track, etr->pc_path_locale, &error);
+
+    if (etr->conv!=NULL)
+    {
+        error = file_convert_pre_copy(track);
+        if (!error) 
+        {
+            error= file_convert_wait_for_conversion(track);
+            if (!error)
+                file_to_transfer=etr->conv->converted_file;
+        }
+    }
+
+    if (error == NULL)
+    {
+        fprintf(stderr,"Trying to copy: %s\n",file_to_transfer);
+        itdb_cp_track_to_ipod (track, file_to_transfer, &error);
+        if (etr->conv != NULL)
+            file_convert_post_copy(track);
+    }
 
     /* delete old size */
     if (track->transferred) etr->oldsize = 0;

Index: misc.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/misc.c,v
retrieving revision 1.213
retrieving revision 1.214
diff -u -d -r1.213 -r1.214
--- misc.c      27 Jun 2006 16:30:02 -0000      1.213
+++ misc.c      16 Jan 2007 09:44:59 -0000      1.214
@@ -1,5 +1,5 @@
 /* -*- coding: utf-8; -*-
-|  Time-stamp: <2006-06-28 01:21:08 jcs>
+|  Time-stamp: <2007-01-16 17:50:45 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -47,6 +47,11 @@
 
 #define DEBUG_MISC 0
 
+
+/* where to find the scripts */
+const gchar *SCRIPTDIR = PACKAGE_DATA_DIR G_DIR_SEPARATOR_S PACKAGE 
G_DIR_SEPARATOR_S "scripts" G_DIR_SEPARATOR_S;
+
+
 /*------------------------------------------------------------------*\
  *                                                                  *
  *             About Window                                         *

Index: misc.h
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/misc.h,v
retrieving revision 1.119
retrieving revision 1.120
diff -u -d -r1.119 -r1.120
--- misc.h      24 Jun 2006 15:39:22 -0000      1.119
+++ misc.h      16 Jan 2007 09:44:59 -0000      1.120
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-06-25 00:25:35 jcs>
+/* Time-stamp: <2007-01-16 17:50:43 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -46,6 +46,9 @@
 
 #define C_FREE(a) {g_free(a); a=NULL;}
 
+/* where to find the scripts */
+extern const gchar *SCRIPTDIR;
+
 /* version of GTK_CHECK_VERSION that uses the runtime variables
    gtk_*_version... instead of the compile-time constants
    GTK_*_VERSION */
@@ -105,7 +108,9 @@
 gboolean parse_tracks_from_string(gchar **s, Track **track);
 gboolean gtkpod_main_quit(void);
 
+gchar *get_allowed_percent_char(void);
 T_item TM_to_T (TM_item sm);
+T_item char_to_T (char c);
 T_item ST_to_T (ST_CAT_item st);
 const gchar *get_tm_string (TM_item tm);
 const gchar *get_tm_tooltip (TM_item tm);

Index: misc_conversion.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/misc_conversion.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- misc_conversion.c   21 Sep 2006 15:03:13 -0000      1.28
+++ misc_conversion.c   16 Jan 2007 09:44:59 -0000      1.29
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-09-21 23:16:41 jcs>
+/* Time-stamp: <2007-01-16 14:08:05 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -197,6 +197,53 @@
 }
 
 
+/* See track_get_item() / track_get_item_pointer()  */
+gchar *get_allowed_percent_char(void )
+{
+    return g_strdup("latgcoysSny");
+}
+/* translates a char into a T_... (defined in display.h) */
+T_item char_to_T(gchar c){
+    switch (c) {
+        case 'l': return T_ALBUM;
+        case 'a': return T_ARTIST;
+        case 't': return T_TITLE;
+        case 'g': return T_GENRE;
+        case 'c': return T_COMMENT;
+        case 'o': return T_COMPOSER;
+        case 'f': return T_FILETYPE;
+        case 's': return T_PC_PATH;
+        case 'S': return T_IPOD_PATH;
+           /* case 'i': return T_IPOD_ID; */
+        case 'n': return T_TRACK_NR;
+           /* case 'f': return T_TRANSFERRED; */
+           /* case 'z': return T_SIZE; */
+           /* case 'L': return T_TRACKLEN; */
+           /* case 'b': return T_BITRATE; */
+           /* case 'r': return T_SAMPLERATE; */
+           /* case 'b': return T_BPM; */
+           /* case 'C': return T_PLAYCOUNT; */
+           /* case 'i': return T_RATING; */
+           /* case '': return T_TIME_ADDED; */
+           /* case '': return T_TIME_PLAYED; */
+           /* case '': return T_TIME_MODIFIED; */
+           /* case '': return T_VOLUME; */
+           /* case '': return T_SOUNDCHECK; */
+        case 'y': return T_YEAR;
+           /* case 'd': return T_CD_NR; */
+           /* case '': return T_GROUPING; */
+           /* case '': return T_COMPILATION; */
+           /* case '': return T_CATEGORY; */
+           /* case '': return T_DESCRIPTION; */
+           /* case '': return T_PODCASTURL; */
+           /* case '': return T_PODCASTRSS; */
+           /* case '': return T_SUBTITLE; */
+           /* case '': return T_TIME_RELEASED; */
+           /* case '': return T_CHECKED; */
+    }
+    return -1;
+}
+
 /* translates a ST_CAT_... (defined in display.h) into a
  * T_... (defined in display.h). Returns -1 in case a translation is not
  * possible */

Index: misc_track.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/misc_track.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- misc_track.c        22 Nov 2006 15:48:19 -0000      1.54
+++ misc_track.c        16 Jan 2007 09:44:59 -0000      1.55
@@ -342,6 +342,7 @@
 
    g_return_if_fail (itdb);
 
+
    if (!prefs_get_int("md5")) return;
 
    ns = itdb_tracks_number (itdb);
@@ -1495,6 +1496,8 @@
                    case FILE_TYPE_MP4:
                    case FILE_TYPE_MOV:
                    case FILE_TYPE_MPG:
+                    case FILE_TYPE_OGG:
+                    case FILE_TYPE_FLAC:
                        if (!pl)
                        {  /* no playlist yet -- create new one */
                            pl = add_new_pl_user_name (itdb, NULL,

Index: prefs.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/prefs.c,v
retrieving revision 1.272
retrieving revision 1.273
diff -u -d -r1.272 -r1.273
--- prefs.c     24 Nov 2006 06:48:25 -0000      1.272
+++ prefs.c     16 Jan 2007 09:45:00 -0000      1.273
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-10-14 19:04:40 jcs>
+/* Time-stamp: <2007-01-16 18:34:24 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Copyright (C) 2006 James Liggett <jrliggett at cox.net>
@@ -136,7 +136,7 @@
 static void set_default_preferences()
 {
     int i;
-    gchar *dir; /* Last directory browsed to */
+    gchar *str;
 
     prefs_set_int("update_existing", FALSE);
     prefs_set_int("id3_write", FALSE);
@@ -156,7 +156,16 @@
     prefs_set_string ("path_play_now", "xmms %s");
     prefs_set_string ("path_play_enqueue", "xmms -e %s");
     prefs_set_string ("path_mserv_trackinfo_root", 
"/var/lib/mserv/trackinfo/");
-  
+
+    str = g_build_filename (SCRIPTDIR, "convert-ogg2mp3.sh", NULL);
+    prefs_set_string ("path_conv_ogg", str);
+    g_free (str);
+
+    str = g_build_filename (SCRIPTDIR, "convert-flac2mp3.sh", NULL);
+    prefs_set_string ("path_conv_flac", str);
+    g_free (str);
+
+
     /* Set sorting tab defaults */
     for (i = 0; i < SORT_TAB_MAX; i++)
     {
@@ -251,12 +260,12 @@
     prefs_set_string("export_template", "%o;%a - %t.mp3;%t.wav");
 
     /* Set last browsed directory */
-    dir = g_get_current_dir();
+    str = g_get_current_dir();
 
-    if (dir)
+    if (str)
     {
-       prefs_set_string("last_dir_browsed", dir);
-       g_free(dir);
+       prefs_set_string("last_dir_browsed", str);
+       g_free(str);
     }
     else
        prefs_set_string("last_dir_browsed", g_get_home_dir());
@@ -267,7 +276,7 @@
     prefs_set_int("st_sort", SORT_NONE);
     prefs_set_int("pm_sort", SORT_NONE);
     prefs_set_int("tm_sortcol", TM_COLUMN_TITLE);
-    prefs_set_int("tm_sort_", SORT_NONE);
+    prefs_set_int("tm_sort", SORT_NONE);
 }
 
 /* Initialize default variable-length list entries */
@@ -708,6 +717,15 @@
        prefs_set_string("coverart", NULL);
     }
   
+    /* rename tm_sort_ to tm_sort */
+    if (prefs_get_string_value("tm_sort_", &buf))
+    {
+       prefs_set_string("tm_sort", buf);
+       g_free(buf);
+       prefs_set_string("tm_sort_", NULL);
+    }
+
+
     /* Convert old path numbered keys to named ones */
   
   
@@ -971,7 +989,7 @@
     /* sm_sort_ renamed to tm_sort */
     if (prefs_get_int_value("sm_sort_", &int_buf))
     {
-       prefs_set_int("tm_sort_", int_buf);
+       prefs_set_int("tm_sort", int_buf);
        prefs_set_string("sm_sort_", NULL);
     }
 

Index: prefs_window.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/prefs_window.c,v
retrieving revision 1.188
retrieving revision 1.189
diff -u -d -r1.188 -r1.189
--- prefs_window.c      22 Nov 2006 15:54:38 -0000      1.188
+++ prefs_window.c      16 Jan 2007 09:45:00 -0000      1.189
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-11-23 00:50:17 jcs>
+/* Time-stamp: <2007-01-16 18:29:48 jcs>
 |
 |  Copyright (C) 2002 Corey Donohoe <atmos at atmos.org>
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
@@ -70,8 +70,6 @@
 
 
 /* Definition of path button names.
-   E.g. path_button_names[PATH_PLAY_ENQUEUE] is
-   "play_enqueue_path_button".
    path_fileselector_titles[] specifies the title for the file
    chooser. path_type[] specifies whether to browse for dirs or for
    files.
@@ -81,12 +79,11 @@
     "play_now_path_button",
     "play_enqueue_path_button",
     "mp3gain_path_button",
-    "",
-    "",
+    "aacgain_path_button",
     "mserv_music_root_button",
     "mserv_trackinfo_root_button",
-    "",
-    "aacgain_path_button",
+    "path_conv_ogg_button",
+    "path_conv_flac_button",
     NULL
 };
 static const gchar *path_key_names[] =
@@ -94,12 +91,11 @@
     "path_play_now",
     "path_play_enqueue",
     "path_mp3gain",
-    "",
-    "",
+    "aacgain_path",
     "path_mserv_music_root",
     "path_mserv_trackinfo_root",
-    "",
-    "aacgain_path",
+    "path_conv_ogg",
+    "path_conv_flac",
     NULL
 };
 const gchar *path_entry_names[] =
@@ -107,12 +103,11 @@
     "play_now_path_entry",
     "play_enqueue_path_entry",
     "mp3gain_path_entry",
-    "",
-    "",
+    "aacgain_path_entry",
     "mserv_music_root_entry",
     "mserv_trackinfo_root_entry",
-    "",
-    "aacgain_path_entry",
+    "path_conv_ogg_entry",
+    "path_conv_flac_entry",
     NULL
 };
 static const gchar *path_fileselector_titles[] =
@@ -120,12 +115,11 @@
     N_("Please select command for 'Play Now'"),
     N_("Please select command for 'Enqueue'"),
     N_("Please select the mp3gain executable"),
-    "",
-    "",
+    N_("Please select the aacgain executable"),
     N_("Select the mserv music root directory"),
     N_("Select the mserv trackinfo root directory"),
-    "",
-    N_("Please select the aacgain executable"),
+    N_("Select the ogg/vorbis converter command"),
+    N_("Select the flac converter command"),
     NULL
 };
 static const GtkFileChooserAction path_type[] =
@@ -134,7 +128,6 @@
     GTK_FILE_CHOOSER_ACTION_OPEN,
     GTK_FILE_CHOOSER_ACTION_OPEN,
     GTK_FILE_CHOOSER_ACTION_OPEN,
-    GTK_FILE_CHOOSER_ACTION_OPEN,
     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, /* select folder */
     GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
     GTK_FILE_CHOOSER_ACTION_OPEN,
@@ -142,7 +135,6 @@
     -1
 };
 
-
 static void on_cfg_st_autoselect_toggled (GtkToggleButton *togglebutton,
                                          gpointer         user_data)
 {
@@ -175,6 +167,8 @@
 {
     gint i = GPOINTER_TO_INT (user_data);
     gchar *oldpath, *newpath;
+    gchar *fallback = NULL;
+    gchar *text = NULL;
 
     g_return_if_fail (temp_prefs);
 
@@ -184,15 +178,23 @@
        oldpath = prefs_get_string (path_key_names[i]);
     }
 
+    /* initialize fallback path with something reasonable */
+    if ((strcmp (path_key_names[i], "path_conv_ogg") == 0) ||
+       (strcmp (path_key_names[i], "path_conv_flac") == 0))
+    {
+       fallback = g_strdup (SCRIPTDIR);
+       text = g_markup_printf_escaped (_("<i>Have a look at the scripts 
provided in '%s'. If you write a new script or improve an existing one, please 
send it to jcsjcs at users.sourceforge.net for inclusion into the next 
release.</i>"), SCRIPTDIR);
+    }
+
     switch (path_type[i])
     {
     case GTK_FILE_CHOOSER_ACTION_OPEN:
        /* script */
        newpath = fileselection_select_script (
            oldpath,
-           NULL,
+           fallback,
            _(path_fileselector_titles[i]),
-           NULL);
+           text);
        break;
     case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
        /* directory */
@@ -205,6 +207,8 @@
        g_return_if_reached ();
     }
     g_free (oldpath);
+    g_free (fallback);
+    g_free (text);
 
     if (newpath)
     {
@@ -1723,7 +1727,7 @@
        if (w)
            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE);
 
-       switch (prefs_get_int("tm_sort_"))
+       switch (prefs_get_int("tm_sort"))
        {
        case SORT_ASCENDING:
            w = gtkpod_xml_get_widget (sort_window_xml, "tm_ascend");
@@ -1840,11 +1844,11 @@
        pm_sort (val);
     if (temp_prefs_get_int_value(sort_temp_prefs, "st_sort", &val))
        st_sort (val);
-    if (temp_prefs_get_int_value(sort_temp_prefs, "tm_sort_", NULL) ||
+    if (temp_prefs_get_int_value(sort_temp_prefs, "tm_sort", NULL) ||
        (sortcol_old != sortcol_new))
     {
        tm_sort_counter (-1);
-       tm_sort (prefs_get_int("tm_sortcol"), prefs_get_int("tm_sort_"));
+       tm_sort (prefs_get_int("tm_sortcol"), prefs_get_int("tm_sort"));
     }
     /* if auto sort was changed to TRUE, store order */
     if (!temp_prefs_get_int(sort_temp_prefs, "tm_autostore"))
@@ -2067,7 +2071,7 @@
 
 void sort_window_set_tm_sort (gint val)
 {
-    temp_prefs_set_int(sort_temp_prefs, "tm_sort_", val);
+    temp_prefs_set_int(sort_temp_prefs, "tm_sort", val);
 }
 
 void sort_window_set_case_sensitive (gboolean val)

Index: repository.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/repository.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- repository.c        25 Jun 2006 16:08:22 -0000      1.15
+++ repository.c        16 Jan 2007 09:45:00 -0000      1.16
@@ -1,4 +1,4 @@
-/* Time-stamp: <2006-06-25 21:40:01 jcs>
+/* Time-stamp: <2007-01-16 17:55:41 jcs>
 |
 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
 |  Part of the gtkpod project.
@@ -63,9 +63,6 @@
 
 typedef struct _RepWin RepWin;
 
-/* where to find the scripts */
-static const gchar *scriptdir = PACKAGE_DATA_DIR G_DIR_SEPARATOR_S PACKAGE 
G_DIR_SEPARATOR_S "scripts" G_DIR_SEPARATOR_S;
-
 typedef enum
 {
     IPOD_SYNC_CONTACTS,
@@ -662,10 +659,10 @@
     oldpath = prefs_get_string (key);
     g_free (key);
 
-    text = g_markup_printf_escaped (_("<i>Have a look at the scripts provided 
in '%s'. If you write a new script, please send it to jcsjcs at 
users.sourceforge.net for inclusion into the next release.</i>"), scriptdir);
+    text = g_markup_printf_escaped (_("<i>Have a look at the scripts provided 
in '%s'. If you write a new script or improve an existing one, please send it 
to jcsjcs at users.sourceforge.net for inclusion into the next release.</i>"), 
SCRIPTDIR);
 
     newpath = fileselection_select_script (oldpath,
-                                          scriptdir,
+                                          SCRIPTDIR,
                                           title,
                                           text);
     g_free (oldpath);

Index: syncdir.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/syncdir.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- syncdir.c   24 Sep 2006 06:42:52 -0000      1.7
+++ syncdir.c   16 Jan 2007 09:45:00 -0000      1.8
@@ -358,6 +358,8 @@
                case FILE_TYPE_MP4:
                case FILE_TYPE_MOV:
                case FILE_TYPE_MPG:
+                case FILE_TYPE_OGG:
+                case FILE_TYPE_FLAC:
                    tr = gp_track_by_filename (pl->itdb, filename);
                    if (tr)
                    {   /* track is known -> add to playlist if not

Index: tools.c
===================================================================
RCS file: /cvsroot/gtkpod/gtkpod/src/tools.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- tools.c     23 Jun 2006 16:46:12 -0000      1.49
+++ tools.c     16 Jan 2007 09:45:00 -0000      1.50
@@ -260,6 +260,8 @@
            }
            break;
        case FILE_TYPE_WAV: /* FIXME */
+       case FILE_TYPE_OGG: /* FIXME */
+       case FILE_TYPE_FLAC: /* FIXME */
        case FILE_TYPE_M4V:
        case FILE_TYPE_MP4:
        case FILE_TYPE_MOV:


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to