1/* 2 * This file Copyright (C) Mnemosyne LLC 3 * 4 * This file is licensed by the GPL version 2. Works owned by the 5 * Transmission project are granted a special exemption to clause 2(b) 6 * so that the bulk of its code can remain under the MIT license. 7 * This exemption does not extend to derived works not owned by 8 * the Transmission project. 9 * 10 * $Id: stats.c 13388 2012-07-14 19:26:55Z jordan $ 11 */ 12 13#include <glib/gi18n.h> 14#include <gtk/gtk.h> 15#include "hig.h" 16#include "stats.h" 17#include "tr-core.h" 18#include "tr-prefs.h" 19#include "util.h" 20 21enum 22{ 23 TR_RESPONSE_RESET = 1 24}; 25 26struct stat_ui 27{ 28 GtkWidget * one_up_lb; 29 GtkWidget * one_down_lb; 30 GtkWidget * one_ratio_lb; 31 GtkWidget * one_time_lb; 32 GtkWidget * all_up_lb; 33 GtkWidget * all_down_lb; 34 GtkWidget * all_ratio_lb; 35 GtkWidget * all_time_lb; 36 GtkWidget * all_sessions_lb; 37 TrCore * core; 38}; 39 40static void 41setLabel( GtkWidget * w, const char * str ) 42{ 43 gtr_label_set_text( GTK_LABEL( w ), str ); 44} 45 46static void 47setLabelFromRatio( GtkWidget * w, double d ) 48{ 49 char buf[128]; 50 51 tr_strlratio( buf, d, sizeof( buf ) ); 52 setLabel( w, buf ); 53} 54 55static gboolean 56updateStats( gpointer gdata ) 57{ 58 char buf[128]; 59 const char * fmt; 60 tr_session_stats one, all; 61 const size_t buflen = sizeof( buf ); 62 struct stat_ui * ui = gdata; 63 64 tr_sessionGetStats( gtr_core_session( ui->core ), &one ); 65 tr_sessionGetCumulativeStats( gtr_core_session( ui->core ), &all ); 66 67 setLabel( ui->one_up_lb, tr_strlsize( buf, one.uploadedBytes, buflen ) ); 68 setLabel( ui->one_down_lb, tr_strlsize( buf, one.downloadedBytes, buflen ) ); 69 setLabel( ui->one_time_lb, tr_strltime( buf, one.secondsActive, buflen ) ); 70 setLabelFromRatio( ui->one_ratio_lb, one.ratio ); 71 72 fmt = ngettext( "Started %'d time", "Started %'d times", 73 (int)all.sessionCount ); 74 g_snprintf( buf, buflen, fmt, (int)all.sessionCount ); 75 setLabel( ui->all_sessions_lb, buf ); 76 setLabel( ui->all_up_lb, tr_strlsize( buf, all.uploadedBytes, buflen ) ); 77 setLabel( ui->all_down_lb, tr_strlsize( buf, all.downloadedBytes, buflen ) ); 78 setLabel( ui->all_time_lb, tr_strltime( buf, all.secondsActive, buflen ) ); 79 setLabelFromRatio( ui->all_ratio_lb, all.ratio ); 80 81 return TRUE; 82} 83 84static void 85dialogDestroyed( gpointer p, GObject * dialog UNUSED ) 86{ 87 g_source_remove( GPOINTER_TO_UINT( p ) ); 88} 89 90static void 91dialogResponse( GtkDialog * dialog, gint response, gpointer gdata ) 92{ 93 struct stat_ui * ui = gdata; 94 95 if( response == TR_RESPONSE_RESET ) 96 { 97 const char * primary = _( "Reset your statistics?" ); 98 const char * secondary = _( "These statistics are for your information only. " 99 "Resetting them doesn't affect the statistics logged by your BitTorrent trackers." ); 100 const int flags = GTK_DIALOG_DESTROY_WITH_PARENT 101 | GTK_DIALOG_MODAL; 102 GtkWidget * w = gtk_message_dialog_new( GTK_WINDOW( dialog ), 103 flags, 104 GTK_MESSAGE_QUESTION, 105 GTK_BUTTONS_NONE, 106 "%s", primary ); 107 gtk_dialog_add_buttons( GTK_DIALOG( w ), 108 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 109 _( "_Reset" ), TR_RESPONSE_RESET, 110 NULL ); 111 gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( w ), "%s", secondary ); 112 if( gtk_dialog_run( GTK_DIALOG( w ) ) == TR_RESPONSE_RESET ) 113 { 114 tr_sessionClearStats( gtr_core_session( ui->core ) ); 115 updateStats( ui ); 116 } 117 gtk_widget_destroy( w ); 118 } 119 120 if( response == GTK_RESPONSE_CLOSE ) 121 gtk_widget_destroy( GTK_WIDGET( dialog ) ); 122} 123 124GtkWidget* 125gtr_stats_dialog_new( GtkWindow * parent, TrCore * core ) 126{ 127 guint i; 128 GtkWidget * d; 129 GtkWidget * t; 130 GtkWidget * l; 131 guint row = 0; 132 struct stat_ui * ui = g_new0( struct stat_ui, 1 ); 133 134 d = gtk_dialog_new_with_buttons( _( "Statistics" ), 135 parent, 136 GTK_DIALOG_DESTROY_WITH_PARENT, 137 _( "_Reset" ), TR_RESPONSE_RESET, 138 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, 139 NULL ); 140 gtk_dialog_set_default_response( GTK_DIALOG( d ), 141 GTK_RESPONSE_CLOSE ); 142 gtk_dialog_set_alternative_button_order( GTK_DIALOG( d ), 143 GTK_RESPONSE_CLOSE, 144 TR_RESPONSE_RESET, 145 -1 ); 146 t = hig_workarea_create( ); 147 ui->core = core; 148 149 hig_workarea_add_section_title( t, &row, _( "Current Session" ) ); 150 l = ui->one_up_lb = gtk_label_new( NULL ); 151 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 152 hig_workarea_add_row( t, &row, _( "Uploaded:" ), l, NULL ); 153 l = ui->one_down_lb = gtk_label_new( NULL ); 154 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 155 hig_workarea_add_row( t, &row, _( "Downloaded:" ), l, NULL ); 156 l = ui->one_ratio_lb = gtk_label_new( NULL ); 157 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 158 hig_workarea_add_row( t, &row, _( "Ratio:" ), l, NULL ); 159 l = ui->one_time_lb = gtk_label_new( NULL ); 160 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 161 hig_workarea_add_row( t, &row, _( "Duration:" ), l, NULL ); 162 hig_workarea_add_section_divider( t, &row ); 163 hig_workarea_add_section_title( t, &row, _( "Total" ) ); 164 l = ui->all_sessions_lb = gtk_label_new( _( "Started %'d time" ) ); 165 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 166 hig_workarea_add_label_w( t, row++, l ); 167 l = ui->all_up_lb = gtk_label_new( NULL ); 168 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 169 hig_workarea_add_row( t, &row, _( "Uploaded:" ), l, NULL ); 170 l = ui->all_down_lb = gtk_label_new( NULL ); 171 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 172 hig_workarea_add_row( t, &row, _( "Downloaded:" ), l, NULL ); 173 l = ui->all_ratio_lb = gtk_label_new( NULL ); 174 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 175 hig_workarea_add_row( t, &row, _( "Ratio:" ), l, NULL ); 176 l = ui->all_time_lb = gtk_label_new( NULL ); 177 gtk_label_set_single_line_mode( GTK_LABEL( l ), TRUE ); 178 hig_workarea_add_row( t, &row, _( "Duration:" ), l, NULL ); 179 gtr_dialog_set_content( GTK_DIALOG( d ), t ); 180 181 updateStats( ui ); 182 g_object_set_data_full( G_OBJECT( d ), "data", ui, g_free ); 183 g_signal_connect( d, "response", G_CALLBACK( dialogResponse ), ui ); 184 i = gdk_threads_add_timeout_seconds( SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS, updateStats, ui ); 185 g_object_weak_ref( G_OBJECT( d ), dialogDestroyed, GUINT_TO_POINTER( i ) ); 186 return d; 187} 188