Changeset 5230


Ignore:
Timestamp:
Mar 9, 2008, 3:27:08 PM (15 years ago)
Author:
charles
Message:

(gtk) #772, #753: added `watch dir' for automatically adding torrents. delete files to trashcan, rather than unlinking them. These features require 2.15.5 or higher.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/configure.ac

    r5133 r5230  
    1111AC_PROG_LIBTOOL
    1212
     13GIO_MINIMUM=2.15.5
    1314GLIB_MINIMUM=2.6.0
    1415GTK_MINIMUM=2.6.0
    1516WX_MINIMUM=2.6.0
    1617LIBNOTIFY_MINIMUM=0.4.4
     18AC_SUBST(GIO_MINIMUM)
    1719AC_SUBST(GLIB_MINIMUM)
    1820AC_SUBST(GTK_MINIMUM)
     
    9597AC_SUBST(GTK_CFLAGS)
    9698
     99PKG_CHECK_MODULES([GIO],
     100                  [gio-2.0 >= $GIO_MINIMUM],
     101                  [use_gio=yes],
     102                  [use_gio=no])
     103AC_SUBST(GIO_LIBS)
     104AC_SUBST(GIO_CFLAGS)
     105if test "x$use_gio" = "xyes"; then
     106    AC_DEFINE([HAVE_GIO], 1)
     107fi
     108
    97109PKG_CHECK_MODULES([LIBNOTIFY],
    98110                  [libnotify >= $LIBNOTIFY_MINIMUM],
     
    278290        Build GTK+ client:          ${build_gtk}
    279291          ... libnotify support:    ${use_libnotify}
     292          ... gio support:          ${use_gio}
    280293        Build OS X client:          ${build_darwin}
    281294        Build wxWidgets client:     ${build_wx}
  • trunk/gtk/Makefile.am

    r5122 r5230  
    1111    $(OPENSSL_CFLAGS) \
    1212    $(PTHREAD_CFLAGS) \
     13    $(GIO_CFLAGS) \
    1314    $(LIBNOTIFY_CFLAGS)
    1415
     
    7273    $(top_builddir)/third-party/libnatpmp/libnatpmp.a \
    7374    $(GTK_LIBS) \
     75    $(GIO_LIBS) \
    7476    $(LIBNOTIFY_LIBS) \
    7577    $(OPENSSL_LIBS) \
  • trunk/gtk/dialogs.c

    r5226 r5230  
    154154
    155155        flag = 0;
    156         w = gtk_check_button_new_with_mnemonic( _( "_Delete original torrent file" ) );
     156        w = gtk_check_button_new_with_mnemonic( _( "_Trash original torrent files" ) );
    157157        g_signal_connect( w, "toggled", G_CALLBACK( deleteToggled ), ctor );
     158        if( tr_ctorGetDeleteSource( ctor, &flag ) )
     159            g_assert_not_reached( );
    158160        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), flag );
    159161        gtk_box_pack_start( GTK_BOX( v ), w, FALSE, FALSE, 0 );
  • trunk/gtk/ipc.c

    r5226 r5230  
    3434#include <gtk/gtk.h>
    3535#include <glib/gi18n.h>
     36#include <glib/gstdio.h> /* g_unlink */
    3637
    3738#include <libevent/evutil.h>
     
    360361static void
    361362rmsock(void) {
    362   if(NULL != gl_sockpath) {
    363     unlink(gl_sockpath);
     363  if( gl_sockpath) {
     364    g_unlink(gl_sockpath);
    364365    g_free(gl_sockpath);
    365366  }
     
    464465
    465466  /* unlink any existing socket file before trying to create ours */
    466   unlink(gl_sockpath);
     467  g_unlink(gl_sockpath);
    467468  if(0 > bind(con->fd, (struct sockaddr *)&sa, SUN_LEN(&sa))) {
    468469    /* bind may fail if there was already a socket, so try twice */
    469     unlink(gl_sockpath);
     470    g_unlink(gl_sockpath);
    470471    if(0 > bind(con->fd, (struct sockaddr *)&sa, SUN_LEN(&sa)))
    471472      goto fail;
  • trunk/gtk/open-dialog.c

    r5226 r5230  
    1212
    1313#include <glib/gi18n.h>
    14 #include <glib/gstdio.h>
    1514#include <gtk/gtk.h>
    1615#include "file-list.h"
     
    2322    GtkWidget * list;
    2423    GtkToggleButton * run_check;
    25     GtkToggleButton * delete_check;
     24    GtkToggleButton * trash_check;
    2625    char * filename;
    2726    char * destination;
     
    5655                tr_torrentStart( tr_torrent_handle( data->gtor ) );
    5756            tr_core_add_torrent( data->core, data->gtor );
    58             if( gtk_toggle_button_get_active( data->delete_check ) )
    59                 g_unlink( data->filename );
     57            if( gtk_toggle_button_get_active( data->trash_check ) )
     58                tr_file_trash_or_unlink( data->filename );
    6059        }
    6160    }
     
    222221    ++row;
    223222    col = 0;
    224     w = gtk_check_button_new_with_mnemonic( _( "_Delete original torrent file" ) );
    225     data->delete_check = GTK_TOGGLE_BUTTON( w );
     223    w = gtk_check_button_new_with_mnemonic( _( "_Trash original torrent file" ) );
     224    data->trash_check = GTK_TOGGLE_BUTTON( w );
     225    if( tr_ctorGetDeleteSource( ctor, &flag ) )
     226        g_assert_not_reached( );
    226227    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), flag );
    227228    gtk_table_attach( GTK_TABLE( t ), w, col, col+2, row, row+1, GTK_FILL, 0, 0, 0 );
  • trunk/gtk/tr-core.c

    r5217 r5230  
    2727#include <gtk/gtk.h>
    2828#include <glib/gi18n.h>
     29#ifdef HAVE_GIO
     30#include <gio/gio.h>
     31#endif
    2932
    3033#include <libtransmission/transmission.h>
     
    3942struct TrCorePrivate
    4043{
     44#ifdef HAVE_GIO
     45    GFileMonitor     * monitor;
     46#endif
    4147    GtkTreeModel     * model;
    4248    tr_handle        * handle;
     
    278284}
    279285
     286#ifdef HAVE_GIO
     287static void
     288watchFolderChanged( GFileMonitor       * monitor UNUSED,
     289                    GFile              * file,
     290                    GFile              * other_type UNUSED,
     291                    GFileMonitorEvent    event_type,
     292                    gpointer             gcore )
     293{
     294    if( event_type == G_FILE_MONITOR_EVENT_CREATED )
     295    {
     296        TrCore * core = TR_CORE( gcore );
     297        char * filename = g_file_get_path( file );
     298        const gboolean isTorrent = g_str_has_suffix( filename, ".torrent" );
     299        if( isTorrent )
     300        {
     301            tr_ctor * ctor = tr_ctorNew( core->priv->handle );
     302            tr_core_add_list( core, g_list_append( NULL, g_strdup( filename ) ), ctor );
     303        }
     304        g_free( filename );
     305    }
     306}
     307
     308static void
     309scanWatchDir( TrCore * core )
     310{
     311    const gboolean isEnabled = pref_flag_get( PREF_KEY_DIR_WATCH_ENABLED );
     312    if( isEnabled )
     313    {
     314        GList * torrents = NULL;
     315        char * dirname = pref_string_get( PREF_KEY_DIR_WATCH );
     316        GDir * dir = g_dir_open( dirname, 0, NULL );
     317        const char * basename;
     318        while(( basename = g_dir_read_name( dir )))
     319            if( g_str_has_suffix( basename, ".torrent" ) )
     320                torrents = g_list_append( torrents, g_build_filename( dirname, basename, NULL ) );
     321        if( torrents )
     322            tr_core_add_list( core, torrents, tr_ctorNew( core->priv->handle ) );
     323        g_free( dirname );
     324    }
     325}
     326
     327static void
     328updateWatchDir( TrCore * core )
     329{
     330    char * filename = pref_string_get( PREF_KEY_DIR_WATCH );
     331    const gboolean isEnabled = pref_flag_get( PREF_KEY_DIR_WATCH_ENABLED );
     332
     333    if( core->priv->monitor && !isEnabled )
     334    {
     335        GFileMonitor * m = core->priv->monitor;
     336        core->priv->monitor = NULL;
     337        g_signal_handlers_disconnect_by_func( m, watchFolderChanged, core );
     338        g_file_monitor_cancel( m );
     339        g_object_unref( G_OBJECT( m ) );
     340    }
     341    else if( isEnabled && !core->priv->monitor )
     342    {
     343        GFile * file = g_file_new_for_path( filename );
     344        GFileMonitor * m = g_file_monitor_directory( file, 0, NULL, NULL );
     345        scanWatchDir( core );
     346        g_signal_connect( m, "changed", G_CALLBACK (watchFolderChanged), core );
     347        core->priv->monitor = m;
     348    }
     349
     350    g_free( filename );
     351}
     352#endif
     353
    280354static void
    281355prefsChanged( TrCore * core, const char * key, gpointer data UNUSED )
     
    294368        tr_setGlobalPeerLimit( tr_core_handle( core ), val );
    295369    }
     370#ifdef HAVE_GIO
     371    else if( !strcmp( key, PREF_KEY_DIR_WATCH ) ||
     372             !strcmp( key, PREF_KEY_DIR_WATCH_ENABLED ) )
     373    {
     374        updateWatchDir( core );
     375    }
     376#endif
    296377}
    297378
     
    383464    prefsChanged( core, PREF_KEY_SORT_MODE, NULL );
    384465    prefsChanged( core, PREF_KEY_SORT_REVERSED, NULL );
     466    prefsChanged( core, PREF_KEY_DIR_WATCH_ENABLED, NULL );
    385467    prefsChanged( core, PREF_KEY_MAX_PEERS_GLOBAL, NULL );
    386468    g_signal_connect( core, "prefs-changed", G_CALLBACK(prefsChanged), NULL );
     
    500582        tr_ctorSetPaused( ctor, TR_FORCE, !pref_flag_get( PREF_KEY_START ) );
    501583
     584    if( tr_ctorGetDeleteSource( ctor, NULL ) )
     585        tr_ctorSetDeleteSource( ctor, pref_flag_get( PREF_KEY_TRASH_ORIGINAL ) );
     586
    502587    if( tr_ctorGetMaxConnectedPeers( ctor, TR_FORCE, NULL ) )
    503588        tr_ctorSetMaxConnectedPeers( ctor, TR_FORCE,
  • trunk/gtk/tr-prefs.c

    r5229 r5230  
    3232    cf_check_older_configs( );
    3333
     34#if HAVE_GIO
     35    str = NULL;
     36    if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DESKTOP );
     37    if( !str ) str = g_get_home_dir( );
     38    pref_string_set_default ( PREF_KEY_DIR_WATCH, str );
     39    pref_flag_set_default   ( PREF_KEY_DIR_WATCH_ENABLED, FALSE );
     40#endif
     41
    3442    pref_int_set_default    ( PREF_KEY_MAX_PEERS_GLOBAL, 200 );
    3543    pref_int_set_default    ( PREF_KEY_MAX_PEERS_PER_TORRENT, 50 );
     
    4856    str = NULL;
    4957#if GLIB_CHECK_VERSION(2,14,0)
    50     if( !str )
    51         str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
     58    if( !str ) str = g_get_user_special_dir( G_USER_DIRECTORY_DOWNLOAD );
    5259#endif
    53     if( !str )
    54         str = g_get_home_dir( );
     60    if( !str ) str = g_get_home_dir( );
    5561    pref_string_set_default ( PREF_KEY_DIR_DEFAULT, str );
    5662
     
    7177
    7278    pref_flag_set_default   ( PREF_KEY_START, TRUE );
     79    pref_flag_set_default   ( PREF_KEY_TRASH_ORIGINAL, FALSE );
    7380
    7481    pref_save( NULL );
     
    212219    GtkWidget * t;
    213220    GtkWidget * w;
     221    GtkWidget * l;
    214222
    215223    t = hig_workarea_create( );
    216224    hig_workarea_add_section_title( t, &row, _( "Adding" ) );
    217225
     226#ifdef HAVE_GIO
     227        s = _( "Automatically add torrents from:" );
     228        l = new_check_button( s, PREF_KEY_DIR_WATCH_ENABLED, core );
     229        w = new_path_chooser_button( PREF_KEY_DIR_WATCH, core );
     230        gtk_widget_set_sensitive( GTK_WIDGET(w), pref_flag_get( PREF_KEY_DIR_WATCH_ENABLED ) );
     231        g_signal_connect( l, "toggled", G_CALLBACK(target_cb), w );
     232        hig_workarea_add_row_w( t, &row, l, w, NULL );
     233#endif
     234
     235        s = _( "Show _options dialog" );
     236        w = new_check_button( s, PREF_KEY_OPTIONS_PROMPT, core );
     237        hig_workarea_add_wide_control( t, &row, w );
     238
     239        s = _( "_Start torrents when added" );
     240        w = new_check_button( s, PREF_KEY_START, core );
     241        hig_workarea_add_wide_control( t, &row, w );
     242
     243        s = _( "_Trash original torrent files" );
     244        w = new_check_button( s, PREF_KEY_TRASH_ORIGINAL, core );
     245        hig_workarea_add_wide_control( t, &row, w );
     246
    218247        w = new_path_chooser_button( PREF_KEY_DIR_DEFAULT, core );
    219248        hig_workarea_add_row( t, &row, _( "Default destination _folder:" ), w, NULL );
    220 
    221         s = _( "Show _options dialog" );
    222         w = new_check_button( s, PREF_KEY_OPTIONS_PROMPT, core );
    223         hig_workarea_add_wide_control( t, &row, w );
    224 
    225         s = _( "_Start when added" );
    226         w = new_check_button( s, PREF_KEY_START, core );
    227         hig_workarea_add_wide_control( t, &row, w );
    228249
    229250#ifdef HAVE_LIBNOTIFY
     
    231252    hig_workarea_add_section_title( t, &row, _( "Notification" ) );
    232253
    233         s = _( "_Popup message when a torrent finishes" );
     254        s = _( "_Display a message when torrents finish" );
    234255        w = new_check_button( s, PREF_KEY_NOTIFY, core );
    235256        hig_workarea_add_wide_control( t, &row, w );
  • trunk/gtk/tr-prefs.h

    r5229 r5230  
    2727#define PREF_KEY_OPTIONS_PROMPT         "show-options-window"
    2828#define PREF_KEY_DIR_DEFAULT            "default-download-directory"
     29#define PREF_KEY_DIR_WATCH              "watch-folder"
     30#define PREF_KEY_DIR_WATCH_ENABLED      "watch-folder-enabled"
    2931#define PREF_KEY_START                  "start-added-torrents"
     32#define PREF_KEY_TRASH_ORIGINAL         "trash-original-torrent-files"
    3033#define PREF_KEY_PORT                   "listening-port"
    3134#define PREF_KEY_NAT                    "nat-traversal-enabled"
  • trunk/gtk/tr-torrent.c

    r5226 r5230  
    2828#include <gtk/gtk.h>
    2929#include <glib/gi18n.h>
    30 #include <glib/gstdio.h>
    3130
    3231#include <libtransmission/transmission.h>
     
    205204    *err = NULL;
    206205
     206    tr_ctorSetDeleteSource( ctor, FALSE );
    207207    tor = tr_torrentNew( handle, ctor, &errcode );
     208
     209    if( tor )
     210    {
     211        uint8_t doTrash = FALSE;
     212        tr_ctorGetDeleteSource( ctor, &doTrash );
     213        if( doTrash )
     214            tr_file_trash_or_unlink( tr_ctorGetSourceFile( ctor ) );
     215    }
    208216 
    209217    if( !tor )
     
    335343        {
    336344            char * swap = g_path_get_dirname( file );
    337             g_unlink( file );
     345            tr_file_trash_or_unlink( file );
    338346            g_free( file );
    339347            file = swap;
  • trunk/gtk/util.c

    r5227 r5230  
    2929#include <gtk/gtk.h>
    3030#include <glib/gi18n.h>
     31#include <glib/gstdio.h> /* g_unlink() */
     32#ifdef HAVE_GIO
     33#include <gio/gio.h> /* g_file_trash() */
     34#endif
    3135
    3236#include <libevent/evhttp.h>
     
    417421    return object;
    418422}
     423
     424void
     425tr_file_trash_or_unlink( const char * filename )
     426{
     427    if( filename && *filename )
     428    {
     429        gboolean trashed = FALSE;
     430#ifdef HAVE_GIO
     431        GError * err = NULL;
     432        GFile * file = g_file_new_for_path( filename );
     433        trashed = g_file_trash( file, NULL, &err );
     434        g_object_unref( G_OBJECT( file ) );
     435#endif
     436        if( !trashed )
     437            g_unlink( filename );
     438    }
     439}
  • trunk/gtk/util.h

    r5169 r5230  
    111111gpointer tr_object_ref_sink (gpointer object);
    112112
     113void tr_file_trash_or_unlink( const char * filename );
     114
    113115#endif /* GTK_MAJOR_VERSION */
    114116
Note: See TracChangeset for help on using the changeset viewer.