/* (C) 2004 John Schweitzer This is the goo for the main window GtkTreeView Widget. Its complicated enough to move into another file. This is part of gtkcutlass. */ // GTK & Glade crap #include #include #include #include void gtkcutlass_add_gtktree( GladeXML *xml ) /* SuX0rs. It looks like I am going to have to: 1. find the widget. (peepstreeview, ) 2. manually add shit to it. 3. hope it works */ { GtkWidget * peepstreeview; GtkTreeViewColumn *col; GtkTreeStore *peepstreestore; GtkCellRenderer *renderer; extern gui_status *currentstatus; /* =============================== VIEW ========================================================================== */ if ( xml == NULL ) return ; /* grab the tree view widget from the glade UI definition */ peepstreeview = glade_xml_get_widget( xml, "peepstreeview" ); if ( peepstreeview == NULL ) g_error( "Cannot find the 'peepstreeview' domain in the glade XML file. abort()ing\n" ); col = gtk_tree_view_column_new(); /* title the column */ gtk_tree_view_column_set_title( col, "Name" ); /* Add the column to the treeview */ gtk_tree_view_append_column( GTK_TREE_VIEW( peepstreeview ) , col ); /* create a new renderer */ renderer = gtk_cell_renderer_text_new(); /* attach the renderer to the newly created column */ gtk_tree_view_column_pack_start( col, renderer, TRUE ); g_object_set( renderer, "text", "Boooo!", NULL ); /* attach the column to the COL_NAME'th column (and declare it text, etc)*/ gtk_tree_view_column_add_attribute( col, renderer, "text", COL_NAME ); col = gtk_tree_view_column_new(); /* title the column */ gtk_tree_view_column_set_title( col, "O" ); /* Add the column to the treeview */ gtk_tree_view_append_column( GTK_TREE_VIEW( peepstreeview ), col ); /* create a new renderer */ renderer = gtk_cell_renderer_text_new(); /* attach the renderer to the newly created column */ gtk_tree_view_column_pack_start( col, renderer, TRUE ); /* attach the column to the COL_NAME'th column (and declare it text, etc)*/ gtk_tree_view_column_add_attribute( col, renderer, "text", COL_ONLINE_STATUS ); col = gtk_tree_view_column_new(); /* title the column */ gtk_tree_view_column_set_title( col, "V" ); /* Add the column to the treeview */ gtk_tree_view_append_column( GTK_TREE_VIEW( peepstreeview ), col ); /* create a new renderer */ renderer = gtk_cell_renderer_text_new(); /* attach the renderer to the newly created column */ gtk_tree_view_column_pack_start( col, renderer, TRUE ); /* attach the column to the COL_NAME'th column (and declare it text, etc)*/ gtk_tree_view_column_add_attribute( col, renderer, "text", COL_VIDEO ); col = gtk_tree_view_column_new(); /* title the column */ gtk_tree_view_column_set_title( col, "A" ); /* Add the column to the treeview */ gtk_tree_view_append_column( GTK_TREE_VIEW( peepstreeview ), col ); /* create a new renderer */ renderer = gtk_cell_renderer_text_new(); /* attach the renderer to the newly created column */ gtk_tree_view_column_pack_start( col, renderer, TRUE ); /* attach the column to the COL_NAME'th column (and declare it text, etc)*/ gtk_tree_view_column_add_attribute( col, renderer, "text", COL_AUDIO ); col = gtk_tree_view_column_new(); /* title the column */ gtk_tree_view_column_set_title( col, "F" ); /* Add the column to the treeview */ gtk_tree_view_append_column( GTK_TREE_VIEW( peepstreeview ), col ); /* create a new renderer */ renderer = gtk_cell_renderer_text_new(); /* attach the renderer to the newly created column */ gtk_tree_view_column_pack_start( col, renderer, TRUE ); /* attach the column to the COL_NAME'th column (and declare it text, etc)*/ gtk_tree_view_column_add_attribute( col, renderer, "text", COL_FILE ); /* fill in a test group */ /* gtk_tree_store_set(GTK_TREE_STORE(peepstreestore),&toplevel, COL_NAME, "Testgroup ", COL_ONLINE_STATUS,TRUE , COL_VIDEO, FALSE, COL_AUDIO, FALSE, COL_FILE, FALSE, -1); */ /* gtk_tree_store_append(peepstreestore, &child, &toplevel); */ /* fill in some test data */ /* gtk_tree_store_set(GTK_TREE_STORE(peepstreestore),&child, COL_NAME, "Testdude 1", COL_ONLINE_STATUS,TRUE, COL_VIDEO, FALSE, COL_AUDIO,FALSE, COL_FILE, FALSE, -1); */ peepstreestore = populate_treestore(); /* =============================== END STORE ===================================================================== */ gtk_tree_view_set_model( GTK_TREE_VIEW( peepstreeview ), GTK_TREE_MODEL( peepstreestore ) ); g_object_unref( peepstreestore ); /* destroy model automatically with view */ gtk_tree_selection_set_mode( gtk_tree_view_get_selection( GTK_TREE_VIEW( peepstreeview ) ), GTK_SELECTION_SINGLE ); currentstatus->Tree = GTK_TREE_VIEW( peepstreeview ); // keep the global structure updated; } void on_peepstreeview_row_collapsed ( GtkWidget *widget, gpointer user_data ) { extern gui_status * currentstatus; currentstatus->something_selected = FALSE; // nada // nada FTM }; GtkTreeStore *populate_treestore( void ) /* From the global user_info structure, populate a GtkTreeStore with the info, preserving the group and contact info. (users in groups, etc) */ { extern user_info * userstuff; GtkTreeStore *treestore; GtkTreeIter toplevel, child; gchar *tmpname; GSList *groups = NULL; contact_group *tempcgroup; GSList *contacts = NULL; contact_info *contactinfo; /* Create the columns : identifier (name or nickname) and 3 columns of status icons */ treestore = gtk_tree_store_new ( GTKC_NUM_TREE_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN ); contacts = ( GSList * ) userstuff->contacts; while ( contacts != NULL ) { contactinfo = ( contact_info * ) contacts->data; gtk_tree_store_append( GTK_TREE_STORE( treestore ), &toplevel, NULL ); /* prefer the nickname, if there is one */ if ( contactinfo->nickname != NULL ) tmpname = g_strdup( contactinfo->nickname ); else tmpname = g_strdup( contactinfo->contactname ); gtk_tree_store_set( GTK_TREE_STORE( treestore ), &toplevel, COL_NAME, tmpname, COL_ONLINE_STATUS, FALSE, // haven't checked yet, dedfault to off COL_VIDEO, contactinfo->videocapable, COL_AUDIO, contactinfo->audiocapable, COL_FILE, contactinfo->fileserver, -1 ); contacts = contacts->next; } groups = ( gpointer ) userstuff->groups; while ( groups != NULL ) { tempcgroup = ( contact_group * ) groups->data; gtk_tree_store_append( GTK_TREE_STORE( treestore ), &toplevel, NULL ); gtk_tree_store_set( GTK_TREE_STORE( treestore ), &toplevel, COL_NAME, tempcgroup->groupname, -1 ); while ( tempcgroup->contacts != NULL ) { contacts = ( GSList * ) tempcgroup->contacts; contactinfo = ( contact_info * ) contacts->data; gtk_tree_store_append( treestore, &child, &toplevel ); if ( contactinfo->nickname != NULL ) tmpname = g_strdup( contactinfo->nickname ); else tmpname = g_strdup( contactinfo->contactname ); gtk_tree_store_set( GTK_TREE_STORE( treestore ), &child, COL_NAME, tmpname, COL_ONLINE_STATUS, contactinfo->connected, // haven't checked yet, dedfault to off COL_VIDEO, contactinfo->videocapable, COL_AUDIO, contactinfo->audiocapable, COL_FILE, contactinfo->fileserver, -1 ); contacts = contacts->next; } groups = groups->next; } return ( treestore ); } void on_peepstreeview_row_activated ( GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer user_data ) { extern gui_status * currentstatus; GtkTreeModel *model; model = gtk_tree_view_get_model ( treeview ); if ( gtk_tree_model_get_iter( model, ¤tstatus->selection, arg1 ) ) { gchar * name; gtk_tree_model_get ( model, ¤tstatus->selection, COL_NAME, &name, -1 ); currentstatus->something_selected = TRUE; currentstatus->selectedname = g_strdup ( name ); g_free( name ); // this will be interesting. I am going to default to text conversation. TextConnect(); } }; void on_peepstreeview_row_expanded ( GtkWidget *widget, gpointer user_data ) { extern gui_status * currentstatus; currentstatus->something_selected = FALSE; }; void on_peepstreeview_select_all ( GtkWidget *widget, gpointer user_data ) { extern gui_status * currentstatus; currentstatus->something_selected = TRUE; }; void on_peepstreeview_realize ( GtkWidget *widget, gpointer user_data ) { extern gui_status * currentstatus; currentstatus->something_selected = FALSE; } void on_peepstreeview_select_cursor_row ( GtkWidget *widget , gpointer user_data ) { extern gui_status * currentstatus; currentstatus->something_selected = FALSE; } void append_treestore_contactinfo ( contact_info *ci ) /* this will append one contact_info entry to the treelist (well, the model, actually */ { extern gui_status * currentstatus; GtkTreeView *gtkt; GtkTreeStore *treestore; GtkTreeIter toplevel; gchar *tmpname; gtkt = currentstatus->Tree; treestore = GTK_TREE_STORE( gtk_tree_view_get_model( gtkt ) ); gtk_tree_store_append( GTK_TREE_STORE( treestore ), &toplevel, NULL ); /* prefer the nickname, if there is one */ if ( ci->nickname != NULL ) tmpname = g_strdup( ci->nickname ); else tmpname = g_strdup( ci->contactname ); gtk_tree_store_set( GTK_TREE_STORE( treestore ), &toplevel, COL_NAME, tmpname, COL_ONLINE_STATUS, ci->connected, // haven't checked yet, dedfault to off COL_VIDEO, ci->videocapable, COL_AUDIO, ci->audiocapable, COL_FILE, ci->fileserver, -1 ); } void insert_treestore_contactinfo ( contact_info *ci, GtkTreeIter iter) /* this will append one contact_info entry to the treelist (well, the model, actually */ { extern gui_status * currentstatus; GtkTreeView *gtkt; GtkTreeStore *treestore; gchar *tmpname; gtkt = currentstatus->Tree; treestore = GTK_TREE_STORE( gtk_tree_view_get_model( gtkt ) ); gtk_tree_store_insert_before( GTK_TREE_STORE( treestore ), &iter, NULL, NULL ); /* prefer the nickname, if there is one */ if ( ci->nickname != NULL ) tmpname = g_strdup( ci->nickname ); else tmpname = g_strdup( ci->contactname ); gtk_tree_store_set( GTK_TREE_STORE( treestore ), &iter, COL_NAME, tmpname, COL_ONLINE_STATUS, ci->connected, // haven't checked yet, dedfault to off COL_VIDEO, ci->videocapable, COL_AUDIO, ci->audiocapable, COL_FILE, ci->fileserver, -1 ); } gchar *get_treeview_selection_name ( void ) { extern gui_status * currentstatus; GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; gchar *name = NULL; selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW( currentstatus->Tree ) ); if ( gtk_tree_selection_get_selected( selection, &model, &iter ) ) gtk_tree_model_get ( model, &iter, COL_NAME, &name, -1 ); return ( name ); } GtkTreeIter get_tree_iter_name ( gchar *name ) { extern gui_status * currentstatus; GtkTreeView *gtkt; GtkTreeIter iter; GtkTreeStore *treestore; gchar *tmpname; if ( name == NULL ) { iter.stamp = -1; return ( iter ); } gtkt = currentstatus->Tree; treestore = GTK_TREE_STORE( gtk_tree_view_get_model ( gtkt ) ); if ( ! gtk_tree_model_get_iter_first ( GTK_TREE_MODEL( treestore ), &iter ) ) { g_warning ( "cannot find first entry in the tree!\n" ); iter.stamp = -1; return ( iter ); } gtk_tree_model_get ( GTK_TREE_MODEL( treestore ), &iter, COL_NAME, &tmpname, -1 ); if ( g_ascii_strncasecmp ( tmpname, name, CUTLASS_NAME_LEN ) == 0 ) { g_free(tmpname); return ( iter ); } else while ( gtk_tree_model_iter_next ( GTK_TREE_MODEL( treestore ), &iter ) ) { gtk_tree_model_get ( GTK_TREE_MODEL( treestore ), &iter, COL_NAME, &tmpname, -1 ); if ( g_ascii_strncasecmp ( tmpname, name, CUTLASS_NAME_LEN ) == 0 ) { g_free(tmpname); return ( iter ); } } iter.stamp = -1; g_free(tmpname); return ( iter ); }; void set_treeview_online_name ( gchar *name ) { extern gui_status * currentstatus; GtkTreeStore *treestore; GtkTreeIter iter; if ( name == NULL ) return ; iter = get_tree_iter_name ( name ); if ( iter.stamp == -1 ) return ; treestore = GTK_TREE_STORE( gtk_tree_view_get_model ( currentstatus->Tree ) ); gtk_tree_store_set ( treestore, &iter, COL_ONLINE_STATUS, TRUE, -1 ); } void set_treeview_offline_name ( gchar *name ) { extern gui_status * currentstatus; GtkTreeStore *treestore; GtkTreeIter iter; if ( name == NULL ) return ; iter = get_tree_iter_name ( name ); if ( iter.stamp == -1 ) { g_print ( "couldn't find dude." ); return ; } treestore = GTK_TREE_STORE( gtk_tree_view_get_model ( currentstatus->Tree ) ); gtk_tree_store_set ( treestore, &iter, COL_ONLINE_STATUS, FALSE, -1 ); } void view_popup_menu ( GtkWidget *treeview, GdkEventButton *event, gpointer userdata ) { GtkWidget * menu, *menuitem1, *menuitem2, *menuitem3, *menuitem4, *menuitem5; menu = gtk_menu_new(); menuitem1 = gtk_menu_item_new_with_label( "Connect" ); menuitem2 = gtk_menu_item_new_with_label( "Disconnect" ); menuitem3 = gtk_menu_item_new_with_label( "Status" ); menuitem4 = gtk_menu_item_new_with_label( "Send File" ); menuitem5 = gtk_menu_item_new_with_label( "Start Audio" ); // g_signal_connect(menuitem, "activate", (GCallback) view_popup_menu_onDoSomething, treeview); // gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); g_signal_connect( menuitem1, "activate", ( GCallback ) on_mainwin_connect_button_clicked, treeview ); // same as the connect button g_signal_connect( menuitem2, "activate", ( GCallback ) disconnect_user, treeview ); g_signal_connect( menuitem3, "activate", ( GCallback ) connection_status_window, treeview ); g_signal_connect( menuitem4, "activate", ( GCallback ) popup_send_file, treeview ); g_signal_connect( menuitem5, "activate", ( GCallback ) popup_start_audio, treeview ); gtk_menu_shell_append ( GTK_MENU_SHELL( menu ), menuitem1 ); gtk_menu_shell_append ( GTK_MENU_SHELL( menu ), menuitem2 ); gtk_menu_shell_append ( GTK_MENU_SHELL( menu ), menuitem4 ); gtk_menu_shell_append ( GTK_MENU_SHELL( menu ), menuitem3 ); gtk_menu_shell_append ( GTK_MENU_SHELL( menu ), menuitem5 ); gtk_widget_show_all( menu ); /* Note: event can be NULL here when called from view_onPopupMenu; * * gdk_event_get_time() accepts a NULL argument */ gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL, ( event != NULL ) ? event->button : 0, gdk_event_get_time( ( GdkEvent* ) event ) ); } gboolean on_peepstreeview_button_press_event ( GtkWidget *widget, GdkEventButton *event, gpointer user_data ) { // ok. This handler will be called whenever this widget recieves *any* button event // so, I will bail unless this is a right button event. if ( ! ( event->type == GDK_BUTTON_PRESS && event->button == 3 ) ) return ( FALSE ); view_popup_menu( widget, event, user_data ); return ( TRUE ); } gboolean on_peepstreeview_popup_menu ( GtkWidget *widget, gpointer user_data ) { g_print ( "on_peepstreeview_popup_menu: called\n" ); view_popup_menu ( widget, NULL, user_data ); return ( TRUE ); }