From 5b12668b9fafb9b8f35ef3a482ce5727cb4f56c8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 6 Jun 2009 04:29:08 +0000 Subject: [PATCH] (trunk gtk) torrents' long file lists were displayed extremely inefficiently --- gtk/file-list.c | 579 +++++++++++++++++++++++++----------------------- gtk/tr-core.c | 1 - 2 files changed, 296 insertions(+), 284 deletions(-) diff --git a/gtk/file-list.c b/gtk/file-list.c index 8a5f9c668..e9edc8afc 100644 --- a/gtk/file-list.c +++ b/gtk/file-list.c @@ -52,7 +52,6 @@ enum FC_ICON, FC_LABEL, FC_PROG, - FC_KEY, FC_INDEX, FC_SIZE, FC_HAVE, @@ -103,200 +102,129 @@ freeData( gpointer gdata ) **** ***/ -static void -parsepath( GtkWidget * w, - const tr_torrent * tor, - GtkTreeStore * store, - GtkTreeIter * ret, - const char * path, - tr_file_index_t index, - uint64_t size ) -{ - GtkTreeModel * model; - GtkTreeIter * parent, start, iter; - char * file, * lower, * mykey; - int priority = 0; - gboolean enabled = TRUE; - gboolean is_file; - GdkPixbuf * icon; - const char * mime_type; - - model = GTK_TREE_MODEL( store ); - parent = NULL; - file = g_path_get_basename( path ); - if( 0 != strcmp( file, path ) ) - { - char * dir = g_path_get_dirname( path ); - parsepath( w, tor, store, &start, dir, index, size ); - parent = &start; - g_free( dir ); - } - - lower = g_utf8_casefold( file, -1 ); - mykey = g_utf8_collate_key( lower, -1 ); - if( gtk_tree_model_iter_children( model, &iter, parent ) ) do - { - gboolean stop; - char * modelkey; - gtk_tree_model_get( model, &iter, FC_KEY, &modelkey, -1 ); - stop = ( modelkey != NULL ) && !strcmp( mykey, modelkey ); - g_free ( modelkey ); - if( stop ) goto done; - } - while( gtk_tree_model_iter_next( model, &iter ) ); - - gtk_tree_store_append( store, &iter, parent ); - if( ( is_file = !ret ) ) - { - priority = tr_torrentGetFilePriority( tor, index ); - enabled = tr_torrentGetFileDL( tor, index ); - mime_type = get_mime_type_from_filename( file ); - } - else - { - size = 0; - mime_type = DIRECTORY_MIME_TYPE; - } - - icon = get_mime_type_icon( mime_type, GTK_ICON_SIZE_MENU, w ); - -#if 0 - gtk_tree_store_set( store, &iter, FC_INDEX, index, - FC_LABEL, file, - FC_KEY, mykey, - FC_ICON, icon, - FC_PRIORITY, priority, - FC_ENABLED, enabled, - FC_IS_FILE, is_file, - FC_SIZE, size, - FC_HAVE, 0, - -1 ); -#else - gtk_tree_store_set( store, &iter, FC_INDEX, index, -1 ); - gtk_tree_store_set( store, &iter, FC_LABEL, file, -1 ); - gtk_tree_store_set( store, &iter, FC_KEY, mykey, -1 ); - gtk_tree_store_set( store, &iter, FC_ICON, icon, -1 ); - gtk_tree_store_set( store, &iter, FC_PRIORITY, priority, -1 ); - gtk_tree_store_set( store, &iter, FC_ENABLED, enabled, -1 ); - gtk_tree_store_set( store, &iter, FC_IS_FILE, is_file, -1 ); - gtk_tree_store_set( store, &iter, FC_SIZE, size, -1 ); - gtk_tree_store_set( store, &iter, FC_HAVE, 0, -1 ); -#endif - - if( icon != NULL ) - g_object_unref( icon ); - -done: - g_free( mykey ); - g_free( lower ); - g_free( file ); - if( NULL != ret ) - *ret = iter; -} - -/*** -**** -***/ - static gboolean refreshFilesForeach( GtkTreeModel * model, GtkTreePath * path UNUSED, GtkTreeIter * iter, gpointer gdata ) { - FileData * data = gdata; - gboolean is_file; + FileData * data = gdata; + gboolean is_file; + gboolean is_enabled; unsigned int index; + uint64_t size; + uint64_t old_have; + int old_sub_state = 0; + int64_t old_sub_size = 0; + int64_t old_sub_have = 0; + int old_prog; + int old_priority; gtk_tree_model_get( model, iter, FC_IS_FILE, &is_file, + FC_ENABLED, &is_enabled, + FC_PRIORITY, &old_priority, FC_INDEX, &index, + FC_HAVE, &old_have, + FC_SIZE, &size, + FC_SUB_STATE, &old_sub_state, + FC_SUB_SIZE, &old_sub_size, + FC_SUB_HAVE, &old_sub_have, + FC_PROG, &old_prog, -1 ); +//g_message ( "is_file {%d} index {%d} name {%s}", (int)is_file, (int)index, name ); if( is_file ) { - GtkTreeStore * store = GTK_TREE_STORE( model ); - tr_torrent * tor = data->tor; - int download = tr_torrentGetFileDL( tor, index ); - int priority = tr_torrentGetFilePriority( tor, index ); - uint64_t have = data->refresh_file_stat[index].bytesCompleted; - gtk_tree_store_set( store, iter, FC_PRIORITY, priority, - FC_ENABLED, download, - FC_HAVE, have, - -1 ); - } - return FALSE; /* keep walking */ -} + int sub_state; + tr_torrent * tor = data->tor; + const int download = tr_torrentGetFileDL( tor, index ); + const int priority = tr_torrentGetFilePriority( tor, index ); + const uint64_t have = data->refresh_file_stat[index].bytesCompleted; + const int prog = (int)((100.0*have)/size); -static gboolean -resetSubForeach( GtkTreeModel * model, - GtkTreePath * path UNUSED, - GtkTreeIter * iter, - gpointer gdata UNUSED ) -{ - /* set the subs to the lowest values... */ - gtk_tree_store_set( GTK_TREE_STORE( model ), iter, - FC_SUB_STATE, 0, - FC_SUB_SIZE, (uint64_t)0, - FC_SUB_HAVE, (uint64_t)0, - -1 ); - return FALSE; /* keep walking */ -} - -static gboolean -addSubForeach( GtkTreeModel * model, - GtkTreePath * path UNUSED, - GtkTreeIter * iter, - gpointer gdata UNUSED ) -{ - uint64_t size; - uint64_t have; - int priority; - gboolean enabled; - gboolean is_file; - - gtk_tree_model_get( model, iter, FC_SIZE, &size, - FC_HAVE, &have, - FC_PRIORITY, &priority, - FC_ENABLED, &enabled, - FC_IS_FILE, &is_file, - -1 ); - if( is_file ) - { - GtkTreeIter child = *iter; - GtkTreeIter parent; - while( ( gtk_tree_model_iter_parent( model, &parent, &child ) ) ) - { - uint64_t sub_size; - uint64_t sub_have; - int sub_state; - gtk_tree_model_get( model, &parent, FC_SUB_SIZE, &sub_size, - FC_SUB_HAVE, &sub_have, - FC_SUB_STATE, &sub_state, - -1 ); - sub_have += have; - sub_size += size; - switch( priority ) - { - case TR_PRI_HIGH: - sub_state |= SUB_STATE_HIGH; break; - - case TR_PRI_NORMAL: - sub_state |= SUB_STATE_NORMAL; break; - - case TR_PRI_LOW: - sub_state |= SUB_STATE_LOW; break; - } - sub_state |= ( enabled ? SUB_STATE_DOWNLOAD : SUB_STATE_IGNORE ); - gtk_tree_store_set( GTK_TREE_STORE( model ), &parent, - FC_SUB_SIZE, sub_size, - FC_SUB_HAVE, sub_have, - FC_SUB_STATE, sub_state, - -1 ); - child = parent; + switch( priority ) { + case TR_PRI_HIGH: sub_state = SUB_STATE_HIGH; break; + case TR_PRI_NORMAL: sub_state = SUB_STATE_NORMAL; break; + case TR_PRI_LOW: sub_state = SUB_STATE_LOW; break; } + sub_state |= ( is_enabled ? SUB_STATE_DOWNLOAD : SUB_STATE_IGNORE ); + + if( (priority!=old_priority) || (download!=is_enabled) + || (have!=old_have) + || (sub_state!=old_sub_state) + || (prog!=old_prog) ) + gtk_tree_store_set( data->store, iter, FC_PRIORITY, priority, + FC_ENABLED, download, + FC_HAVE, have, + FC_SUB_STATE, sub_state, + FC_SUB_HAVE, have, + FC_PROG, (int)((100.0*have)/size), + -1 ); } + else + { + GtkTreeIter child; + int state = 0; + int64_t size = 0; + int64_t have = 0; + int prog; + + /* since gtk_tree_model_foreach() is depth-first, we can + * get the `sub' info by walking the immediate children */ + + if( gtk_tree_model_iter_children( model, &child, iter ) ) do + { + int child_state; + int64_t child_have, child_size; + gtk_tree_model_get( model, &child, FC_SUB_SIZE, &child_size, + FC_SUB_HAVE, &child_have, + FC_SUB_STATE, &child_state, + -1 ); + size += child_size; + have += child_have; + state |= child_state; + } + while( gtk_tree_model_iter_next( model, &child ) ); + + prog = (int)((100.0*have)/size); + + if( (have!=old_sub_have) || (size!=old_sub_size) + || (state!=old_sub_state) + || (prog!=old_prog) ) + gtk_tree_store_set( data->store, iter, FC_SUB_SIZE, size, + FC_SUB_HAVE, have, + FC_SUB_STATE, state, + FC_PROG, prog, + -1 ); + } + return FALSE; /* keep walking */ } +static void +gtr_tree_model_foreach_postorder_subtree( GtkTreeModel * model, + GtkTreeIter * parent, + GtkTreeModelForeachFunc func, + gpointer data ) +{ + GtkTreeIter child; + if( gtk_tree_model_iter_children( model, &child, parent ) ) do + gtr_tree_model_foreach_postorder_subtree( model, &child, func, data ); + while( gtk_tree_model_iter_next( model, &child ) ); + if( parent ) + func( model, NULL, parent, data ); +} + +static void +gtr_tree_model_foreach_postorder( GtkTreeModel * model, + GtkTreeModelForeachFunc func, + gpointer data ) +{ + GtkTreeIter iter; + if( gtk_tree_model_get_iter_first( model, &iter ) ) do + gtr_tree_model_foreach_postorder_subtree( model, &iter, func, data ); + while( gtk_tree_model_iter_next( model, &iter ) ); +} + static void refresh( FileData * data ) { @@ -314,9 +242,9 @@ refresh( FileData * data ) data->tor = tr_torrentFindFromId( tr_core_session( data->core ), data->torrentId ); data->refresh_file_stat = tr_torrentFiles( tor, &fileCount ); - gtk_tree_model_foreach( data->model, refreshFilesForeach, data ); - gtk_tree_model_foreach( data->model, resetSubForeach, data ); - gtk_tree_model_foreach( data->model, addSubForeach, data ); + gtr_tree_model_foreach_postorder( data->model, refreshFilesForeach, data ); + //gtk_tree_model_foreach( data->model, refreshFilesForeach, data ); + //gtk_tree_model_foreach( data->model, addSubForeach, data ); /* clean up the temporary variables */ tr_torrentFilesFree( data->refresh_file_stat, fileCount ); @@ -460,6 +388,84 @@ file_list_clear( GtkWidget * w ) file_list_set_torrent( w, -1 ); } +struct build_data +{ + GtkWidget * w; + tr_torrent * tor; + GtkTreeIter * iter; + GtkTreeStore * store; +}; + +struct row_struct +{ + char * name; + int index; + uint64_t length; +}; + +static void +buildTree( GNode * node, gpointer gdata ) +{ + GtkTreeIter child_iter; + struct build_data * build = gdata; + struct row_struct *child_data = node->data; + const gboolean isLeaf = node->children == NULL; + + const char * mime_type = isLeaf ? get_mime_type_from_filename( child_data->name ) : DIRECTORY_MIME_TYPE; + GdkPixbuf * icon = get_mime_type_icon( mime_type, GTK_ICON_SIZE_MENU, build->w ); + const int priority = isLeaf ? tr_torrentGetFilePriority( build->tor, child_data->index ) : 0; + const gboolean enabled = isLeaf ? tr_torrentGetFileDL( build->tor, child_data->index ) : TRUE; +#if GTK_CHECK_VERSION(2,10,0) + gtk_tree_store_insert_with_values( build->store, &child_iter, build->iter, INT_MAX, + FC_INDEX, child_data->index, + FC_LABEL, child_data->name, + FC_SIZE, child_data->length, + FC_SUB_SIZE, child_data->length, + FC_ICON, icon, + FC_PRIORITY, priority, + FC_ENABLED, enabled, + FC_IS_FILE, isLeaf, + -1 ); +#else + gtk_tree_store_append( build->store, &child_iter, build->iter ); + gtk_tree_store_set( build->store, &child_iter, + FC_INDEX, child_data->index, + FC_LABEL, child_data->name, + FC_SIZE, child_data->length, + FC_ICON, icon, + FC_PRIORITY, priority, + FC_ENABLED, enabled, + FC_IS_FILE, isLeaf, + -1 ); +#endif + + if( !isLeaf ) + { + struct build_data b = *build; + b.iter = &child_iter; + g_node_children_foreach( node, G_TRAVERSE_ALL, buildTree, &b ); + } + + g_object_unref( icon ); + + /* we're done with this node */ + g_free( child_data->name ); + g_free( child_data ); +} + +static GNode* +find_child( GNode* parent, const char * name ) +{ + GNode * child = parent->children; + while( child ) { + const struct row_struct * child_data = child->data; + if( ( *child_data->name == *name ) && !strcmp( child_data->name, name ) ) + break; + child = child->next; + } + return child; +} + void file_list_set_torrent( GtkWidget * w, int torrentId ) { @@ -474,7 +480,6 @@ file_list_set_torrent( GtkWidget * w, int torrentId ) GDK_TYPE_PIXBUF, /* icon */ G_TYPE_STRING, /* label */ G_TYPE_INT, /* prog [0..100] */ - G_TYPE_STRING, /* key */ G_TYPE_UINT, /* index */ G_TYPE_UINT64, /* size */ G_TYPE_UINT64, /* have */ @@ -498,13 +503,48 @@ file_list_set_torrent( GtkWidget * w, int torrentId ) { tr_file_index_t i; const tr_info * inf = tr_torrentInfo( tor ); + struct row_struct * root_data; + GNode * root; + struct build_data build; - for( i=0; ifileCount; ++i ) - { - const char * path = inf->files[i].name; - const char * base = g_path_is_absolute( path ) ? g_path_skip_root( path ) : path; - parsepath( w, tor, store, NULL, base, i, inf->files[i].length ); + /* build a GNode tree of the files */ + root_data = g_new0( struct row_struct, 1 ); + root_data->name = g_strdup( inf->name ); + root_data->index = -1; + root_data->length = 0; + root = g_node_new( root_data ); + for( i=0; ifileCount; ++i ) { + int j; + GNode * parent = root; + const tr_file * file = &inf->files[i]; + char ** tokens = g_strsplit( file->name, G_DIR_SEPARATOR_S, 0 ); + for( j=0; tokens[j]; ++j ) { + const gboolean isLeaf = tokens[j+1] == NULL; + const char * name = tokens[j]; + GNode * node = find_child( parent, name ); + if( node == NULL ) { + struct row_struct * row = g_new( struct row_struct, 1 ); + row->name = g_strdup( name ); + row->index = isLeaf ? (int)i : -1; + row->length = isLeaf ? file->length : 0; + node = g_node_new( row ); + g_node_append( parent, node ); + } + parent = node; + } + g_strfreev( tokens ); } + + /* now, add them to the model */ + build.w = w; + build.tor = tor; + build.store = data->store; + build.iter = NULL; + g_node_children_foreach( root, G_TRAVERSE_ALL, buildTree, &build ); + + /* cleanup */ + g_node_destroy( root ); + g_free( root_data ); } refresh( data ); @@ -519,50 +559,23 @@ file_list_set_torrent( GtkWidget * w, int torrentId ) **** ***/ -static void -renderProgress( GtkTreeViewColumn * column UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, - gpointer data UNUSED ) -{ - gboolean is_file; - uint64_t size, have, subsize, subhave; - double progress; - - gtk_tree_model_get( model, iter, FC_SIZE, &size, - FC_HAVE, &have, - FC_SUB_SIZE, &subsize, - FC_SUB_HAVE, &subhave, - FC_IS_FILE, &is_file, - -1 ); - progress = is_file ? tr_getRatio( have, size ) - : tr_getRatio( subhave, subsize ); - g_object_set( renderer, "value", (int)( progress * 100 ), NULL ); -} - static void renderFilename( GtkTreeViewColumn * column UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, + GtkCellRenderer * renderer, + GtkTreeModel * model, + GtkTreeIter * iter, gpointer data UNUSED ) { char * filename; char * str; - int64_t size; int64_t subsize; - gboolean is_file; char buf[64]; gtk_tree_model_get( model, iter, FC_LABEL, &filename, - FC_SIZE, &size, - FC_SUB_SIZE, &subsize, - FC_IS_FILE, &is_file, - -1 ); - tr_strlsize( buf, is_file ? size : subsize, sizeof( buf ) ); - str = g_markup_printf_escaped( "%s (%s)", - filename, buf ); + FC_SUB_SIZE, &subsize, + -1 ); + tr_strlsize( buf, subsize, sizeof( buf ) ); + str = g_markup_printf_escaped( "%s (%s)", filename, buf ); g_object_set( renderer, "markup", str, NULL ); g_free( str ); g_free( filename ); @@ -570,9 +583,9 @@ renderFilename( GtkTreeViewColumn * column UNUSED, static void renderDownload( GtkTreeViewColumn * column UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, + GtkCellRenderer * renderer, + GtkTreeModel * model, + GtkTreeIter * iter, gpointer data UNUSED ) { int sub_state; @@ -582,9 +595,9 @@ renderDownload( GtkTreeViewColumn * column UNUSED, gboolean is_file = FALSE; gtk_tree_model_get( model, iter, FC_IS_FILE, &is_file, - FC_ENABLED, &enabled, - FC_SUB_STATE, &sub_state, - -1 ); + FC_ENABLED, &enabled, + FC_SUB_STATE, &sub_state, + -1 ); if( is_file && enabled ) active = TRUE; else if( is_file ) @@ -608,9 +621,9 @@ renderDownload( GtkTreeViewColumn * column UNUSED, static void renderPriority( GtkTreeViewColumn * column UNUSED, - GtkCellRenderer * renderer, - GtkTreeModel * model, - GtkTreeIter * iter, + GtkCellRenderer * renderer, + GtkTreeModel * model, + GtkTreeIter * iter, gpointer data UNUSED ) { int priority; @@ -619,54 +632,33 @@ renderPriority( GtkTreeViewColumn * column UNUSED, const char * text = ""; gtk_tree_model_get( model, iter, FC_IS_FILE, &is_file, - FC_PRIORITY, &priority, - FC_SUB_STATE, &sub_state, - -1 ); - if( !is_file ) - { - switch( sub_state & SUB_STATE_PRIORITY_MASK ) - { - case SUB_STATE_HIGH: - priority = TR_PRI_HIGH; break; - - case SUB_STATE_NORMAL: - priority = TR_PRI_NORMAL; break; - - case SUB_STATE_LOW: - priority = TR_PRI_LOW; break; - - default: - priority = 666; break; + FC_PRIORITY, &priority, + FC_SUB_STATE, &sub_state, + -1 ); + if( !is_file ) { + switch( sub_state & SUB_STATE_PRIORITY_MASK ) { + case SUB_STATE_HIGH: priority = TR_PRI_HIGH; break; + case SUB_STATE_NORMAL: priority = TR_PRI_NORMAL; break; + case SUB_STATE_LOW: priority = TR_PRI_LOW; break; + default: priority = 666; break; } } - switch( priority ) - { - case TR_PRI_HIGH: - text = _( "High" ); - break; - - case TR_PRI_NORMAL: - text = _( "Normal" ); - break; - - case TR_PRI_LOW: - text = _( "Low" ); - break; - - default: - text = _( "Mixed" ); - break; + switch( priority ) { + case TR_PRI_HIGH: text = _( "High" ); break; + case TR_PRI_NORMAL: text = _( "Normal" ); break; + case TR_PRI_LOW: text = _( "Low" ); break; + default: text = _( "Mixed" ); break; } g_object_set( renderer, "text", text, - "xalign", (gfloat)0.5, - "yalign", (gfloat)0.5, - NULL ); + "xalign", (gfloat)0.5, + "yalign", (gfloat)0.5, + NULL ); } static gboolean -onViewButtonPressed( GtkWidget * w, +onViewButtonPressed( GtkWidget * w, GdkEventButton * event, gpointer gdata ) { @@ -710,13 +702,12 @@ onViewButtonPressed( GtkWidget * w, /* get the `priority' state of the clicked row */ gtk_tree_model_get( model, &iter, FC_IS_FILE, &is_file, - FC_PRIORITY, &priority, - FC_SUB_STATE, &sub_state, - -1 ); + FC_PRIORITY, &priority, + FC_SUB_STATE, &sub_state, + -1 ); /* twiddle it to the next state */ - if( !is_file ) switch( sub_state & - SUB_STATE_PRIORITY_MASK ) + if( !is_file ) switch( sub_state & SUB_STATE_PRIORITY_MASK ) { case SUB_STATE_NORMAL: priority = TR_PRI_HIGH; break; @@ -753,8 +744,8 @@ onViewButtonPressed( GtkWidget * w, /* get the `enabled' state of the clicked row */ gtk_tree_model_get( model, &iter, FC_IS_FILE, &is_file, - FC_ENABLED, &enabled, - FC_SUB_STATE, &sub_state, -1 ); + FC_ENABLED, &enabled, + FC_SUB_STATE, &sub_state, -1 ); /* twiddle it to the next state */ if( is_file ) @@ -790,6 +781,9 @@ onViewButtonPressed( GtkWidget * w, GtkWidget * file_list_new( TrCore * core, int torrentId ) { + const char * title; + PangoLayout * pango_layout; + int width; GtkWidget * ret; GtkWidget * view, * scroll; GtkCellRenderer * rend; @@ -801,6 +795,7 @@ file_list_new( TrCore * core, int torrentId ) /* create the view */ view = gtk_tree_view_new( ); + gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW( view ), TRUE ); gtk_tree_view_set_rules_hint( GTK_TREE_VIEW( view ), TRUE ); gtk_container_set_border_width( GTK_CONTAINER( view ), GUI_PAD_BIG ); g_signal_connect( view, "button-press-event", @@ -821,6 +816,7 @@ file_list_new( TrCore * core, int torrentId ) "expand", TRUE, "title", _( "File" ), NULL ) ); + gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_FIXED ); rend = gtk_cell_renderer_pixbuf_new( ); gtk_tree_view_column_pack_start( col, rend, FALSE ); gtk_tree_view_column_add_attribute( col, rend, "pixbuf", FC_ICON ); @@ -829,27 +825,45 @@ file_list_new( TrCore * core, int torrentId ) g_object_set( rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL ); gtk_tree_view_column_pack_start( col, rend, TRUE ); gtk_tree_view_column_set_cell_data_func( col, rend, renderFilename, NULL, NULL ); - gtk_tree_view_column_set_resizable( col, TRUE ); gtk_tree_view_append_column( GTK_TREE_VIEW( view ), col ); + /* add "progress" column */ + title = _( "Progress" ); + pango_layout = gtk_widget_create_pango_layout( view, title ); + pango_layout_get_pixel_size( pango_layout, &width, NULL ); + width += GUI_PAD * 2; + g_object_unref( G_OBJECT( pango_layout ) ); rend = gtk_cell_renderer_progress_new( ); - col = gtk_tree_view_column_new_with_attributes( _( "Progress" ), rend, NULL ); - gtk_tree_view_column_set_cell_data_func( col, rend, renderProgress, NULL, NULL ); - gtk_tree_view_column_set_resizable( col, FALSE ); + col = gtk_tree_view_column_new_with_attributes( title, rend, "value", FC_PROG, NULL ); + gtk_tree_view_column_set_fixed_width( col, width ); + gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_FIXED ); + //gtk_tree_view_column_set_cell_data_func( col, rend, renderProgress, NULL, NULL ); gtk_tree_view_append_column ( GTK_TREE_VIEW( view ), col ); /* add "enabled" column */ + title = _( "Download" ); + pango_layout = gtk_widget_create_pango_layout( view, title ); + pango_layout_get_pixel_size( pango_layout, &width, NULL ); + width += GUI_PAD * 2; + g_object_unref( G_OBJECT( pango_layout ) ); rend = gtk_cell_renderer_toggle_new( ); - col = gtk_tree_view_column_new_with_attributes( _( "Download" ), rend, NULL ); + col = gtk_tree_view_column_new_with_attributes( title, rend, NULL ); + gtk_tree_view_column_set_fixed_width( col, width ); + gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_FIXED ); gtk_tree_view_column_set_cell_data_func( col, rend, renderDownload, NULL, NULL ); - gtk_tree_view_column_set_resizable( col, FALSE ); gtk_tree_view_append_column ( GTK_TREE_VIEW( view ), col ); /* add priority column */ + title = _( "Priority" ); + pango_layout = gtk_widget_create_pango_layout( view, title ); + pango_layout_get_pixel_size( pango_layout, &width, NULL ); + width += GUI_PAD * 2; + g_object_unref( G_OBJECT( pango_layout ) ); rend = gtk_cell_renderer_text_new( ); - col = gtk_tree_view_column_new_with_attributes( _( "Priority" ), rend, NULL ); + col = gtk_tree_view_column_new_with_attributes( title, rend, NULL ); + gtk_tree_view_column_set_fixed_width( col, width ); + gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_FIXED ); gtk_tree_view_column_set_cell_data_func( col, rend, renderPriority, NULL, NULL ); - gtk_tree_view_column_set_resizable( col, FALSE ); gtk_tree_view_append_column ( GTK_TREE_VIEW( view ), col ); /* create the scrolled window and stick the view in it */ @@ -870,4 +884,3 @@ file_list_new( TrCore * core, int torrentId ) return ret; } - diff --git a/gtk/tr-core.c b/gtk/tr-core.c index 817813272..014f10e00 100644 --- a/gtk/tr-core.c +++ b/gtk/tr-core.c @@ -1437,7 +1437,6 @@ tr_core_blocklist_update( TrCore * core ) void tr_core_exec_json( TrCore * core, const char * json ) { - g_message( "executing %s", json ); sendRequest( core, json, 0, NULL, NULL ); }