source: trunk/gtk/tr_window.c @ 3449

Last change on this file since 3449 was 3449, checked in by charles, 15 years ago

(gtk) remember between sessions which column is used for sorting in the main window's torrent list

  • Property svn:keywords set to Date Rev Author Id
File size: 10.3 KB
Line 
1/******************************************************************************
2 * $Id: tr_window.c 3449 2007-10-17 18:31:12Z charles $
3 *
4 * Copyright (c) 2005-2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#include <string.h>
26
27#include <gtk/gtk.h>
28#include <glib/gi18n.h>
29
30#include <libtransmission/transmission.h>
31
32#include "actions.h"
33#include "hig.h"
34#include "tr_cell_renderer_progress.h"
35#include "tr_core.h"
36#include "tr_torrent.h"
37#include "tr_window.h"
38#include "util.h"
39
40typedef struct
41{
42    GtkWidget * scroll;
43    GtkWidget * view;
44    GtkWidget * status;
45    GtkWidget * ul_lb;
46    GtkWidget * dl_lb;
47    GtkTreeSelection * selection;
48    GtkCellRenderer * namerend;
49}
50PrivateData;
51
52#define PRIVATE_DATA_KEY "private-data"
53
54PrivateData*
55get_private_data( TrWindow * w )
56{
57    return (PrivateData*) g_object_get_data (G_OBJECT(w), PRIVATE_DATA_KEY);
58}
59
60/***
61****
62***/
63
64static void
65formatname( GtkTreeViewColumn * col UNUSED, GtkCellRenderer * rend,
66            GtkTreeModel * model, GtkTreeIter * iter, gpointer data UNUSED )
67{
68    TrTorrent * gtor;
69    char  * name, * mb, * str, * top, * bottom;
70    const char * fmt;
71    guint64 size;
72    int     status, err, eta, tpeers, upeers, dpeers;
73
74    gtk_tree_model_get( model, iter, MC_NAME, &name, MC_STAT, &status,
75                        MC_ERR, &err, MC_SIZE, &size,
76                        MC_ETA, &eta, MC_PEERS, &tpeers, MC_UPEERS, &upeers,
77                        MC_DPEERS, &dpeers, MC_TORRENT, &gtor, -1 );
78
79    tpeers = MAX( tpeers, 0 );
80    upeers = MAX( upeers, 0 );
81    dpeers = MAX( dpeers, 0 );
82    mb = readablesize(size);
83
84    top = tr_torrent_status_str ( gtor );
85
86    if( TR_OK != err )
87    {
88        char * terr;
89        gtk_tree_model_get( model, iter, MC_TERR, &terr, -1 );
90        bottom = g_strconcat( _("Error"), ": ", terr, NULL );
91        g_free( terr );
92    }
93    else if( TR_STATUS_DOWNLOAD & status )
94    {
95        bottom = g_strdup_printf( ngettext( "Downloading from %i of %i peer",
96                                            "Downloading from %i of %i peers",
97                                            tpeers ), dpeers, tpeers );
98    }
99    else
100    {
101        bottom = NULL;
102    }
103
104    fmt = err==TR_OK
105        ? "<b>%s (%s)</b>\n<small>%s\n%s</small>"
106        : "<span color='red'><b>%s (%s)</b>\n<small>%s\n%s</small></span>";
107    str = g_markup_printf_escaped( fmt, name, mb, top, (bottom ? bottom : "") );
108    g_object_set( rend, "markup", str, NULL );
109    g_free( name );
110    g_free( mb );
111    g_free( str );
112    g_free( top );
113    g_free( bottom );
114    g_object_unref( gtor );
115}
116
117static void
118formatprog( GtkTreeViewColumn * col UNUSED, GtkCellRenderer * rend,
119            GtkTreeModel * model, GtkTreeIter * iter, gpointer data UNUSED )
120{
121    char  * dlstr, * ulstr, * str, * marked;
122    gfloat  prog, dl, ul;
123    guint64 down, up;
124
125    gtk_tree_model_get( model, iter, MC_PROG_D, &prog, MC_DRATE, &dl,
126                        MC_URATE, &ul, MC_DOWN, &down, MC_UP, &up, -1 );
127    prog = MAX( prog, 0.0 );
128    prog = MIN( prog, 1.0 );
129
130    ulstr = readablespeed (ul);
131    if( 1.0 == prog )
132    {
133        dlstr = ratiostr( down, up );
134        str = g_strdup_printf( _("Ratio: %s\nUL: %s"), dlstr, ulstr );
135    }
136    else
137    {
138        dlstr = readablespeed( dl );
139        str = g_strdup_printf( _("DL: %s\nUL: %s"), dlstr, ulstr );
140    }
141    marked = g_markup_printf_escaped( "<small>%s</small>", str );
142    g_object_set( rend, "markup", str, "progress", prog, NULL );
143    g_free( dlstr );
144    g_free( ulstr );
145    g_free( str );
146    g_free( marked );
147}
148
149static void
150on_popup_menu ( GtkWidget * self UNUSED, GdkEventButton * event )
151{
152    GtkWidget * menu = action_get_widget ( "/main-window-popup" );
153    gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
154                    (event ? event->button : 0),
155                    (event ? event->time : 0));
156}
157
158static void
159view_row_activated ( GtkTreeView       * tree_view  UNUSED,
160                     GtkTreePath       * path       UNUSED,
161                     GtkTreeViewColumn * column     UNUSED,
162                     gpointer            user_data  UNUSED )
163{
164    action_activate( "show-torrent-details" );
165}
166
167static GtkWidget*
168makeview( PrivateData * p )
169{
170    GtkWidget         * view;
171    GtkTreeViewColumn * col;
172    GtkTreeSelection  * sel;
173    GtkCellRenderer   * namerend, * progrend;
174    char              * str;
175
176    view = gtk_tree_view_new();
177
178    p->selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(view) );
179    namerend = gtk_cell_renderer_text_new();
180    p->namerend = namerend;
181    /* note that this renderer is set to ellipsize, just not here */
182    col = gtk_tree_view_column_new_with_attributes( _("Name"), namerend,
183                                                    NULL );
184    gtk_tree_view_column_set_cell_data_func( col, namerend, formatname,
185                                             NULL, NULL );
186    gtk_tree_view_column_set_expand( col, TRUE );
187    gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_AUTOSIZE );
188    gtk_tree_view_column_set_sort_column_id( col, MC_NAME );
189    gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );
190
191    progrend = tr_cell_renderer_progress_new();
192    /* this string is only used to determine the size of the progress bar */
193    str = g_markup_printf_escaped( "<big>%s</big>", "  fnord    fnord  " );
194    g_object_set( progrend, "bar-sizing", str, NULL );
195    g_free(str);
196    col = gtk_tree_view_column_new_with_attributes( _("Progress"), progrend,
197                                                    NULL);
198    gtk_tree_view_column_set_cell_data_func( col, progrend, formatprog,
199                                             NULL, NULL );
200    gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_AUTOSIZE );
201    gtk_tree_view_column_set_sort_column_id( col, MC_PROG_D );
202    gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col );
203
204    gtk_tree_view_set_rules_hint( GTK_TREE_VIEW( view ), TRUE );
205    sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( view ) );
206    gtk_tree_selection_set_mode( GTK_TREE_SELECTION( sel ),
207                                 GTK_SELECTION_MULTIPLE );
208
209    g_signal_connect( view, "popup-menu",
210                      G_CALLBACK(on_popup_menu), NULL );
211    g_signal_connect( view, "button-press-event",
212                      G_CALLBACK(on_tree_view_button_pressed), (void *) on_popup_menu);
213    g_signal_connect( view, "row-activated",
214                      G_CALLBACK(view_row_activated), NULL);
215
216    return view;
217}
218
219static void
220realized_cb ( GtkWidget * wind, gpointer unused UNUSED )
221{
222    PrivateData * p = get_private_data( GTK_WINDOW( wind ) );
223    sizingmagic( GTK_WINDOW(wind), GTK_SCROLLED_WINDOW( p->scroll ),
224                 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
225    g_object_set( p->namerend, "ellipsize", PANGO_ELLIPSIZE_END, NULL );
226}
227
228/***
229****  PUBLIC
230***/
231
232GtkWidget *
233tr_window_new( GtkUIManager * ui_manager )
234{
235    PrivateData * p = g_new( PrivateData, 1 );
236    GtkWidget *vbox, *w, *self, *h;
237
238    /* make the window */
239    self = gtk_window_new (GTK_WINDOW_TOPLEVEL);
240    g_object_set_data_full(G_OBJECT(self), PRIVATE_DATA_KEY, p, g_free );
241    gtk_window_set_title( GTK_WINDOW( self ), g_get_application_name());
242    gtk_window_set_role( GTK_WINDOW( self ), "tr-main" );
243    gtk_window_add_accel_group (GTK_WINDOW(self),
244                                gtk_ui_manager_get_accel_group (ui_manager));
245    g_signal_connect( self, "realize", G_CALLBACK(realized_cb), NULL);
246
247    /* window's main container */
248    vbox = gtk_vbox_new (FALSE, 0);
249    gtk_container_add (GTK_CONTAINER(self), vbox);
250
251    /* main menu */
252    w = action_get_widget( "/main-window-menu" );
253    gtk_box_pack_start( GTK_BOX(vbox), w, FALSE, FALSE, 0 ); 
254
255    /* toolbar */
256    w = action_get_widget( "/main-window-toolbar" );
257    gtk_box_pack_start( GTK_BOX(vbox), w, FALSE, FALSE, 0 ); 
258
259    /* workarea */
260    p->view = makeview( p );
261    w = p->scroll = gtk_scrolled_window_new( NULL, NULL );
262    gtk_container_add( GTK_CONTAINER(w), p->view );
263    gtk_box_pack_start_defaults( GTK_BOX(vbox), w );
264    gtk_container_set_focus_child( GTK_CONTAINER( vbox ), w );
265
266    /* spacer */
267    w = gtk_alignment_new (0.0f, 0.0f, 0.0f, 0.0f);
268    gtk_widget_set_usize (w, 0u, 6u);
269    gtk_box_pack_start( GTK_BOX(vbox), w, FALSE, FALSE, 0 ); 
270
271
272    /* statusbar */
273    h = gtk_hbox_new( FALSE, 0 );
274    w = p->ul_lb = gtk_label_new( NULL );
275    gtk_box_pack_end( GTK_BOX(h), w, FALSE, FALSE, GUI_PAD );
276    w = gtk_vseparator_new( );
277    gtk_box_pack_end( GTK_BOX(h), w, FALSE, FALSE, GUI_PAD );
278    w = p->dl_lb = gtk_label_new( NULL );
279    gtk_box_pack_end( GTK_BOX(h), w, FALSE, FALSE, GUI_PAD );
280    gtk_box_pack_start( GTK_BOX(vbox), h, FALSE, FALSE, 0 );
281
282    /* show all but the window */
283    gtk_widget_show_all( vbox );
284
285    return self;
286}
287
288void
289tr_window_update( TrWindow * self, float downspeed, float upspeed )
290{
291    PrivateData * p = get_private_data( self );
292    char *tmp1, *tmp2;
293
294    tmp1 = readablespeed( downspeed );
295    tmp2 = g_strdup_printf( _("Total DL: %s"), tmp1 );
296    gtk_label_set_text( GTK_LABEL(p->dl_lb), tmp2 );
297    g_free( tmp2 );
298    g_free( tmp1 );
299
300    tmp1 = readablespeed( upspeed );
301    tmp2 = g_strdup_printf( _("Total UL: %s"), tmp1 );
302    gtk_label_set_text( GTK_LABEL(p->ul_lb), tmp2 );
303    g_free( tmp2 );
304    g_free( tmp1 );
305}
306
307GtkTreeSelection*
308tr_window_get_selection ( TrWindow * w )
309{
310    return get_private_data(w)->selection;
311}
Note: See TracBrowser for help on using the repository browser.