diff --git a/gtk/main.c b/gtk/main.c index 1e83d4a18..313bf7f86 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -41,6 +41,8 @@ #include #endif +#include +#include #include #include "actions.h" @@ -476,6 +478,85 @@ main( int argc, char ** argv ) return 0; } +static gboolean +updateScheduledLimits(gpointer data) +{ + tr_handle *tr = (tr_handle *) data; + static gboolean last_state = FALSE; + gboolean in_sched_state = FALSE; + + if( !pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ) ) + { + in_sched_state = FALSE; + } + else + { + time_t t; + struct tm *tm; + int begin_hour, begin_minute, end_hour, end_minute; + int begin_time, end_time, cur_time; + + begin_hour = pref_int_get( PREF_KEY_SCHED_BEGIN_HOUR ); + begin_minute = pref_int_get( PREF_KEY_SCHED_BEGIN_MINUTE ); + end_hour = pref_int_get( PREF_KEY_SCHED_END_HOUR ); + end_minute = pref_int_get( PREF_KEY_SCHED_END_MINUTE ); + + time( &t ); + tm = localtime (&t); + cur_time = (tm->tm_hour * 60) + tm->tm_min; + begin_time = (begin_hour * 60) + begin_minute; + end_time = (end_hour * 60) + end_minute; + + if( (end_time - begin_time) >= 0 ) + { + if( (cur_time >= begin_time) && (cur_time <= end_time) ) + in_sched_state = TRUE; + } + else + { + if ( (cur_time >= begin_time) || (cur_time <= end_time) ) + in_sched_state = TRUE; + } + } + + if( last_state != in_sched_state ) + { + if( in_sched_state ) + { + int limit; + + tr_inf ( _( "Enabling scheduled bandwidth limits" ) ); + + tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, TRUE ); + limit = pref_int_get( PREF_KEY_SCHED_DL_LIMIT ); + tr_sessionSetSpeedLimit( tr, TR_DOWN, limit ); + tr_sessionSetSpeedLimitEnabled( tr, TR_UP, TRUE ); + limit = pref_int_get( PREF_KEY_SCHED_UL_LIMIT ); + tr_sessionSetSpeedLimit( tr, TR_UP, limit ); + } + else + { + gboolean b; + int limit; + + tr_inf ( _( "Disabling scheduled bandwidth limits" ) ); + + b = pref_flag_get( PREF_KEY_DL_LIMIT_ENABLED ); + tr_sessionSetSpeedLimitEnabled( tr, TR_DOWN, b ); + limit = pref_int_get( PREF_KEY_DL_LIMIT ); + tr_sessionSetSpeedLimit( tr, TR_DOWN, limit ); + b = pref_flag_get( PREF_KEY_UL_LIMIT_ENABLED ); + tr_sessionSetSpeedLimitEnabled( tr, TR_UP, b ); + limit = pref_int_get( PREF_KEY_UL_LIMIT ); + tr_sessionSetSpeedLimit( tr, TR_UP, limit ); + } + + last_state = in_sched_state; + } + + return TRUE; +} + static void appsetup( TrWindow * wind, GSList * torrentFiles, struct cbdata * cbdata, @@ -525,6 +606,10 @@ appsetup( TrWindow * wind, GSList * torrentFiles, cbdata->timer = g_timeout_add( UPDATE_INTERVAL, updatemodel, cbdata ); updatemodel( cbdata ); + /* start scheduled rate timer */ + updateScheduledLimits (tr_core_handle( cbdata->core )); + g_timeout_add_seconds( 60, updateScheduledLimits, tr_core_handle( cbdata->core ) ); + /* either show the window or iconify it */ if( !minimized ) gtk_widget_show( GTK_WIDGET( wind ) ); diff --git a/gtk/tr-prefs.c b/gtk/tr-prefs.c index a2f70d50d..b88b3a0ee 100644 --- a/gtk/tr-prefs.c +++ b/gtk/tr-prefs.c @@ -71,6 +71,14 @@ tr_prefs_init_global( void ) pref_int_set_default ( PREF_KEY_DL_LIMIT, 100 ); pref_flag_set_default ( PREF_KEY_UL_LIMIT_ENABLED, FALSE ); pref_int_set_default ( PREF_KEY_UL_LIMIT, 50 ); + pref_flag_set_default ( PREF_KEY_SCHED_LIMIT_ENABLED, FALSE ); + pref_int_set_default ( PREF_KEY_SCHED_BEGIN_HOUR, 0 ); + pref_int_set_default ( PREF_KEY_SCHED_BEGIN_MINUTE, 0 ); + pref_int_set_default ( PREF_KEY_SCHED_END_HOUR, 0 ); + pref_int_set_default ( PREF_KEY_SCHED_END_MINUTE, 0 ); + pref_int_set_default ( PREF_KEY_SCHED_DL_LIMIT, 100 ); + pref_int_set_default ( PREF_KEY_SCHED_UL_LIMIT, 50 ); + pref_flag_set_default ( PREF_KEY_OPTIONS_PROMPT, TRUE ); pref_int_set_default ( PREF_KEY_MAIN_WINDOW_HEIGHT, 500 ); @@ -1060,13 +1068,46 @@ trackerPage( GObject * core ) return t; } +struct NetworkPage +{ + TrCore * core; + GSList * sched_widgets; +}; + +static void +refreshNetworkSensitivity( struct NetworkPage * p ) +{ + GSList * l; + const gboolean sched_enabled = pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ); + + for( l=p->sched_widgets; l!=NULL; l=l->next ) + gtk_widget_set_sensitive( GTK_WIDGET( l->data ), sched_enabled ); +} + +static void +onNetworkToggled( GtkToggleButton * tb UNUSED, gpointer user_data ) +{ + refreshNetworkSensitivity( user_data ); +} + +static void +networkPageFree( gpointer gpage ) +{ + struct NetworkPage * page = gpage; + g_slist_free( page->sched_widgets ); + g_free( page ); +} + static GtkWidget* networkPage( GObject * core ) { int row = 0; const char * s; GtkWidget * t; - GtkWidget * w, * w2; + GtkWidget * w, * w2, * h; + struct NetworkPage * page = tr_new0( struct NetworkPage, 1 ); + + page->core = TR_CORE( core ); t = hig_workarea_create( ); hig_workarea_add_section_title (t, &row, _( "Router" ) ); @@ -1092,7 +1133,50 @@ networkPage( GObject * core ) g_signal_connect( w, "toggled", G_CALLBACK(target_cb), w2 ); hig_workarea_add_row_w( t, &row, w, w2, NULL ); + hig_workarea_add_section_divider( t, &row ); + hig_workarea_add_section_title (t, &row, _("Scheduled Bandwidth Limit")); + + h = gtk_hbox_new( FALSE, 0 ); + w2 = new_spin_button( PREF_KEY_SCHED_BEGIN_HOUR, core, 0, 23, 1 ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = gtk_label_new (":"); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = new_spin_button( PREF_KEY_SCHED_BEGIN_MINUTE, core, 0, 59, 1 ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = gtk_label_new (_(" and ")); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = new_spin_button( PREF_KEY_SCHED_END_HOUR, core, 0, 23, 1 ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = gtk_label_new (":"); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + w2 = new_spin_button( PREF_KEY_SCHED_END_MINUTE, core, 0, 59, 1 ); + page->sched_widgets = g_slist_append( page->sched_widgets, w2 ); + gtk_box_pack_start( GTK_BOX(h), w2, FALSE, FALSE, 0 ); + + s = _( "Limit bandwidth between" ); + w = new_check_button( s, PREF_KEY_SCHED_LIMIT_ENABLED, core ); + g_signal_connect( w, "toggled", G_CALLBACK(onNetworkToggled), page ); + hig_workarea_add_row_w( t, &row, w, h, NULL ); + + w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 ); + gtk_widget_set_sensitive( GTK_WIDGET(w), pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ) ); + page->sched_widgets = g_slist_append( page->sched_widgets, w ); + hig_workarea_add_row( t, &row, _( "Scheduled download speed (KB/s):" ), w, NULL ); + w = new_spin_button( PREF_KEY_SCHED_DL_LIMIT, core, 0, INT_MAX, 5 ); + gtk_widget_set_sensitive( GTK_WIDGET(w), pref_flag_get( PREF_KEY_SCHED_LIMIT_ENABLED ) ); + page->sched_widgets = g_slist_append( page->sched_widgets, w ); + hig_workarea_add_row( t, &row, _( "Scheduled upload speed (KB/s):" ), w, NULL ); + hig_workarea_finish( t, &row ); + g_object_set_data_full( G_OBJECT( t ), "page", page, networkPageFree ); + + refreshNetworkSensitivity( page ); return t; } diff --git a/gtk/tr-prefs.h b/gtk/tr-prefs.h index e1e498a1a..427aba3fe 100644 --- a/gtk/tr-prefs.h +++ b/gtk/tr-prefs.h @@ -24,6 +24,13 @@ GtkWidget * tr_prefs_dialog_new( GObject * core, GtkWindow * parent ); #define PREF_KEY_DL_LIMIT "download-limit" #define PREF_KEY_UL_LIMIT_ENABLED "upload-limit-enabled" #define PREF_KEY_UL_LIMIT "upload-limit" +#define PREF_KEY_SCHED_LIMIT_ENABLED "sched-limit-enabled" +#define PREF_KEY_SCHED_BEGIN_HOUR "sched-begin-hour" +#define PREF_KEY_SCHED_BEGIN_MINUTE "sched-begin-minute" +#define PREF_KEY_SCHED_END_HOUR "sched-end-hour" +#define PREF_KEY_SCHED_END_MINUTE "sched-end-minute" +#define PREF_KEY_SCHED_DL_LIMIT "sched-download-limit" +#define PREF_KEY_SCHED_UL_LIMIT "sched-upload-limit" #define PREF_KEY_OPTIONS_PROMPT "show-options-window" #define PREF_KEY_DOWNLOAD_DIR "download-dir" #define PREF_KEY_OPEN_DIALOG_FOLDER "open-dialog-dir"