Move model appending, updating, and deleting to TrCore.

The TrTorrent refcounting clusterfuck should be isolated from main.c now.
This commit is contained in:
Josh Elsasser 2007-05-23 02:45:28 +00:00
parent c32c517d46
commit 51b8ea47c9
3 changed files with 156 additions and 86 deletions

View File

@ -784,10 +784,6 @@ setpex( tr_torrent_t * tor, void * arg )
gboolean
updatemodel(gpointer gdata) {
struct cbdata *data = gdata;
GtkTreeModel * model;
TrTorrent *tor;
tr_stat_t *st;
GtkTreeIter iter;
float up, down;
if( !data->closing && 0 < global_sigcount )
@ -796,27 +792,8 @@ updatemodel(gpointer gdata) {
return FALSE;
}
model = tr_core_model( data->core );
if( gtk_tree_model_get_iter_first( model, &iter ) )
{
do {
gtk_tree_model_get( model, &iter, MC_TORRENT, &tor, -1);
st = tr_torrent_stat(tor);
g_object_unref(tor);
/* XXX find out if setting the same data emits changed signal */
gtk_list_store_set( GTK_LIST_STORE( model ), &iter,
MC_STAT, st->status, MC_ERR, st->error,
MC_TERR, st->errorString, MC_PROG, st->progress,
MC_DRATE, st->rateDownload, MC_URATE, st->rateUpload,
MC_ETA, st->eta, MC_PEERS, st->peersTotal,
MC_UPEERS, st->peersUploading, MC_DPEERS, st->peersDownloading,
MC_SEED, st->seeders, MC_LEECH, st->leechers,
MC_DONE, st->completedFromTracker, MC_TRACKER, st->tracker,
MC_DOWN, st->downloaded, MC_UP, st->uploaded,
MC_LEFT, st->left, -1);
}
while( gtk_tree_model_iter_next( model, &iter ) );
}
/* update the torrent data in the model */
tr_core_update( data->core );
/* update the main window's statusbar and toolbar buttons */
if( NULL != data->wind )
@ -825,7 +802,7 @@ updatemodel(gpointer gdata) {
tr_window_update( TR_WINDOW( data->wind ), down, up );
}
/* check for politely stopped torrents unless we're exiting */
/* check for stopped torrents unless we're exiting */
if( !data->closing )
{
tr_core_reap( data->core );
@ -964,14 +941,7 @@ handleaction( struct cbdata * data, int act )
changed = TRUE;
break;
case ACT_DELETE:
/* tor will be unref'd in the politely_stopped handler */
g_object_ref( tor );
tr_torrent_stop_politely( tor );
if( TR_FLAG_SAVE & tr_torrent_info( tor )->flags )
{
tr_torrentRemoveSaved( tr_torrent_handle( tor ) );
}
gtk_list_store_remove( GTK_LIST_STORE( model ), &iter );
tr_core_delete_torrent( data->core, tor, &iter );
changed = TRUE;
break;
case ACT_INFO:
@ -1008,20 +978,17 @@ static void
addtorrents(void *vdata, void *state, GList *files,
const char *dir, guint flags) {
struct cbdata *data = vdata;
GList *torlist, *errlist, *ii;
GList *errlist, *ii;
char *errstr;
TrTorrent *tor;
GtkTreeModel * model;
GtkTreeIter iter;
const char * pref;
tr_info_t *in;
int added;
errlist = NULL;
torlist = NULL;
added = 0;
if( NULL != state )
{
torlist = tr_core_load( data->core, state, &errlist );
added += tr_core_load( data->core, state, &errlist );
}
if(NULL != files) {
@ -1037,29 +1004,15 @@ addtorrents(void *vdata, void *state, GList *files,
}
for(ii = g_list_first(files); NULL != ii; ii = ii->next) {
errstr = NULL;
tor = tr_core_new_torrent( data->core, ii->data, dir, flags, &errstr);
if(NULL != tor)
torlist = g_list_append(torlist, tor);
if( tr_core_add_torrent( data->core, ii->data, dir, flags, &errstr ) )
{
added++;
}
if(NULL != errstr)
errlist = g_list_append(errlist, errstr);
}
}
model = tr_core_model( data->core );
for( ii = g_list_first( torlist ); NULL != ii; ii = ii->next )
{
gtk_list_store_append( GTK_LIST_STORE( model ), &iter );
in = tr_torrent_info( ii->data );
gtk_list_store_set( GTK_LIST_STORE( model ), &iter,
MC_NAME, in->name,
MC_SIZE, in->totalSize,
MC_TORRENT, ii->data, -1);
/* we will always ref a torrent before politely stopping it */
g_signal_connect( ii->data, "politely_stopped",
G_CALLBACK( g_object_unref ), data );
g_object_unref( ii->data );
}
if(NULL != errlist) {
errstr = joinstrlist(errlist, "\n");
errmsg( data->wind, ngettext( "Failed to load torrent file:\n%s",
@ -1070,7 +1023,8 @@ addtorrents(void *vdata, void *state, GList *files,
g_free(errstr);
}
if(NULL != torlist) {
if( 0 < added )
{
updatemodel(data);
savetorrents(data);
}

View File

@ -28,6 +28,7 @@
#include <glib/gi18n.h>
#include "bencode.h"
#include "transmission.h"
#include "tr_backend.h"
#include "tr_core.h"
@ -40,6 +41,8 @@ static void
tr_core_class_init( gpointer g_class, gpointer g_class_data );
static void
tr_core_dispose( GObject * obj );
static void
tr_core_insert( TrCore * self, TrTorrent * tor );
GType
tr_core_get_type( void )
@ -67,7 +70,7 @@ tr_core_get_type( void )
return type;
}
static void
void
tr_core_class_init( gpointer g_class, gpointer g_class_data SHUTUP )
{
GObjectClass * gobject_class;
@ -76,7 +79,7 @@ tr_core_class_init( gpointer g_class, gpointer g_class_data SHUTUP )
gobject_class->dispose = tr_core_dispose;
}
static void
void
tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
{
TrCore * self = (TrCore *) instance;
@ -108,7 +111,7 @@ tr_core_init( GTypeInstance * instance, gpointer g_class SHUTUP )
self->disposed = FALSE;
}
static void
void
tr_core_dispose( GObject * obj )
{
TrCore * self = (TrCore *) obj;
@ -212,15 +215,6 @@ tr_core_reap( TrCore * self )
{
TR_IS_CORE( self );
tr_backend_torrents_stopped( self->backend, FALSE );
}
GList *
tr_core_load( TrCore * self, benc_val_t * state, GList ** errors )
{
TR_IS_CORE( self );
return tr_backend_load_state( self->backend, state, 0, errors );
}
void
@ -231,12 +225,123 @@ tr_core_save( TrCore * self, char ** error )
tr_backend_save_state( self->backend, error );
}
TrTorrent *
tr_core_new_torrent( TrCore * self, const char * torrent, const char * dir,
int
tr_core_load( TrCore * self, benc_val_t * state, GList ** errors )
{
GList * tors, * ii;
int count;
TR_IS_CORE( self );
count = 0;
tors = tr_backend_load_state( self->backend, state, 0, errors );
for( ii = g_list_first( tors ); NULL != ii; ii = ii->next )
{
tr_core_insert( self, ii->data );
count++;
}
g_list_free( tors );
return count;
}
gboolean
tr_core_add_torrent( TrCore * self, const char * torrent, const char * dir,
guint flags, char ** err )
{
TrTorrent * tor;
TR_IS_CORE( self );
tor = tr_torrent_new( G_OBJECT( self->backend ),
torrent, dir, flags, err );
if( NULL == tor )
{
return FALSE;
}
tr_core_insert( self, tor );
return TRUE;
}
void
tr_core_delete_torrent( TrCore * self, void * torrent,
GtkTreeIter * iter )
{
TR_IS_CORE( self );
return tr_torrent_new( G_OBJECT( self->backend ),
torrent, dir, flags, err );
/* tor will be unref'd in the politely_stopped handler */
g_object_ref( torrent );
tr_torrent_stop_politely( torrent );
if( TR_FLAG_SAVE & tr_torrent_info( torrent )->flags )
{
tr_torrentRemoveSaved( tr_torrent_handle( torrent ) );
}
gtk_list_store_remove( GTK_LIST_STORE( self->model ), iter );
}
void
tr_core_insert( TrCore * self, TrTorrent * tor )
{
GtkTreeIter iter;
tr_info_t * inf;
gtk_list_store_append( GTK_LIST_STORE( self->model ), &iter );
inf = tr_torrent_info( tor );
/* inserting the torrent into the model adds a reference */
gtk_list_store_set( GTK_LIST_STORE( self->model ), &iter,
MC_NAME, inf->name,
MC_SIZE, inf->totalSize,
MC_TORRENT, tor,
-1);
/* we will always ref a torrent before politely stopping it */
g_signal_connect( tor, "politely_stopped",
G_CALLBACK( g_object_unref ), NULL );
g_object_unref( tor );
}
void
tr_core_update( TrCore * self )
{
GtkTreeIter iter;
TrTorrent * tor;
tr_stat_t * st;
TR_IS_CORE( self );
if( gtk_tree_model_get_iter_first( self->model, &iter ) )
{
do
{
gtk_tree_model_get( self->model, &iter, MC_TORRENT, &tor, -1 );
st = tr_torrent_stat( tor );
g_object_unref( tor );
/* XXX find out if setting the same data emits changed signal */
gtk_list_store_set( GTK_LIST_STORE( self->model ), &iter,
MC_STAT, st->status,
MC_ERR, st->error,
MC_TERR, st->errorString,
MC_PROG, st->progress,
MC_DRATE, st->rateDownload,
MC_URATE, st->rateUpload,
MC_ETA, st->eta,
MC_PEERS, st->peersTotal,
MC_UPEERS, st->peersUploading,
MC_DPEERS, st->peersDownloading,
MC_SEED, st->seeders,
MC_LEECH, st->leechers,
MC_DONE, st->completedFromTracker,
MC_TRACKER, st->tracker,
MC_DOWN, st->downloaded,
MC_UP, st->uploaded,
MC_LEFT, st->left,
-1 );
}
while( gtk_tree_model_iter_next( self->model, &iter ) );
}
}

View File

@ -93,24 +93,35 @@ tr_core_did_quit( TrCore * self );
void
tr_core_force_quit( TrCore * self );
/* Reap any dead torrents */
/* Check for stopped torrents */
void
tr_core_reap( TrCore * self );
/* Load saved state, return list of TrTorrent*. A char* is appended to
*errors for each error which occurs, these must be freed. */
GList *
tr_core_load( TrCore * self, benc_val_t * state, GList ** errors );
/* Save state. Set *error to any error which occurs, this must be freed. */
/* Save state. If error is not NULL is will be set to any error which
occurs, this must be freed. */
void
tr_core_save( TrCore * self, char ** error );
/* XXX temporary hack for transition away from TrBackend */
struct _TrTorrent *
tr_core_new_torrent( TrCore * self, const char * torrent, const char * dir,
/* Load saved state, return number of torrents added. If errors is not
NULL then a char* is appended for each error which occurs, these
must be freed. */
int
tr_core_load( TrCore * self, benc_val_t * state, GList ** errors );
/* Add a torrent. Torrent, dir, flags, and err arguments are the same
as tr_torrent_new() */
gboolean
tr_core_add_torrent( TrCore * self, const char * torrent, const char * dir,
guint flags, char ** err );
/* remove a torrent, waiting for it to pause if necessary */
void
tr_core_delete_torrent( TrCore * self, void * torrent,
GtkTreeIter * iter /* XXX */ );
void
tr_core_update( TrCore * self );
/* column names for the model used to store torrent information */
/* keep this in sync with the type array in tr_core_init() in tr_core.c */
enum {