/******************************************************************** Copyright (C) 2000 Bassoukos Tassos This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MALLOC_H #include #endif #include #include #include #include #include "bookmarks.h" #include "tasks.h" #include "threads.h" #include "network.h" #include "hotline.h" #include "guiprefs.h" #include "connection.h" #include "main.h" #include "guiutils.h" #include "smalltrans.h" #include "pixmap.h" #include "tasklist.h" typedef struct _Server { int num,users,port; char *host; char *name; char *description; NetAddr na; } Server; typedef struct { int number_read,number_total; Thread thread; char *tracker; Task *task; NetAddr na; FILE *fd; } TrackerConn; static GStaticMutex trackers_mutex=G_STATIC_MUTEX_INIT; static Server *Servers=NULL,*selserver=NULL; static int numservers=0,allocservers=0; static int sortbycolumn=1; static char **sortptr=NULL; static Tracker *lasttracker=NULL; static GtkWidget *tracker_window=NULL; static GtkWidget *tracker_list=NULL; static GtkWidget *server_list=NULL; static GtkWidget *counter_label=NULL; static void tracker_select_changed(void); static void server_select_changed(void); static void populate_trackers(void); static void show_servers(void); static void start_tracker(Tracker *t); static void start_reading_trackers(void); static void clear_servers(){ int i; g_static_mutex_lock(&trackers_mutex); for(i=0;iusers - (*(Server **)a)->users; } static int sortstring(const void *a,const void *b){ if(sortbycolumn==1 || sortbycolumn==-1) return strcmp((*(Server **)a)->name,(*(Server **)b)->name); else return strcmp((*(Server **)a)->description,(*(Server **)b)->description); } static int sortip(const void *a,const void *b){ guint32 ia; guint32 ib; ib=ntohl((*(Server **)b)->na.s_addr); ia=ntohl((*(Server **)a)->na.s_addr); if(ia>ib) return 1; if(iavalue; if(numservers>0) s=malloc(sizeof(Server *)*numservers); if(sortptr!=NULL && sortptr[0]!=NULL){ j=0; for(i=0;iusers); strptr[0]=s[i]->name; strptr[3]=s[i]->description; strptr[1]=inet_ntoa(s[i]->na); if(sortbycolumn<0) k=gtk_clist_prepend(GTK_CLIST(server_list),strptr); else k=gtk_clist_append(GTK_CLIST(server_list),strptr); gtk_clist_set_row_data(GTK_CLIST(server_list),k,s[i]); } sprintf(buf,_("%d/%d Servers listed."),num,numservers); gtk_label_set_text(GTK_LABEL(counter_label),buf); gtk_adjustment_set_value(a,pos); gtk_clist_thaw(GTK_CLIST(server_list)); if(s!=NULL) free(s); server_select_changed(); g_static_mutex_unlock(&trackers_mutex); } static GStaticMutex transport_mutex=G_STATIC_MUTEX_INIT; static GList *inter_list=NULL; static gboolean update_serverlist_timeout(gpointer dummy){ gboolean show=FALSE; GList *gl=NULL; Server *s; gboolean needs_alloc=FALSE; int new_size=0,i; g_static_mutex_lock(&trackers_mutex); g_static_mutex_lock(&transport_mutex); if(inter_list!=NULL){ show=TRUE; gl=inter_list; inter_list=NULL; } g_static_mutex_unlock(&transport_mutex); while(gl!=NULL && gl->data!=NULL){ s=(Server *)gl->data; gl=g_list_remove(gl,s); for(i=0;iport) && strcmp(s->host,Servers[i].host)==0){ free(s->host); free(s->name); free(s->description); free(s); s=NULL; break; } } if(s!=NULL){ if(allocservers==0){ needs_alloc=TRUE; new_size=1500; } else if(numservers==allocservers){ needs_alloc=TRUE; new_size=allocservers*2+1; } if(needs_alloc==TRUE){ Servers=realloc(Servers,new_size*sizeof(Server)); allocservers=new_size; needs_alloc=FALSE; } Servers[numservers++]=*s; free(s); } } g_static_mutex_unlock(&trackers_mutex); if(show==TRUE) show_servers(); return FALSE; } static void add_server(TrackerServer *t,char *name,char *description){ struct in_addr sina; Server *s; gboolean needs_update; sina.s_addr=t->server_ip; s=calloc(sizeof(Server),1); s->num=0; s->users=t->server_usercount; s->port=t->server_port; s->host=strdup(inet_ntoa(sina)); s->name=name; s->description=description; s->na=sina; g_static_mutex_lock(&transport_mutex); needs_update=(inter_list==NULL)?TRUE:FALSE; inter_list=g_list_prepend(inter_list,s); g_static_mutex_unlock(&transport_mutex); if(needs_update){ g_timeout_add_full(G_PRIORITY_LOW, 100, update_serverlist_timeout, NULL,NULL); } } static void servers_change_order(GtkCList *clist, gint column, gpointer user_data){ column++; if(column==abs(sortbycolumn)) sortbycolumn*=-1; else sortbycolumn=column; show_servers(); } static void servers_change_text(GtkEditable *e, gpointer user_data){ char *str; if(sortptr!=NULL) g_strfreev(sortptr); str=gtk_editable_get_chars(e,0,-1); if(strlen(str)==0){ free(str); sortptr=NULL; } else { sortptr=g_strsplit(str," ",0); if(sortptr!=NULL && sortptr[0]==NULL){ g_strfreev(sortptr); sortptr=NULL; } } show_servers(); } static Bookmark *server_to_bookmark(Server* s){ Bookmark *b; if(s==NULL) return NULL; b=calloc(sizeof(Bookmark),1); b->login=strdup(""); b->passwd=strdup(""); b->host=strdup(s->host); b->name=strdup(s->name); b->port=s->port; return b; } static void server_bookmark_this(GtkButton *widget,gpointer dummy){ Bookmark *b,*c; b=server_to_bookmark(selserver); c=bookmark_dialog(b,_("Add Bookmark..."),tracker_window); if(c==NULL){ free_bookmark(b); return; } add_bookmark(b); } static gboolean tracked_server_connect_to(gpointer open_window){ Bookmark *b,*c; if(selserver==NULL) return FALSE; c=b=server_to_bookmark(selserver); if(open_window!=NULL || prefs_dblclick_connect_query_bookmarks==TRUE) c=bookmark_dialog(b,_("Connect to..."),tracker_window); if(c!=NULL) connection_new_to(b); free_bookmark(b); return FALSE; } static void server_connect_query(GtkButton *b,gpointer data){ tracked_server_connect_to(server_connect_query); } static void handle_server_dblclick(GtkWidget *w,gint row,gpointer data){ if(row==-1 || selserver==NULL) return; if(prefs_dblclick_connect_query_trackers==FALSE) tracked_server_connect_to(NULL); else server_connect_query(NULL,NULL); } static void server_list_selected(GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer user_data){ if(row==-1 || column==-1) return; selserver=gtk_clist_get_row_data(GTK_CLIST(server_list),row); server_select_changed(); } static void server_list_unselected(GtkCList *clist, gint row, gint column, GdkEventButton *event, gpointer user_data){ if(row==-1 || column==-1) return; selserver=NULL; server_select_changed(); } static gint close_tracker_window(GtkWidget *widget, GdkEvent *event, gpointer cbd){ GList *gl; g_static_mutex_lock(&trackers_mutex); for(gl=Trackers;gl!=NULL;gl=gl->next) ((Tracker *)(gl->data))->selected=FALSE; g_static_mutex_unlock(&trackers_mutex); if(tracker_window!=NULL) gtk_widget_destroy(tracker_window); tracker_window=NULL; return FALSE; } static void stracker_delete(GtkWidget *widget, GdkEvent *event, gpointer cbd){ if(lasttracker==NULL || tracker_window==NULL) return; { GtkWidget *dialog_window,*label; int button; char buf[512]; dialog_window=gnome_dialog_new(_("Delete Tracker?"), GNOME_STOCK_BUTTON_YES,GNOME_STOCK_BUTTON_NO, NULL); sprintf(buf,_("Really Delete Tracker?\n\n%s"),lasttracker->host); label=gtk_label_new(&buf[0]); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog_window)->vbox), label,TRUE,TRUE,0); gnome_dialog_set_parent(GNOME_DIALOG(dialog_window), GTK_WINDOW(tracker_window)); gtk_widget_show_all(dialog_window); button=gnome_dialog_run_and_close(GNOME_DIALOG(dialog_window)); if(button!=0) return; } g_static_mutex_lock(&trackers_mutex); Trackers=g_list_remove(Trackers,lasttracker); free(lasttracker->host); free(lasttracker->name); free(lasttracker); lasttracker=NULL; write_bookmarks(); populate_trackers(); g_static_mutex_unlock(&trackers_mutex); } static void stracker_new(GtkWidget *widget, GdkEvent *event, gpointer cbd){ GtkWidget *dialog_window,*label; GtkWidget *entry,*hbox; int button; char *s; Tracker *t; if(tracker_window==NULL) return; dialog_window=gnome_dialog_new(_("New Tracker"), GNOME_STOCK_BUTTON_CANCEL, GNOME_STOCK_BUTTON_OK, NULL); hbox=gtk_hbox_new(FALSE,2); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog_window)->vbox), hbox,TRUE,TRUE,0); label=gtk_label_new(_("Tracker host:")); gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); entry=gtk_entry_new(); gtk_box_pack_end(GTK_BOX(hbox),entry,FALSE,FALSE,0); gnome_dialog_editable_enters(GNOME_DIALOG(dialog_window), GTK_EDITABLE(entry)); gnome_dialog_set_parent(GNOME_DIALOG(dialog_window), GTK_WINDOW(tracker_window)); gtk_widget_show_all(dialog_window); button=gnome_dialog_run(GNOME_DIALOG(dialog_window)); if(button!=1) { if(button!=-1) gtk_widget_destroy(dialog_window); return; } s=strdup(gtk_entry_get_text(GTK_ENTRY(entry))); t=malloc(sizeof(Tracker)); t->host=s;t->name=strdup(s); t->port=0;t->selected=FALSE; g_static_mutex_lock(&trackers_mutex); Trackers=g_list_append(Trackers,t); gtk_widget_destroy(dialog_window); write_bookmarks(); populate_trackers(); g_static_mutex_unlock(&trackers_mutex); } static void check_tracker_dblclick(GtkWidget *w,gint row,gpointer data){ Tracker *t; if(row==-1) return; t=g_list_nth(Trackers,row)->data; if(t!=NULL) start_tracker(t); } static void stracker_selected(GtkWidget *widget,gint row, gint column, GdkEventButton *event, gpointer data) { Tracker *t; if(row==-1||column==-1) return; g_static_mutex_lock(&trackers_mutex); t=(Tracker*)gtk_clist_get_row_data(GTK_CLIST(widget),row); t->selected=TRUE; tracker_select_changed(); g_static_mutex_unlock(&trackers_mutex); } static void stracker_deselected(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { Tracker *t; if(row==-1||column==-1) return; g_static_mutex_lock(&trackers_mutex); t=(Tracker*)gtk_clist_get_row_data(GTK_CLIST(widget),row); t->selected=FALSE; tracker_select_changed(); g_static_mutex_unlock(&trackers_mutex); } static void stracker_select_all(GtkWidget *widget, GdkEventButton *event, gpointer data) { GList *gl; g_static_mutex_lock(&trackers_mutex); for(gl=Trackers;gl!=NULL;gl=gl->next) ((Tracker *)(gl->data))->selected=TRUE; gtk_clist_select_all(GTK_CLIST(tracker_list)); tracker_select_changed(); g_static_mutex_unlock(&trackers_mutex); start_reading_trackers(); } static void stracker_select_none(GtkWidget *widget, GdkEventButton *event, gpointer data) { GList *gl; g_static_mutex_lock(&trackers_mutex); for(gl=Trackers;gl!=NULL;gl=gl->next) ((Tracker *)(gl->data))->selected=FALSE; gtk_clist_unselect_all(GTK_CLIST(tracker_list)); tracker_select_changed(); g_static_mutex_unlock(&trackers_mutex); } static gboolean tracker_download_close_real(gpointer data){ TrackerConn *tc=(TrackerConn *)data; Tracker *t; GList *gl; g_static_mutex_lock(&trackers_mutex); for(gl=Trackers;gl!=NULL;gl=gl->next){ t=(Tracker *)gl->data; if(strcmp(t->name,tc->tracker)==0){ t->running=FALSE; break; } } g_static_mutex_unlock(&trackers_mutex); free(tc->tracker); if(tc->fd!=NULL) fclose(tc->fd); if(tc->task) task_async_destroy(tc->task); free(tc); return FALSE; } static void tracker_download_close(gpointer data){ gtk_idle_add(tracker_download_close_real,data); } static void tracker_user_close(Task *t,TrackerConn *tc){ killThread(tc->thread); } static gboolean tracker_read_update(TrackerConn *tc,TrackerUpdate *tu){ if(fread(tu,sizeof(*tu),1,tc->fd)!=1) return FALSE; tu->version=GINT16_FROM_BE(tu->version); tu->total_users=GINT16_FROM_BE(tu->total_users); tu->server_count=GINT16_FROM_BE(tu->server_count); tu->pad=GINT16_FROM_BE(tu->pad); return TRUE; } static void tracker_task_update(Task *task,TrackerConn *tc){ if(tc->number_total==0){ task_set_printf(task,-1.0,_("Connecting to %s..."),tc->tracker); } else { task_set_printf(task,(float)tc->number_read/(float)tc->number_total, _("Received %d/%d servers from %s..."), tc->number_read,tc->number_total,tc->tracker); } } static void tracker_thread(gpointer data){ TrackerConn *tc=(TrackerConn *)data; TrackerUpdate tu; TrackerServer t; char buf[256],*name,*description; int i; guint32 a,b; guint8 len; if(tc->na.s_addr==0){ if(resolveHost(&tc->na,tc->tracker)==FALSE){ show_error_errno(NULL,tracker_window,_("No IP for name %s:"),tc->tracker); return; } } if(tc->task) task_async_request_update(tc->task); tc->fd=getSocketTo(&tc->na,HL_TRACKER_PORT); if(tc->fd==NULL){ show_error_errno(NULL,tracker_window,_("Could not connect to %s:"),tc->tracker); return; } fwrite("HTRK\000\001",6,1,tc->fd); fflush(tc->fd); buf[5]=0; if(fread(buf,6,1,tc->fd)!=1 || strncmp(buf,HL_TRACKER_STRING,4)!=0 || tracker_read_update(tc,&tu)==FALSE){ show_error_errno(NULL,tracker_window,_("%s is not a Hotline Tracker!"),tc->tracker); return; } tc->number_read=0; tc->number_total=tu.server_count; for(i=0;inumber_total;i++){ if(fread(&a,4,1,tc->fd)!=1) break; b=a; a=GUINT32_FROM_BE(a); // printf("%x\n",a); if((a>>24)==0) { fread(buf,2*sizeof(guint16),1,tc->fd); continue; } t.server_ip=b; if(fread(&t.server_port,sizeof(guint16),1,tc->fd)!=1) break; t.server_port=GUINT16_FROM_BE(t.server_port); if(fread(&t.server_usercount,sizeof(guint16),1,tc->fd)!=1) break; t.server_usercount=GUINT16_FROM_BE(t.server_usercount); if(fread(&t.pad,sizeof(guint16),1,tc->fd)!=1) break; if(fread(&len,sizeof(len),1,tc->fd)!=1) break; if(len>0 && fread(buf,len,1,tc->fd)!=1) break; buf[len]=0; name=strdup(buf); if(fread(&len,sizeof(guint8),1,tc->fd)!=1 || (len>0 && fread(buf,len,1,tc->fd)!=1)){ free(name); break; } buf[len]=0; description=strdup(buf); add_server(&t,name,description); tc->number_read=i; if(tc->task) task_async_request_update(tc->task); } } static void start_reading_trackers(void){ Tracker *t; GList *gl; g_static_mutex_lock(&trackers_mutex); for(gl=Trackers;gl!=NULL;gl=gl->next){ t=(Tracker *)gl->data; if(t->selected==TRUE) start_tracker(t); } g_static_mutex_unlock(&trackers_mutex); } static void start_tracker(Tracker *t){ TrackerConn *tc; NetAddr na; if(t->running==FALSE){ t->running=TRUE; tc=(TrackerConn *)calloc(sizeof(TrackerConn),1); tc->number_read=0; tc->number_total=0; tc->tracker=strdup(t->host); tc->task=task_new("Trackers",HL_STOCK_PIXMAP_TRACKERS); gtk_signal_connect(GTK_OBJECT(tc->task),"cancelled",GTK_SIGNAL_FUNC(tracker_user_close),tc); gtk_signal_connect(GTK_OBJECT(tc->task),"updated",GTK_SIGNAL_FUNC(tracker_task_update),tc); tc->fd=NULL; if(isIP(&tc->na,t->host)==TRUE){ task_set_printf(tc->task,-1.0,_("Connecting to %s..."),inet_ntoa(na)); tc->na.s_addr=0; } else { task_set_printf(tc->task,-1.0,_("Resolving %s..."),tc->tracker); } newThread(&tc->thread,tracker_thread,tracker_download_close, (gpointer)tc); } } static void tp_close(GtkWidget *w, gpointer *dummy){ gtk_widget_destroy(GTK_WIDGET(dummy)); } static void tracker_properties(GtkWidget *w, gpointer *dummy){ GtkWidget *d,*table,*label,*text; char buf[256]; if(selserver==NULL) return; d=gnome_dialog_new(_("Server Properties"),GNOME_STOCK_BUTTON_CLOSE,NULL); gnome_dialog_set_parent(GNOME_DIALOG(d), GTK_WINDOW(tracker_window)); gnome_dialog_button_connect(GNOME_DIALOG(d),0, GTK_SIGNAL_FUNC(tp_close), (gpointer)d); gtk_signal_connect_object_while_alive(GTK_OBJECT(tracker_window),"destroy", GTK_SIGNAL_FUNC(gtk_object_destroy),GTK_OBJECT(d)); table=gtk_table_new(5,2,FALSE); label=gtk_label_new(_("Server Name: ")); gtk_misc_set_alignment(GTK_MISC(label),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,0,1); label=gtk_label_new(_("Host: ")); gtk_misc_set_alignment(GTK_MISC(label),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,1,2); label=gtk_label_new(_("Port: ")); gtk_misc_set_alignment(GTK_MISC(label),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,2,3); label=gtk_label_new(_("Users: ")); gtk_misc_set_alignment(GTK_MISC(label),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,3,4); label=gtk_label_new(_("Description: ")); gtk_misc_set_alignment(GTK_MISC(label),1.0,0.0); gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,4,5); text=gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(text),selserver->name); gtk_table_attach_defaults(GTK_TABLE(table),text,1,2,0,1); text=gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(text),selserver->host); gtk_table_attach_defaults(GTK_TABLE(table),text,1,2,1,2); sprintf(buf,"%d",selserver->port); label=gtk_label_new(buf); gtk_misc_set_alignment(GTK_MISC(label),0.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,2,3); sprintf(buf,"%d",selserver->users); label=gtk_label_new(buf); gtk_misc_set_alignment(GTK_MISC(label),0.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,3,4); text=gtk_text_new(NULL,NULL); gtk_text_insert(GTK_TEXT(text),NULL,NULL,NULL,selserver->description,-1); gtk_text_set_editable(GTK_TEXT(text),FALSE); gtk_text_set_word_wrap(GTK_TEXT(text),TRUE); gtk_table_attach_defaults(GTK_TABLE(table),text,1,2,4,5); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(d)->vbox),table,TRUE,TRUE,0); gtk_widget_show_all(d); } static GnomeUIInfo file_menu[]={ HOTLINE_UIITEM_STOCK(N_("_New Tracker"),N_("Add a Tracker"), stracker_new,HL_MENU HL_STOCK_PIXMAP_TRACKERS, 'N',GDK_CONTROL_MASK), HOTLINE_UIITEM_STOCK(N_("Scan all"),N_("Scan all trackers"), stracker_select_all,HL_MENU HL_STOCK_PIXMAP_TRACKERS, 'A',GDK_CONTROL_MASK), GNOMEUIINFO_SEPARATOR, HOTLINE_UIITEM_STOCK(N_("_Close"),N_("Close tracker window"), close_tracker_window,HL_MENU HL_STOCK_PIXMAP_CLOSE, 'Q',GDK_CONTROL_MASK), GNOMEUIINFO_END }; static GnomeUIInfo menubar[]={ GNOMEUIINFO_MENU_FILE_TREE(file_menu), GNOMEUIINFO_END }; static GnomeUIInfo menu_servers[]={ GNOMEUIINFO_ITEM_STOCK(N_("Connect..."),N_("Connect to this Hotline Server"), server_connect_query, HL_MENU HL_STOCK_PIXMAP_CONNECT), GNOMEUIINFO_ITEM_STOCK(N_("Properties..."),N_("Info on this Hotline Server"), tracker_properties, HL_MENU HL_STOCK_PIXMAP_INFO), GNOMEUIINFO_ITEM_STOCK(N_("Bookmark..."), N_("Add this Hotline Server to your Bookmarks"), server_bookmark_this, HL_MENU HL_STOCK_PIXMAP_NEW_BOOKMARK), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_STOCK("Clear servers",N_("Clear server list"), clear_servers, GNOME_STOCK_PIXMAP_CLEAR), GNOMEUIINFO_END }; static GnomeUIInfo trackers_menu[] = { GNOMEUIINFO_ITEM_STOCK(N_("New..."),N_("Add a Tracker"), stracker_new, HL_MENU HL_STOCK_PIXMAP_TRACKERS), GNOMEUIINFO_ITEM_STOCK(N_("Refresh"),N_("Reload bookmarks from disk"), init_bookmarks, HL_MENU HL_STOCK_PIXMAP_REFRESH), GNOMEUIINFO_ITEM_STOCK(N_("Delete"),N_("Remove this tracker"), stracker_delete, HL_MENU HL_STOCK_PIXMAP_DELETE), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_NONE(N_("Scan all"),N_("Scan all trackers"), stracker_select_all), GNOMEUIINFO_ITEM_NONE(N_("Unselect All"),N_("Unselect all trackers"), stracker_select_none), GNOMEUIINFO_ITEM_NONE(N_("Scan"),N_("Start scanning trackers"), start_reading_trackers), GNOMEUIINFO_END }; static void tracker_select_changed(){ Tracker *t; GList *gl; gboolean all_selected=TRUE; gboolean any_selected=FALSE; gboolean one_selected=FALSE; for(gl=Trackers;gl!=NULL;gl=gl->next){ t=(Tracker *)gl->data; if(t->selected==TRUE){ if(any_selected==FALSE){ one_selected=TRUE; lasttracker=t; } else { one_selected=FALSE; lasttracker=NULL; } any_selected=TRUE; } else { all_selected=FALSE; } } clist_popup_set_sensitive(tracker_list,2,one_selected); clist_popup_set_sensitive(tracker_list,4,all_selected?FALSE:TRUE); clist_popup_set_sensitive(tracker_list,5,any_selected); clist_popup_set_sensitive(tracker_list,6,any_selected); } static void server_select_changed(){ clist_popup_set_sensitive(server_list,3,numservers==0?FALSE:TRUE); clist_popup_set_sensitive(server_list,0,selserver==NULL?FALSE:TRUE); clist_popup_set_sensitive(server_list,1,selserver==NULL?FALSE:TRUE); } static void populate_trackers() { Tracker *t; GList *gl; char *ptr[1]; gint i; if(tracker_window==NULL) return; gtk_clist_freeze(GTK_CLIST(tracker_list)); gtk_clist_clear(GTK_CLIST(tracker_list)); for(gl=Trackers;gl!=NULL;gl=gl->next){ t=(Tracker *)gl->data; ptr[0]=t->name; t->selected=FALSE; i=gtk_clist_append(GTK_CLIST(tracker_list),(gchar **)ptr); gtk_clist_set_row_data(GTK_CLIST(tracker_list),i,(gpointer)t); } gtk_clist_thaw(GTK_CLIST(tracker_list)); tracker_select_changed(); server_select_changed(); } void new_trackers(){ populate_trackers(); } static gchar *tracker_names[]={N_("Tracker"),NULL}; void show_trackers(){ GtkWidget *tmp,*hbox,*vbox,*tmp2; static gchar *list_names[]={ N_("Name"), N_("Host"), N_("Users"), N_("Description")}; if(tracker_window!=NULL){ guiutils_raise_window(GTK_WINDOW(tracker_window)); return; } tracker_window=gnome_app_new(PACKAGE "/Trackers",_("Trackers")); gtk_signal_connect (GTK_OBJECT(tracker_window),"delete_event", GTK_SIGNAL_FUNC(close_tracker_window), NULL); gnome_app_create_menus(GNOME_APP(tracker_window),menubar); hbox=gtk_hpaned_new(); gnome_app_set_contents(GNOME_APP(tracker_window),hbox); tracker_list=gtk_clist_new_with_titles(1,tracker_names); gtk_clist_column_titles_passive(GTK_CLIST(tracker_list)); tmp2=gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tmp2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(tmp2),tracker_list); gtk_paned_add1(GTK_PANED(hbox),tmp2); gtk_clist_set_column_width(GTK_CLIST(tracker_list),0,90); gtk_clist_set_selection_mode(GTK_CLIST(tracker_list),GTK_SELECTION_MULTIPLE); vbox=gtk_vbox_new(FALSE,2); gtk_paned_add2(GTK_PANED(hbox),vbox); tmp=gtk_hbox_new(FALSE,1); gtk_box_pack_start(GTK_BOX(vbox),tmp,FALSE,FALSE,0); gtk_box_pack_start(GTK_BOX(tmp),counter_label=gtk_label_new(""),TRUE,TRUE,0); gtk_box_pack_start(GTK_BOX(tmp),gtk_label_new(_("Search for:")), FALSE,FALSE,0); tmp2=gtk_entry_new(); gtk_signal_connect(GTK_OBJECT(tmp2), "changed", GTK_SIGNAL_FUNC(servers_change_text), NULL); gtk_box_pack_start(GTK_BOX(tmp),tmp2,FALSE,FALSE,0); tmp2=gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tmp2), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); server_list=gtk_clist_new_with_titles(4,list_names); gtk_container_add(GTK_CONTAINER(tmp2),server_list); gtk_box_pack_end(GTK_BOX(vbox),tmp2,TRUE,TRUE,0); guiprefs_add_clist(GTK_CLIST(server_list),"Trackers/Window/List","90,0,0,0"); gtk_clist_set_selection_mode(GTK_CLIST(server_list),GTK_SELECTION_SINGLE); gtk_signal_connect(GTK_OBJECT(tracker_list), "select_row", GTK_SIGNAL_FUNC(stracker_selected), NULL); gtk_signal_connect(GTK_OBJECT(tracker_list), "unselect_row", GTK_SIGNAL_FUNC(stracker_deselected), NULL); gtk_signal_connect(GTK_OBJECT(server_list), "click-column", GTK_SIGNAL_FUNC(servers_change_order), NULL); gtk_signal_connect(GTK_OBJECT(server_list), "select_row", GTK_SIGNAL_FUNC(server_list_selected), NULL); gtk_signal_connect(GTK_OBJECT(server_list), "unselect_row", GTK_SIGNAL_FUNC(server_list_unselected), NULL); gutils_clist_add_popup_menu(server_list,menu_servers,NULL); gutils_clist_add_popup_menu(tracker_list,trackers_menu,NULL); gutils_clist_on_dblclick(server_list,handle_server_dblclick,NULL); gutils_clist_on_dblclick(tracker_list,check_tracker_dblclick,NULL); guiprefs_add_window(GTK_WINDOW(tracker_window),"Trackers/Window/Size"); guiprefs_add_paned(GTK_PANED(hbox),"Trackers/Window/PanePos"); gtk_widget_show_all(tracker_window); register_window(tracker_window,_("_Trackers")); populate_trackers(); if(sortptr) { g_strfreev(sortptr); sortptr = NULL; } show_servers(); }