Changeset 3380


Ignore:
Timestamp:
Oct 12, 2007, 7:53:30 PM (15 years ago)
Author:
charles
Message:

code cleanup: let glib do more of the heavy lifting w.r.t. parsing command-line arguments, drag-and-drop strings

Location:
trunk/gtk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/dialogs.c

    r3352 r3380  
    7070};
    7171
    72 struct infowind
    73 {
    74     GtkWidget             * widget;
    75     TrTorrent             * tor;
    76     int64_t                 size;
    77     GtkTreeModel          * model;
    78     GtkTreeRowReference   * row;
    79     GtkTreeModel          * filesmodel;
    80     guint                   timer;
    81     struct
    82     {
    83         tr_tracker_info   * track;
    84         GtkLabel          * trackwid;
    85         GtkLabel          * annwid;
    86         GtkLabel          * scrwid;
    87         int                 seed;
    88         GtkLabel          * seedwid;
    89         int                 leech;
    90         GtkLabel          * leechwid;
    91         int                 done;
    92         GtkLabel          * donewid;
    93         uint64_t            up;
    94         GtkLabel          * upwid;
    95         uint64_t            down;
    96         GtkLabel          * downwid;
    97         uint64_t            left;
    98         GtkLabel          * leftwid;
    99     }                       inf;
    100 };
    101 
    10272static void
    10373addwindnocore( gpointer gdata, GObject * core );
  • trunk/gtk/main.c

    r3353 r3380  
    2525#include <sys/param.h>
    2626#include <errno.h>
    27 #include <getopt.h>
    2827#include <signal.h>
    2928#include <string.h>
     
    124123static sig_atomic_t global_sigcount = 0;
    125124
    126 static GList *
    127 readargs( int argc, char ** argv, gboolean * sendquit, gboolean * paused );
    128125static gboolean
    129126sendremote( GList * files, gboolean sendquit );
    130 static void
    131 gtksetup( int * argc, char *** argv, struct cbdata* );
    132127static void
    133128appsetup( TrWindow * wind, GList * args,
     
    219214main( int argc, char ** argv )
    220215{
     216    char * err;
    221217    struct cbdata * cbdata = g_new (struct cbdata, 1);
    222     char       * err;
    223     benc_val_t * state;
    224     GList      * argfiles;
    225     gboolean     didinit, didlock, sendquit, startpaused;
    226 
    227     argfiles = readargs( argc, argv, &sendquit, &startpaused );
     218    GList * argfiles;
     219    gboolean didinit, didlock, sendquit, startpaused;
     220    char * domain = "transmission";
     221    GOptionEntry entries[] = {
     222        { "paused", 'p', 0, G_OPTION_ARG_NONE, &startpaused, _("Start with all torrents paused"), NULL },
     223        { "quit", 'q', 0, G_OPTION_ARG_NONE, &sendquit, _( "Request that the running instance quit"), NULL },
     224        { NULL, 0, 0, 0, NULL, NULL, NULL }
     225    };
     226
     227    /* bind the gettext domain */
     228    bindtextdomain( domain, TRANSMISSIONLOCALEDIR );
     229    bind_textdomain_codeset( domain, "UTF-8" );
     230    textdomain( domain );
     231    g_set_application_name( _( "Transmission" ) );
     232
     233    /* initialize gtk */
     234    gtk_init_with_args( &argc, &argv, _("[torrent files]"), entries, domain, NULL );
     235    myUIManager = gtk_ui_manager_new ();
     236    actions_init ( myUIManager, cbdata );
     237    gtk_ui_manager_add_ui_from_string (myUIManager, fallback_ui_file, -1, NULL);
     238    gtk_ui_manager_ensure_update (myUIManager);
     239    gtk_window_set_default_icon_name ( "transmission-logo" );
     240
     241    argfiles = checkfilenames( argc-1, argv+1 );
    228242    didinit = cf_init( tr_getPrefsDirectory(), NULL );
    229243    didlock = FALSE;
     
    234248    }
    235249    setupsighandlers();         /* set up handlers for fatal signals */
    236     gtksetup( &argc, &argv, cbdata );   /* set up gtk and gettext */
    237250
    238251    if( ( didinit || cf_init( tr_getPrefsDirectory(), &err ) ) &&
    239252        ( didlock || cf_lock( &err ) ) )
    240253    {
    241         GtkWindow  * mainwind;
     254        GtkWindow * mainwind;
     255        benc_val_t * state;
    242256
    243257        /* create main window now to be a parent to any error dialogs */
     
    271285}
    272286
    273 GList *
    274 readargs( int argc, char ** argv, gboolean * sendquit, gboolean * startpaused )
    275 {
    276     struct option opts[] =
    277     {
    278         { "help",    no_argument, NULL, 'h' },
    279         { "paused",  no_argument, NULL, 'p' },
    280         { "quit",    no_argument, NULL, 'q' },
    281         { "version", no_argument, NULL, 'v' },
    282         { NULL, 0, NULL, 0 }
    283     };
    284     int          opt;
    285     const char * name;
    286 
    287     *sendquit    = FALSE;
    288     *startpaused = FALSE;
    289 
    290     gtk_parse_args( &argc, &argv );
    291     name = g_get_prgname();
    292 
    293     while( 0 <= ( opt = getopt_long( argc, argv, "hpqv", opts, NULL ) ) )
    294     {
    295         switch( opt )
    296         {
    297             case 'p':
    298                 *startpaused = TRUE;
    299                 break;
    300             case 'q':
    301                 *sendquit = TRUE;
    302                 break;
    303             case 'v':
    304             case 'h':
    305                 printf(
    306 _("usage: %s [-hpq] [files...]\n"
    307   "\n"
    308   "Transmission %s http://transmission.m0k.org/\n"
    309   "A free, lightweight BitTorrent client with a simple, intuitive interface\n"
    310   "\n"
    311   "  -h --help    display this message and exit\n"
    312   "  -p --paused  start with all torrents paused\n"
    313   "  -q --quit    request that the running %s instance quit\n"
    314   "\n"
    315   "Only one instance of %s may run at one time. Multiple\n"
    316   "torrent files may be loaded at startup by adding them to the command\n"
    317   "line. If %s is already running, those torrents will be\n"
    318   "opened in the running instance.\n"),
    319                         name, LONG_VERSION_STRING,
    320                         name, name, name );
    321                 exit(0);
    322                 break;
    323         }
    324     }
    325 
    326     argc -= optind;
    327     argv += optind;
    328 
    329     return checkfilenames( argc, argv );
    330 }
    331 
    332287static gboolean
    333288sendremote( GList * files, gboolean sendquit )
     
    357312
    358313    return didlock;
    359 }
    360 
    361 static void
    362 gtksetup( int * argc, char *** argv, struct cbdata * callback_data )
    363 {
    364 
    365     bindtextdomain( "transmission", TRANSMISSIONLOCALEDIR );
    366     bind_textdomain_codeset( "transmission", "UTF-8" );
    367     textdomain( "transmission" );
    368 
    369     g_set_application_name( _("Transmission") );
    370     gtk_init( argc, argv );
    371 
    372     /* connect up the actions */
    373     myUIManager = gtk_ui_manager_new ();
    374     actions_init ( myUIManager, callback_data );
    375     gtk_ui_manager_add_ui_from_string (myUIManager, fallback_ui_file, -1, NULL);
    376     gtk_ui_manager_ensure_update (myUIManager);
    377 
    378     /* tweak some style properties in dialogs to get closer to the GNOME HiG */
    379     gtk_rc_parse_string(
    380         "style \"transmission-standard\"\n"
    381         "{\n"
    382         "    GtkDialog::action-area-border  = 6\n"
    383         "    GtkDialog::button-spacing      = 12\n"
    384         "    GtkDialog::content-area-border = 6\n"
    385         "}\n"
    386         "widget \"TransmissionDialog\" style \"transmission-standard\"\n" );
    387 
    388     gtk_window_set_default_icon_name ( "transmission-logo" );
    389314}
    390315
     
    581506
    582507static void
    583 gotdrag(GtkWidget *widget SHUTUP, GdkDragContext *dc, gint x SHUTUP,
    584         gint y SHUTUP, GtkSelectionData *sel, guint info SHUTUP, guint time,
    585         gpointer gdata) {
    586   struct cbdata *data = gdata;
    587   char prefix[] = "file:";
    588   char *files, *decoded, *deslashed, *hostless;
    589   int ii, len;
    590   GList *errs;
    591   struct stat sb;
    592   int prelen = strlen(prefix);
    593   GList *paths, *freeables;
    594   enum tr_torrent_action action;
     508gotdrag( GtkWidget         * widget UNUSED,
     509         GdkDragContext    * dc,
     510         gint                x UNUSED,
     511         gint                y UNUSED,
     512         GtkSelectionData  * sel,
     513         guint               info UNUSED,
     514         guint               time,
     515         gpointer            gdata )
     516{
     517    struct cbdata * data = gdata;
     518    GList * paths = NULL;
     519    GList * freeme = NULL;
    595520
    596521#ifdef DND_DEBUG
    597   char *sele = gdk_atom_name(sel->selection);
    598   char *targ = gdk_atom_name(sel->target);
    599   char *type = gdk_atom_name(sel->type);
    600 
    601   fprintf(stderr, "dropped file: sel=%s targ=%s type=%s fmt=%i len=%i\n",
    602           sele, targ, type, sel->format, sel->length);
    603   g_free(sele);
    604   g_free(targ);
    605   g_free(type);
    606   if(8 == sel->format) {
    607     for(ii = 0; ii < sel->length; ii++)
    608       fprintf(stderr, "%02X ", sel->data[ii]);
    609     fprintf(stderr, "\n");
    610   }
     522    char *sele = gdk_atom_name(sel->selection);
     523    char *targ = gdk_atom_name(sel->target);
     524    char *type = gdk_atom_name(sel->type);
     525
     526    fprintf(stderr, "dropped file: sel=%s targ=%s type=%s fmt=%i len=%i\n",
     527            sele, targ, type, sel->format, sel->length);
     528    g_free(sele);
     529    g_free(targ);
     530    g_free(type);
     531    if( sel->format == 8 ) {
     532        for( i=0; i<sel->length; ++i )
     533            fprintf(stderr, "%02X ", sel->data[i]);
     534        fprintf(stderr, "\n");
     535    }
    611536#endif
    612537
    613   errs = NULL;
    614   paths = NULL;
    615   freeables = NULL;
    616   if(gdk_atom_intern("XdndSelection", FALSE) == sel->selection &&
    617      8 == sel->format) {
    618     /* split file list on carriage returns and linefeeds */
    619     files = g_new(char, sel->length + 1);
    620     memcpy(files, sel->data, sel->length);
    621     files[sel->length] = '\0';
    622     for(ii = 0; '\0' != files[ii]; ii++)
    623       if('\015' == files[ii] || '\012' == files[ii])
    624         files[ii] = '\0';
    625 
    626     /* try to get a usable filename out of the URI supplied and add it */
    627     for(ii = 0; ii < sel->length; ii += len + 1) {
    628       if('\0' == files[ii])
    629         len = 0;
    630       else {
    631         len = strlen(files + ii);
    632         /* de-urlencode the URI */
    633         decoded = urldecode(files + ii, len);
    634         freeables = g_list_append(freeables, decoded);
    635         if(g_utf8_validate(decoded, -1, NULL)) {
    636           /* remove the file: prefix */
    637           if(prelen < len && 0 == strncmp(prefix, decoded, prelen)) {
    638             deslashed = decoded + prelen;
    639             /* trim excess / characters from the beginning */
    640             while('/' == deslashed[0] && '/' == deslashed[1])
    641               deslashed++;
    642             /* if the file doesn't exist, the first part might be a hostname */
    643             if(0 > g_stat(deslashed, &sb) &&
    644                NULL != (hostless = strchr(deslashed + 1, '/')) &&
    645                0 == g_stat(hostless, &sb))
    646               deslashed = hostless;
     538    if( ( sel->format == 8 ) &&
     539        ( sel->selection == gdk_atom_intern( "XdndSelection", FALSE ) ) )
     540    {
     541        /* split file list on carriage returns and linefeeds */
     542        int i;
     543        char * str = g_strndup( (char*)sel->data, sel->length );
     544        gchar ** files = g_strsplit_set( str, "\r\n", -1 );
     545        for( i=0; files && files[i]; ++i )
     546        {
     547            char * filename;
     548            if( !*files[i] ) /* empty filename... */
     549                continue;
     550
     551            /* decode the filename */
     552            filename = urldecode( files[i], -1 );
     553            freeme = g_list_prepend( freeme, filename );
     554            if( !g_utf8_validate( filename, -1, NULL ) )
     555                continue;
     556
     557            /* walk past "file://", if present */
     558            if( g_str_has_prefix( filename, "file:" ) ) {
     559                filename += 5;
     560                while( g_str_has_prefix( filename, "//" ) )
     561                    ++filename;
     562            }
     563
     564            /* if the file doesn't exist, the first part
     565               might be a hostname ... walk past it. */
     566            if( !g_file_test( filename, G_FILE_TEST_EXISTS ) ) {
     567                char * pch = strchr( filename + 1, '/' );
     568                if( pch != NULL )
     569                    filename = pch;
     570            }
     571
    647572            /* finally, add it to the list of torrents to try adding */
    648             paths = g_list_append(paths, deslashed);
    649           }
    650         }
    651       }
    652     }
    653 
    654     /* try to add any torrents we found */
    655     if( NULL != paths )
    656     {
    657         action = tr_prefs_get_action( PREF_KEY_ADDSTD );
    658         tr_core_add_list( data->core, paths, action, FALSE );
    659         tr_core_torrents_added( data->core );
    660         g_list_free(paths);
    661     }
    662     freestrlist(freeables);
    663     g_free(files);
    664   }
    665 
    666   gtk_drag_finish(dc, (NULL != paths), FALSE, time);
     573            if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
     574                paths = g_list_prepend( paths, filename );
     575        }
     576
     577        /* try to add any torrents we found */
     578        if( paths != NULL )
     579        {
     580            enum tr_torrent_action action = tr_prefs_get_action( PREF_KEY_ADDSTD );
     581            paths = g_list_reverse( paths );
     582            tr_core_add_list( data->core, paths, action, FALSE );
     583            tr_core_torrents_added( data->core );
     584            g_list_free( paths );
     585        }
     586
     587        freestrlist( freeme );
     588        g_strfreev( files );
     589        g_free( str );
     590    }
     591
     592    gtk_drag_finish(dc, (NULL != paths), FALSE, time);
    667593}
    668594
     
    894820#endif
    895821  gtk_about_dialog_set_logo_icon_name( a, "transmission-logo" );
    896   gtk_about_dialog_set_comments( a, _("A simple yet powerful BitTorrent Client") );
     822  gtk_about_dialog_set_comments( a, _("A fast and intuitive BitTorrent client") );
    897823  gtk_about_dialog_set_website( a, "http://transmission.m0k.org/" );
    898824  gtk_about_dialog_set_copyright( a, _("Copyright 2005-2007 The Transmission Project") );
  • trunk/gtk/util.c

    r3353 r3380  
    241241
    242242GList *
    243 checkfilenames(int argc, char **argv) {
    244   char *pwd = g_get_current_dir();
    245   int ii, cd;
    246   char *dirstr, *filestr;
    247   GList *ret = NULL;
    248 
    249   for(ii = 0; ii < argc; ii++) {
    250     dirstr = g_path_get_dirname(argv[ii]);
    251     if(!g_path_is_absolute(argv[ii])) {
    252       filestr = g_build_filename(pwd, dirstr, NULL);
    253       g_free(dirstr);
    254       dirstr = filestr;
    255     }
    256     cd = chdir(dirstr);
    257     g_free(dirstr);
    258     if(0 > cd)
    259       continue;
    260     dirstr = g_get_current_dir();
    261     filestr = g_path_get_basename(argv[ii]);
    262     ret = g_list_append(ret, g_build_filename(dirstr, filestr, NULL));
    263     g_free(dirstr);
    264     g_free(filestr);
    265   }
    266 
    267   chdir(pwd);
    268   g_free(pwd);
    269 
    270   return ret;
     243checkfilenames( int argc, char **argv )
     244{
     245    int i;
     246    GList * ret = NULL;
     247    char * pwd = g_get_current_dir( );
     248
     249    for( i=0; i<argc; ++i )
     250    {
     251        char * filename = g_path_is_absolute( argv[i] )
     252            ? g_strdup ( argv[i] )
     253            : g_build_filename( pwd, argv[i], NULL );
     254
     255        if( g_file_test( filename, G_FILE_TEST_EXISTS ) )
     256            ret = g_list_append( ret, filename );
     257        else
     258            g_free( filename );
     259    }
     260
     261    g_free( pwd );
     262    return ret;
    271263}
    272264
     
    274266toraddaction( const char * action )
    275267{
    276     if( NULL == action || 0 == strcmp( "copy", action ) )
    277     {
     268    if( !action || !strcmp( "copy", action ) )
    278269        return TR_TOR_COPY;
    279     }
    280     else if( 0 == strcmp( "move", action ) )
    281     {
     270
     271    if( !strcmp( "move", action ) )
    282272        return TR_TOR_MOVE;
    283     }
    284     else
    285     {
    286         return TR_TOR_LEAVE;
    287     }
     273
     274    return TR_TOR_LEAVE;
    288275}
    289276
     
    295282        case TR_TOR_COPY:
    296283            return "copy";
     284
    297285        case TR_TOR_MOVE:
    298286            return "move";
     287
    299288        default:
    300289            return "leave";
  • trunk/gtk/util.h

    r3206 r3380  
    9191/* return a list of cleaned-up paths, with invalid directories removed */
    9292GList *
    93 checkfilenames(int argc, char **argv);
     93checkfilenames( int argc, char ** argv );
    9494
    9595/* returns the flag for an action string */
Note: See TracChangeset for help on using the changeset viewer.