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: tr-icon.c 13286 2012-04-16 18:42:26Z jordan $ 11 */ 12 13#include <glib/gi18n.h> 14#include <gtk/gtk.h> 15#ifdef HAVE_LIBAPPINDICATOR 16 #include <libappindicator/app-indicator.h> 17#endif 18#include <libtransmission/transmission.h> 19#include <libtransmission/utils.h> 20#include "actions.h" 21#include "tr-icon.h" 22#include "util.h" 23 24static GQuark 25get_core_quark( void ) 26{ 27 static GQuark quark = 0; 28 if( !quark ) quark = g_quark_from_static_string( "tr-core" ); 29 return quark; 30} 31 32#define ICON_NAME "transmission" 33 34#ifdef HAVE_LIBAPPINDICATOR 35void 36gtr_icon_refresh( gpointer vindicator UNUSED ) 37{ 38} 39#else 40static void 41activated( GtkStatusIcon * self UNUSED, gpointer user_data UNUSED ) 42{ 43 gtr_action_activate( "toggle-main-window" ); 44} 45 46static void 47popup( GtkStatusIcon * self, 48 guint button, 49 guint when, 50 gpointer data UNUSED ) 51{ 52 GtkWidget * w = gtr_action_get_widget( "/icon-popup" ); 53 54 gtk_menu_popup ( GTK_MENU( w ), NULL, NULL, 55 gtk_status_icon_position_menu, 56 self, button, when ); 57} 58 59void 60gtr_icon_refresh( gpointer vicon ) 61{ 62 double KBps; 63 double limit; 64 char up[64]; 65 char upLimit[64]; 66 char down[64]; 67 char downLimit[64]; 68 char tip[1024]; 69 const char * idle = _( "Idle" ); 70 GtkStatusIcon * icon = GTK_STATUS_ICON( vicon ); 71 tr_session * session = gtr_core_session( g_object_get_qdata( G_OBJECT( icon ), get_core_quark( ) ) ); 72 73 /* up */ 74 KBps = tr_sessionGetRawSpeed_KBps( session, TR_UP ); 75 if( KBps < 0.001 ) 76 g_strlcpy( up, idle, sizeof( up ) ); 77 else 78 tr_formatter_speed_KBps( up, KBps, sizeof( up ) ); 79 80 /* up limit */ 81 if( !tr_sessionGetActiveSpeedLimit_KBps( session, TR_UP, &limit ) ) 82 *upLimit = '\0'; 83 else { 84 char buf[64]; 85 tr_formatter_speed_KBps( buf, limit, sizeof( buf ) ); 86 g_snprintf( upLimit, sizeof( upLimit ), _( "(Limit: %s)" ), buf ); 87 } 88 89 /* down */ 90 KBps = tr_sessionGetRawSpeed_KBps( session, TR_DOWN ); 91 if( KBps < 0.001 ) 92 g_strlcpy( down, idle, sizeof( down ) ); 93 else 94 tr_formatter_speed_KBps( down, KBps, sizeof( down ) ); 95 96 /* down limit */ 97 if( !tr_sessionGetActiveSpeedLimit_KBps( session, TR_DOWN, &limit ) ) 98 *downLimit = '\0'; 99 else { 100 char buf[64]; 101 tr_formatter_speed_KBps( buf, limit, sizeof( buf ) ); 102 g_snprintf( downLimit, sizeof( downLimit ), _( "(Limit: %s)" ), buf ); 103 } 104 105 /* %1$s: current upload speed 106 * %2$s: current upload limit, if any 107 * %3$s: current download speed 108 * %4$s: current download limit, if any */ 109 g_snprintf( tip, sizeof( tip ), _( "Transmission\nUp: %1$s %2$s\nDown: %3$s %4$s" ), up, upLimit, down, downLimit ); 110 111 gtk_status_icon_set_tooltip_text( GTK_STATUS_ICON( icon ), tip ); 112} 113#endif 114 115static const char * 116getIconName( void ) 117{ 118 const char * icon_name; 119 120 GtkIconTheme * theme = gtk_icon_theme_get_default( ); 121 122 /* if the tray's icon is a 48x48 file, use it; 123 * otherwise, use the fallback builtin icon */ 124 if( !gtk_icon_theme_has_icon( theme, TRAY_ICON ) ) 125 icon_name = ICON_NAME; 126 else { 127 GtkIconInfo * icon_info = gtk_icon_theme_lookup_icon( theme, TRAY_ICON, 48, GTK_ICON_LOOKUP_USE_BUILTIN ); 128 const gboolean icon_is_builtin = gtk_icon_info_get_filename ( icon_info ) == NULL; 129 gtk_icon_info_free ( icon_info ); 130 icon_name = icon_is_builtin ? ICON_NAME : TRAY_ICON; 131 } 132 133 return icon_name; 134} 135 136gpointer 137gtr_icon_new( TrCore * core) 138{ 139#ifdef HAVE_LIBAPPINDICATOR 140 GtkWidget * w; 141 const char * icon_name = getIconName( ); 142 AppIndicator * indicator = app_indicator_new( ICON_NAME, icon_name, APP_INDICATOR_CATEGORY_SYSTEM_SERVICES ); 143 app_indicator_set_status( indicator, APP_INDICATOR_STATUS_ACTIVE ); 144 w = gtr_action_get_widget( "/icon-popup" ); 145 app_indicator_set_menu( indicator, GTK_MENU ( w ) ); 146 app_indicator_set_title( indicator, g_get_application_name( ) ); 147 g_object_set_qdata( G_OBJECT( indicator ), get_core_quark( ), core ); 148 return indicator; 149#else 150 const char * icon_name = getIconName( ); 151 GtkStatusIcon * icon = gtk_status_icon_new_from_icon_name( icon_name ); 152 g_signal_connect( icon, "activate", G_CALLBACK( activated ), NULL ); 153 g_signal_connect( icon, "popup-menu", G_CALLBACK( popup ), NULL ); 154 g_object_set_qdata( G_OBJECT( icon ), get_core_quark( ), core ); 155 return icon; 156#endif 157} 158