mirror of
https://github.com/transmission/transmission
synced 2024-12-24 16:52:39 +00:00
(trunk gtk) #3903 "Scroll to new messages when viewing new messages in the message window" -- added.
This commit is contained in:
parent
5c96f9ebd8
commit
1a862315de
1 changed files with 74 additions and 23 deletions
97
gtk/msgwin.c
97
gtk/msgwin.c
|
@ -50,20 +50,74 @@ struct MsgData
|
||||||
static struct tr_msg_list * myTail = NULL;
|
static struct tr_msg_list * myTail = NULL;
|
||||||
static struct tr_msg_list * myHead = NULL;
|
static struct tr_msg_list * myHead = NULL;
|
||||||
|
|
||||||
/***
|
/****
|
||||||
****
|
*****
|
||||||
***/
|
****/
|
||||||
|
|
||||||
|
/* is the user looking at the latest messages? */
|
||||||
|
static gboolean
|
||||||
|
is_pinned_to_new( struct MsgData * data )
|
||||||
|
{
|
||||||
|
gboolean pinned_to_new;
|
||||||
|
|
||||||
|
if( data->view == NULL )
|
||||||
|
{
|
||||||
|
pinned_to_new = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GtkTreePath * last_visible;
|
||||||
|
if( gtk_tree_view_get_visible_range( data->view, NULL, &last_visible ) )
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
const int row_count = gtk_tree_model_iter_n_children( data->sort, NULL );
|
||||||
|
if( gtk_tree_model_iter_nth_child( data->sort, &iter, NULL, row_count-1 ) )
|
||||||
|
{
|
||||||
|
GtkTreePath * last_row = gtk_tree_model_get_path( data->sort, &iter );
|
||||||
|
pinned_to_new = !gtk_tree_path_compare( last_visible, last_row );
|
||||||
|
gtk_tree_path_free( last_row );
|
||||||
|
}
|
||||||
|
gtk_tree_path_free( last_visible );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pinned_to_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scroll_to_bottom( struct MsgData * data )
|
||||||
|
{
|
||||||
|
if( data->sort != NULL )
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
const int row_count = gtk_tree_model_iter_n_children( data->sort, NULL );
|
||||||
|
if( gtk_tree_model_iter_nth_child( data->sort, &iter, NULL, row_count-1 ) )
|
||||||
|
{
|
||||||
|
GtkTreePath * last_row = gtk_tree_model_get_path( data->sort, &iter );
|
||||||
|
gtk_tree_view_scroll_to_cell( data->view, last_row, NULL, TRUE, 1, 0 );
|
||||||
|
gtk_tree_path_free( last_row );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
*****
|
||||||
|
****/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
level_combo_changed_cb( GtkComboBox * combo_box, gpointer gdata )
|
level_combo_changed_cb( GtkComboBox * combo_box, gpointer gdata )
|
||||||
{
|
{
|
||||||
struct MsgData * data = gdata;
|
struct MsgData * data = gdata;
|
||||||
const int level = gtr_combo_box_get_active_enum( combo_box );
|
const int level = gtr_combo_box_get_active_enum( combo_box );
|
||||||
|
const gboolean pinned_to_new = is_pinned_to_new( data );
|
||||||
|
|
||||||
tr_setMessageLevel( level );
|
tr_setMessageLevel( level );
|
||||||
tr_core_set_pref_int( data->core, TR_PREFS_KEY_MSGLEVEL, level );
|
tr_core_set_pref_int( data->core, TR_PREFS_KEY_MSGLEVEL, level );
|
||||||
data->maxLevel = level;
|
data->maxLevel = level;
|
||||||
gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( data->filter ) );
|
gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( data->filter ) );
|
||||||
|
|
||||||
|
if( pinned_to_new )
|
||||||
|
scroll_to_bottom( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -286,9 +340,7 @@ appendColumn( GtkTreeView * view,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
isRowVisible( GtkTreeModel * model,
|
isRowVisible( GtkTreeModel * model, GtkTreeIter * iter, gpointer gdata )
|
||||||
GtkTreeIter * iter,
|
|
||||||
gpointer gdata )
|
|
||||||
{
|
{
|
||||||
const struct MsgData * data = gdata;
|
const struct MsgData * data = gdata;
|
||||||
const struct tr_msg_list * node;
|
const struct tr_msg_list * node;
|
||||||
|
@ -298,8 +350,7 @@ isRowVisible( GtkTreeModel * model,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
onWindowDestroyed( gpointer gdata,
|
onWindowDestroyed( gpointer gdata, GObject * deadWindow UNUSED )
|
||||||
GObject * deadWindow UNUSED )
|
|
||||||
{
|
{
|
||||||
struct MsgData * data = gdata;
|
struct MsgData * data = gdata;
|
||||||
|
|
||||||
|
@ -308,28 +359,22 @@ onWindowDestroyed( gpointer gdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
static tr_msg_list *
|
static tr_msg_list *
|
||||||
addMessages( GtkListStore * store,
|
addMessages( GtkListStore * store, struct tr_msg_list * head )
|
||||||
struct tr_msg_list * head )
|
|
||||||
{
|
{
|
||||||
const char * default_name = g_get_application_name( );
|
tr_msg_list * i;
|
||||||
static unsigned int sequence = 1;
|
static unsigned int sequence = 0;
|
||||||
tr_msg_list * i;
|
const char * default_name = g_get_application_name( );
|
||||||
|
|
||||||
for( i = head; i; i = i->next )
|
for( i=head; i && i->next; i=i->next )
|
||||||
{
|
{
|
||||||
GtkTreeIter unused;
|
const char * name = i->name ? i->name : default_name;
|
||||||
|
|
||||||
gtk_list_store_insert_with_values( store, &unused, 0,
|
gtk_list_store_insert_with_values( store, NULL, 0,
|
||||||
COL_TR_MSG, i,
|
COL_TR_MSG, i,
|
||||||
COL_NAME,
|
COL_NAME, name,
|
||||||
( i->name ? i->name :
|
|
||||||
default_name ),
|
|
||||||
COL_MESSAGE, i->message,
|
COL_MESSAGE, i->message,
|
||||||
COL_SEQUENCE, sequence++,
|
COL_SEQUENCE, ++sequence,
|
||||||
-1 );
|
-1 );
|
||||||
|
|
||||||
if( !i->next )
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i; /* tail */
|
return i; /* tail */
|
||||||
|
@ -339,6 +384,7 @@ static gboolean
|
||||||
onRefresh( gpointer gdata )
|
onRefresh( gpointer gdata )
|
||||||
{
|
{
|
||||||
struct MsgData * data = gdata;
|
struct MsgData * data = gdata;
|
||||||
|
const gboolean pinned_to_new = is_pinned_to_new( data );
|
||||||
|
|
||||||
if( !data->isPaused )
|
if( !data->isPaused )
|
||||||
{
|
{
|
||||||
|
@ -354,7 +400,11 @@ onRefresh( gpointer gdata )
|
||||||
myHead = msgs;
|
myHead = msgs;
|
||||||
myTail = tail;
|
myTail = tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pinned_to_new )
|
||||||
|
scroll_to_bottom( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,6 +533,7 @@ gtr_message_log_window_new( GtkWindow * parent, TrCore * core )
|
||||||
data->refresh_tag = gtr_timeout_add_seconds( SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS, onRefresh, data );
|
data->refresh_tag = gtr_timeout_add_seconds( SECONDARY_WINDOW_REFRESH_INTERVAL_SECONDS, onRefresh, data );
|
||||||
g_object_weak_ref( G_OBJECT( win ), onWindowDestroyed, data );
|
g_object_weak_ref( G_OBJECT( win ), onWindowDestroyed, data );
|
||||||
|
|
||||||
|
scroll_to_bottom( data );
|
||||||
gtk_widget_show_all( win );
|
gtk_widget_show_all( win );
|
||||||
return win;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue