/******************************************************************** 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 #include #include #include /* XML headers */ #include #include #include "bookmarks.h" #include "hotline.h" #include "guiprefs.h" #include "connection.h" #include "main.h" #include "guiutils.h" #include "pixmap.h" #ifndef FXML2 #define FXML2 0 #if defined(LIBXML_VERSION) #if LIBXML_VERSION >= 20000 #undef FXML2 #define FXML2 1 #endif #endif #endif #ifndef xmlChildNode #if FXML2 #define xmlChildNode children #else #define xmlChildNode childs #endif #endif #ifndef xmlRootNode #if FXML2 #define xmlRootNode children #else #define xmlRootNode root #endif #endif static char *empty_bookmarks_ghx_xml= "" "<" PACKAGE " ver=\"1.0\">" "" "" "" "" "" "" ""; static char *empty_bookmarks_xml= "" "<" PACKAGE " ver=\"1.0\">" "" "" "" "" "" "" ""; static GList *Bookmarks=NULL; static xmlDocPtr Bookmark_tree=NULL; static xmlNodePtr Bookmarks_ptr=NULL; static xmlNodePtr selected_node=NULL; static xmlNodePtr selected_folder=NULL; GList *Trackers=NULL; static GtkWidget *bookmark_window=NULL; static GtkWidget *bookmark_list=NULL; static void populate_bklist(void); static void refresh_callback(GtkWidget *widget, GdkEventButton *event, gpointer data); static gint highlight_toolbar(gpointer dummy); void free_bookmark(Bookmark *bm){ if(bm==NULL) return; Bookmarks=g_list_remove(Bookmarks,bm); free(bm->name); free(bm->host); free(bm->login); free(bm->passwd); free(bm); } static void clear_trackers(void){ Tracker *t; /* FIXME: will crash when downloading and clearing */ while(Trackers!=NULL && Trackers->data!=NULL){ t=(Tracker *)Trackers->data; Trackers=g_list_remove(Trackers,t); if(t->name) free(t->name); if(t->host) free(t->host); free(t); } Trackers=NULL; } static void clear_bookmarks(void){ clear_trackers(); while(Bookmarks!=NULL && Bookmarks->data!=NULL) free_bookmark((Bookmark *)Bookmarks->data); Bookmarks=NULL; if(Bookmark_tree!=NULL){ xmlFreeDoc(Bookmark_tree); Bookmark_tree=NULL; } Bookmarks_ptr=NULL; selected_node=NULL; selected_folder=NULL; } Bookmark *dup_bookmark(Bookmark *bm){ Bookmark *b; if(bm==NULL) return NULL; b=malloc(sizeof(Bookmark)); b->port=bm->port; b->name=strdup(bm->name); b->host=strdup(bm->host); b->login=strdup(bm->login); b->passwd=strdup(bm->passwd); return b; } static void splitupbookmarks(char **splitar,int size,char *string){ int i=0; char *s; for(i=0;ihost=strdup(splits[1]); t->name=strdup(splits[0]); t->selected=FALSE; t->running=FALSE; gl=g_list_prepend(gl,t); } else if(buf[0]=='S' && trackers==FALSE){ splitupbookmarks(splits,5,buf+2); b=malloc(sizeof(Bookmark)); b->name=strdup(splits[0]); b->host=strdup(splits[1]); b->login=strdup(splits[3]); b->passwd=strdup(splits[4]); b->port=atoi(splits[2]); if(b->port==0) b->port=HL_PORT; gl=g_list_prepend(gl,b); } } fclose(bookfile); gl=g_list_reverse(gl); return gl; } static xmlDocPtr init_self_bookmarks(void){ xmlDocPtr doc=NULL; char *f=file_bookmarks_what(PACKAGE); doc=xmlParseFile(f); free(f); if(doc==NULL){ /* Does user have bookmarks? */ doc=xmlParseFile(DATADIR "/fidelio.default"); if (doc==NULL) { FILE *b=open_bookmarks_what("ghx","r"); if(b==NULL) doc=xmlParseDoc(empty_bookmarks_xml); else { fclose(b); doc=xmlParseDoc(empty_bookmarks_ghx_xml); } } } return doc; } static void make_xml_trackers(xmlNodePtr p){ xmlNodePtr t; Tracker *tr; for(t=p->xmlChildrenNode;t!=NULL;t=t->next){ if(!strcmp(t->name,"t")){ tr=malloc(sizeof(Tracker)); tr->host=xmlGetProp(t,"host"); tr->name=xmlGetProp(t,"name"); tr->selected=FALSE; tr->running=FALSE; Trackers=g_list_prepend(Trackers,tr); } } Trackers=g_list_reverse(Trackers); } static xmlNodePtr bookmark_to_xml(Bookmark *bm,xmlNodePtr n){ char buf[16]; if(n==NULL) n=xmlNewDocNode(Bookmark_tree,NULL,"b",NULL); if(bm->name!=NULL && strlen(bm->name)>0) xmlSetProp(n,"name",bm->name); else xmlRemoveProp(xmlSetProp(n,"name",NULL)); if(bm->host!=NULL) xmlSetProp(n,"host",bm->host); else xmlRemoveProp(xmlSetProp(n,"host",NULL)); if(bm->login!=NULL && strlen(bm->login)>0) xmlSetProp(n,"login",bm->login); else xmlRemoveProp(xmlSetProp(n,"login",NULL)); if(bm->passwd!=NULL && strlen(bm->passwd)>0) xmlSetProp(n,"passwd",bm->passwd); else xmlRemoveProp(xmlSetProp(n,"passwd",NULL)); if(bm->port!=0 && bm->port!=HL_PORT){ sprintf(buf,"%d",bm->port); xmlSetProp(n,"port",buf); } else xmlRemoveProp(xmlSetProp(n,"port",NULL)); return n; } static Bookmark *xml_to_bookmark(xmlNodePtr p,Bookmark *bookmark){ char *s; if(bookmark==NULL){ bookmark=calloc(sizeof(Bookmark),1); } else { g_free(bookmark->name); g_free(bookmark->host); g_free(bookmark->login); g_free(bookmark->passwd); } s=xmlGetProp(p,"name"); bookmark->name=s!=NULL?s:strdup(""); s=xmlGetProp(p,"host"); bookmark->host=s!=NULL?s:strdup(""); s=xmlGetProp(p,"login"); bookmark->login=s!=NULL?s:strdup(""); s=xmlGetProp(p,"passwd"); bookmark->passwd=s!=NULL?s:strdup(""); s=xmlGetProp(p,"port"); bookmark->port= s ? atoi(s) : HL_PORT; free(s); if(bookmark->port==0) bookmark->port=HL_PORT; return bookmark; } static void fxgb_helper(Bookmark *bm, xmlNodePtr b) { bookmark_to_xml(bm, xmlNewChild(b,NULL,"b",NULL)); } static void fixup_xml_ghx_bookmarks(xmlNodePtr p){ xmlNodePtr b; for(b=p->xmlChildrenNode;b!=NULL;b=b->next){ if(!strcmp(b->name,"f")){ if(xmlGetProp(b,"ghx")!=NULL){ xmlRemoveProp(xmlSetProp(b,"ghx",NULL)); if(b->xmlChildrenNode!=NULL){ xmlFreeNodeList(b->xmlChildrenNode); b->xmlChildrenNode=NULL; } g_list_foreach(Bookmarks, (GFunc) fxgb_helper, (gpointer)b); } else fixup_xml_ghx_bookmarks(b); } } } static void fixup_self_bookmarks(void){ xmlNodePtr p=NULL,f=NULL; char *c=NULL; for(p=xmlDocGetRootElement(Bookmark_tree);p!=NULL;p=p->next){ if(!strcmp(p->name,PACKAGE)){ f=p;break; } } c=xmlGetProp(f,"ver"); if(strcmp(c,"1.0")) f=NULL; free(c); if(f==NULL) return; for(p=f->xmlChildrenNode;p!=NULL;p=p->next){ if(p->type!=XML_ELEMENT_NODE) continue; if(!strcmp(p->name,"bookmarks")){ Bookmarks_ptr=p; fixup_xml_ghx_bookmarks(p); } else if(!strcmp(p->name,"trackers")) { if(xmlGetProp(p,"ghx")!=NULL) continue; clear_trackers(); make_xml_trackers(p); } } } void init_bookmarks(void) { xmlSubstituteEntitiesDefault(1); clear_bookmarks(); Bookmarks=get_ghx_bookmarks(FALSE); Trackers=get_ghx_bookmarks(TRUE); Bookmark_tree=init_self_bookmarks(); fixup_self_bookmarks(); new_trackers(); populate_bklist(); } void write_bookmarks() { xmlDocPtr doc; xmlNodePtr tree,subtree,*bookmarks,bt; GList *gl; FILE *f; doc=xmlNewDoc("1.0"); xmlDocSetRootElement(doc,xmlNewDocNode(doc,NULL,PACKAGE,NULL)); bt=xmlDocGetRootElement(doc); xmlSetProp(bt,"ver","1.0"); xmlAddChild(bt,xmlNewDocComment(doc," Automatically generated by " PACKAGE ". do not edit. ")); tree=xmlNewChild(bt,NULL,"bookmarks",NULL); bookmarks=&tree->xmlChildrenNode; *bookmarks=Bookmarks_ptr->xmlChildrenNode; tree=xmlNewChild(bt,NULL,"trackers",NULL); for(gl=Trackers;gl!=NULL;gl=gl->next){ subtree=xmlNewChild(tree,NULL,"t",NULL); xmlSetProp(subtree,"name",((Tracker *)gl->data)->name); xmlSetProp(subtree,"host",((Tracker *)gl->data)->host); } /* FIXME: what happens when you don't have enough free space ? you lose data ... */ f=open_bookmarks_what(PACKAGE,"w"); xmlDocDump(f,doc); fclose(f); *bookmarks=NULL; xmlFreeDoc(doc); } static xmlNodePtr bookmark_dialog_xml(xmlNodePtr bookmark, const char *name, GtkWidget *parent_window){ GtkWidget *dialog; GtkWidget *name_entry,*host_entry,*login_entry,*passwd_entry; GtkWidget *port_entry; GtkWidget *table,*tmp; gboolean has_bookmark=bookmark==NULL?FALSE:TRUE; int result; dialog=gnome_dialog_new(name,GNOME_STOCK_BUTTON_CANCEL, GNOME_STOCK_BUTTON_OK,NULL); if(parent_window!=NULL) gnome_dialog_set_parent(GNOME_DIALOG(dialog),GTK_WINDOW(parent_window)); else if(bookmark_window!=NULL) gnome_dialog_set_parent(GNOME_DIALOG(dialog),GTK_WINDOW(bookmark_window)); else if(main_app!=NULL) gnome_dialog_set_parent(GNOME_DIALOG(dialog),GTK_WINDOW(main_app)); table=gtk_table_new(2,5,FALSE); tmp=gtk_label_new(_("Name:")); gtk_misc_set_alignment(GTK_MISC(tmp),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),tmp,0,1,0,1); tmp=gtk_label_new(_("Host:")); gtk_misc_set_alignment(GTK_MISC(tmp),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),tmp,0,1,1,2); tmp=gtk_label_new(_("Port:")); gtk_misc_set_alignment(GTK_MISC(tmp),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),tmp,0,1,2,3); tmp=gtk_label_new(_("Login:")); gtk_misc_set_alignment(GTK_MISC(tmp),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),tmp,0,1,3,4); tmp=gtk_label_new(_("Passwd:")); gtk_misc_set_alignment(GTK_MISC(tmp),1.0,0.5); gtk_table_attach_defaults(GTK_TABLE(table),tmp,0,1,4,5); gtk_table_attach(GTK_TABLE(table),name_entry=gtk_entry_new(),1,2,0,1, GTK_EXPAND|GTK_FILL,0,0,0); gtk_table_attach(GTK_TABLE(table),host_entry=gtk_entry_new(),1,2,1,2, GTK_EXPAND|GTK_FILL,0,0,0); gtk_table_attach(GTK_TABLE(table),port_entry=gtk_entry_new(),1,2,2,3, GTK_EXPAND|GTK_FILL,0,0,0); gtk_table_attach(GTK_TABLE(table),login_entry=gtk_entry_new(),1,2,3,4, GTK_EXPAND|GTK_FILL,0,0,0); gtk_table_attach(GTK_TABLE(table),passwd_entry=gtk_entry_new(),1,2,4,5, GTK_EXPAND|GTK_FILL,0,0,0); if(passwords_are_hidden==TRUE) gtk_entry_set_visibility(GTK_ENTRY(passwd_entry),FALSE); if(bookmark){ char *s; if((s=xmlGetProp(bookmark,"name"))!=NULL) { gtk_entry_set_text(GTK_ENTRY(name_entry),s); free(s); } if((s=xmlGetProp(bookmark,"host"))!=NULL){ gtk_entry_set_text(GTK_ENTRY(host_entry),s); free(s); } if((s=xmlGetProp(bookmark,"port"))!=NULL){ gtk_entry_set_text(GTK_ENTRY(port_entry),s); free(s); } if((s=xmlGetProp(bookmark,"login"))!=NULL){ gtk_entry_set_text(GTK_ENTRY(login_entry),s); free(s); } if((s=xmlGetProp(bookmark,"passwd"))!=NULL){ gtk_entry_set_text(GTK_ENTRY(passwd_entry),s); free(s); } } gnome_dialog_editable_enters(GNOME_DIALOG(dialog),GTK_EDITABLE(name_entry)); gnome_dialog_editable_enters(GNOME_DIALOG(dialog),GTK_EDITABLE(host_entry)); gnome_dialog_editable_enters(GNOME_DIALOG(dialog),GTK_EDITABLE(port_entry)); gnome_dialog_editable_enters(GNOME_DIALOG(dialog),GTK_EDITABLE(login_entry)); gnome_dialog_editable_enters(GNOME_DIALOG(dialog),GTK_EDITABLE(passwd_entry)); gnome_dialog_close_hides(GNOME_DIALOG(dialog),TRUE); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), table,TRUE,TRUE,0); gtk_widget_show_all(dialog); result=gnome_dialog_run(GNOME_DIALOG(dialog)); if(result!=1){ /* cancel/close */ gtk_widget_destroy(dialog); return NULL; } if(has_bookmark==FALSE){ bookmark=xmlNewDocNode(Bookmark_tree,NULL,"b",NULL); } xmlSetProp(bookmark,"name",gtk_entry_get_text(GTK_ENTRY(name_entry))); xmlSetProp(bookmark,"host",gtk_entry_get_text(GTK_ENTRY(host_entry))); xmlSetProp(bookmark,"login",gtk_entry_get_text(GTK_ENTRY(login_entry))); xmlSetProp(bookmark,"passwd",gtk_entry_get_text(GTK_ENTRY(passwd_entry))); xmlSetProp(bookmark,"port",gtk_entry_get_text(GTK_ENTRY(port_entry))); gtk_widget_destroy(dialog); return bookmark; } Bookmark *bookmark_dialog(Bookmark *bookmark, const char *name, GtkWidget *parent_window){ xmlNodePtr n,b=(bookmark==NULL?NULL:bookmark_to_xml(bookmark,NULL)); n=bookmark_dialog_xml(b,name,parent_window); if(n!=NULL){ bookmark=xml_to_bookmark(n,bookmark); xmlFreeNode(n); return bookmark; } if(b!=NULL) xmlFreeNode(b); return NULL; } static void rename_folder(char *string,gpointer data){ xmlNodePtr n=data; if(string==NULL || n==NULL) return; xmlSetProp(n,"name",string); write_bookmarks(); populate_bklist(); } static void properties_callback(){ if(selected_node!=NULL){ if(bookmark_dialog_xml(selected_node,_("Bookmark Properties"),NULL)!=NULL){ write_bookmarks(); populate_bklist(); } } else if(selected_folder!=NULL){ GtkWidget *d; d=gnome_request_dialog(FALSE,_("New bookmark folder to create:"), xmlGetProp(selected_folder,"name"),0,rename_folder, selected_folder, (bookmark_window==NULL)?NULL: GTK_WINDOW(bookmark_window)); gtk_widget_show_all(d); gnome_dialog_run_and_close(GNOME_DIALOG(d)); } } void add_bookmark(Bookmark *bm){ xmlNodePtr n; if(bm==NULL) return; n=xmlNewChild(Bookmarks_ptr,NULL,"b",NULL); bookmark_to_xml(bm,n); free_bookmark(bm); write_bookmarks(); populate_bklist(); } static void new_bkmark_callback(){ Bookmark *bm=bookmark_dialog(NULL,_("Add Bookmark"),NULL); if(bm!=NULL) add_bookmark(bm); } static void add_new_folder(char *string,gpointer data){ xmlNodePtr n,p=data; if(string==NULL) return; n=xmlNewDocNode(Bookmark_tree,NULL,"f",NULL); if(p==NULL){ if(selected_node!=NULL) p=selected_node; else p=selected_folder; } xmlSetProp(n,"name",string); if(p!=NULL){ xmlAddPrevSibling(p,n); } else { xmlAddChild(Bookmarks_ptr,n); } write_bookmarks(); populate_bklist(); } static void new_folder_callback(){ GtkWidget *d; d=gnome_request_dialog(FALSE,_("New bookmark folder to create:"), _("New Folder"),0,add_new_folder, selected_node!=NULL?selected_node:selected_folder, (bookmark_window==NULL)?NULL: GTK_WINDOW(bookmark_window)); gtk_widget_ref(d); gtk_widget_show_all(d); gnome_dialog_run_and_close(GNOME_DIALOG(d)); } static void connect_as_callback(GtkButton *w,gpointer data){ Bookmark *bm,*bc; if(selected_node==NULL) return; bc=bm=xml_to_bookmark(selected_node,NULL); if(w!=NULL){ bc=bookmark_dialog(bm,_("Connect To..."),NULL); } if(bc!=NULL) connection_new_to(bm); free_bookmark(bm); } static void connect_callback(GtkButton *b,gpointer data){ connect_as_callback(NULL,NULL); } static void null_callback(gint res,gpointer data){} static void delete_bkmark_callback(){ GtkWidget *dialog; gint res; char buf[1024]; if(selected_node==NULL && selected_folder==NULL) return; sprintf(buf,_("Really delete this bookmark?\n\n\"%s\""), xmlGetProp(selected_node,"name")); dialog=gnome_ok_cancel_dialog_parented(buf,null_callback, NULL,GTK_WINDOW(bookmark_window)); gnome_dialog_set_close(GNOME_DIALOG(dialog),FALSE); res=gnome_dialog_run_and_close(GNOME_DIALOG(dialog)); if((selected_node==NULL && selected_folder==NULL)|| res!=0){ return; } xmlUnlinkNode(selected_node); xmlFreeNode(selected_node); selected_node=NULL; highlight_toolbar(NULL); write_bookmarks(); populate_bklist(); } static GnomeUIInfo toolbar[] = { GNOMEUIINFO_ITEM_STOCK(N_("New..."),N_("Create a new bookmark"), new_bkmark_callback, HL_STOCK_PIXMAP_NEW_BOOKMARK), GNOMEUIINFO_ITEM_STOCK(N_("Refresh"),N_("Reload bookmarks from disk"), refresh_callback, HL_STOCK_PIXMAP_REFRESH), GNOMEUIINFO_ITEM_STOCK(N_("Delete"),N_("Delete this bookmark"), delete_bkmark_callback, HL_STOCK_PIXMAP_DELETE), GNOMEUIINFO_ITEM_STOCK(N_("Properties..."),N_("Edit server's properties"), properties_callback, HL_STOCK_PIXMAP_PROP_BOOKMARK), GNOMEUIINFO_ITEM_STOCK(N_("Connect..."), N_("Connect to this Hotline Server, with different login / password"), connect_as_callback, HL_STOCK_PIXMAP_CONNECT), GNOMEUIINFO_END }; static gint highlight_toolbar(gpointer dummy){ gboolean t=(selected_node==NULL && selected_folder==NULL)?FALSE:TRUE; if(bookmark_window==NULL) return FALSE; gtk_widget_set_sensitive(toolbar[2].widget,t); gtk_widget_set_sensitive(toolbar[3].widget,t); gtk_widget_set_sensitive(toolbar[4].widget,selected_node==NULL?FALSE:TRUE); return FALSE; } static void handle_dblclick(GtkWidget *w,gint row,gpointer data){ if(row==-1) return; selected_node=gtk_ctree_node_get_row_data(GTK_CTREE(bookmark_list), gtk_ctree_node_nth(GTK_CTREE(bookmark_list),row)); if(selected_node==NULL || strcmp(selected_node->name,"b")) return; if(prefs_dblclick_connect_query_bookmarks==TRUE){ connect_as_callback((GtkButton *)w,NULL); } else { connect_callback(NULL,NULL); } } static void collapse_tree_callback(GtkCTree *tree,GtkCTreeNode *node,gpointer data){ xmlNodePtr n=gtk_ctree_node_get_row_data(tree,node); xmlRemoveProp(xmlSetProp(n,"expanded",NULL)); write_bookmarks(); } static void expand_tree_callback(GtkCTree *tree,GtkCTreeNode *node,gpointer data){ xmlNodePtr n=gtk_ctree_node_get_row_data(tree,node); xmlSetProp(n,"expanded","true"); write_bookmarks(); } static void select_row_callback(GtkCTree *tree,GtkCTreeNode *node,int col,gpointer data){ selected_node=gtk_ctree_node_get_row_data(tree,node); selected_folder=NULL; if(selected_node!=NULL && strcmp(selected_node->name,"b")){ selected_folder=selected_node; selected_node=NULL; } highlight_toolbar(NULL); } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { selected_node=NULL; selected_folder=NULL; highlight_toolbar(NULL); } static void bookmark_move_callback(GtkCTree *ctree, GtkCTreeNode *node, GtkCTreeNode *new_parent, GtkCTreeNode *new_sibling, gpointer user_data){ xmlNodePtr o,n; o=gtk_ctree_node_get_row_data(ctree,node); xmlUnlinkNode(o); if(new_sibling!=NULL){ n=gtk_ctree_node_get_row_data(ctree,new_sibling); xmlAddNextSibling(n,o); } else { if(new_parent!=NULL) n=gtk_ctree_node_get_row_data(ctree,new_parent); else n=Bookmarks_ptr; xmlAddChild(n,o); } write_bookmarks(); } static void refresh_callback(GtkWidget *widget, GdkEventButton *event, gpointer data){ init_bookmarks(); highlight_toolbar(NULL); } static gint close_bookmark_window(GtkWidget *widget,GdkEvent *event,gpointer cbd){ bookmark_window=NULL; return FALSE; } static void insert_bookmarks_at(GtkCTreeNode *parent,xmlNodePtr pn){ xmlNodePtr n; char *ptrs[5]; GtkCTreeNode *p; for(n=pn->xmlChildrenNode;n!=NULL;n=n->next) { if(n->type!=XML_ELEMENT_NODE) continue; ptrs[0]=xmlGetProp(n,"name"); if(!strcmp(n->name,"f")){ char *expanded=xmlGetProp(n,"expanded"); ptrs[1]=NULL; ptrs[2]=NULL; ptrs[3]=NULL; ptrs[4]=NULL; p=gtk_ctree_insert_node(GTK_CTREE(bookmark_list), parent,NULL,ptrs,0, NULL,NULL,NULL,NULL, FALSE,expanded && !strcmp(expanded,"true")); free(expanded); gtk_ctree_node_set_row_data(GTK_CTREE(bookmark_list),p,n); insert_bookmarks_at(p,n); } else if(!strcmp(n->name,"b")){ ptrs[1]=xmlGetProp(n,"host"); ptrs[2]=xmlGetProp(n,"port"); if(ptrs[2]==NULL || strlen(ptrs[2])==0) { free(ptrs[2]); ptrs[2]=strdup("5500"); } ptrs[3]=xmlGetProp(n,"login"); ptrs[4]=xmlGetProp(n,"passwd"); if(ptrs[4]!=NULL && strlen(ptrs[4])>0 && passwords_are_hidden) { free(ptrs[4]); ptrs[4]=strdup("******"); } p=gtk_ctree_insert_node(GTK_CTREE(bookmark_list), parent,NULL,ptrs,0, NULL,NULL,NULL,NULL, TRUE,FALSE); gtk_ctree_node_set_row_data(GTK_CTREE(bookmark_list),p,n); } { int i; for(i = 0; i < 5; i++) free(ptrs[i]); } } } static void populate_bklist(){ gfloat pos; GtkAdjustment *a; if(bookmark_window==NULL) return; gtk_clist_freeze(GTK_CLIST(bookmark_list)); a=gtk_clist_get_vadjustment(GTK_CLIST(bookmark_list)); pos=a->value; gtk_clist_clear(GTK_CLIST(bookmark_list)); insert_bookmarks_at(NULL,Bookmarks_ptr); gtk_adjustment_set_value(a,pos); if(selected_node!=NULL || selected_folder!=NULL){ int i=gtk_clist_find_row_from_data(GTK_CLIST(bookmark_list), selected_node==NULL?selected_folder:selected_node); if(i!=-1) gtk_clist_select_row(GTK_CLIST(bookmark_list),i,-1); } gtk_clist_thaw(GTK_CLIST(bookmark_list)); } static GnomeUIInfo menu_bookmarks[]={ GNOMEUIINFO_ITEM_STOCK(N_("Connect as..."), N_("Connect to this Hotline Server, with different login / password"), connect_as_callback, HL_MENU HL_STOCK_PIXMAP_CONNECT), GNOMEUIINFO_ITEM_STOCK(N_("Properties..."),N_("Edit server's properties"), properties_callback, HL_MENU HL_STOCK_PIXMAP_PROP_BOOKMARK), GNOMEUIINFO_SEPARATOR, GNOMEUIINFO_ITEM_STOCK(N_("New Folder"),N_("Add a new folder item."), new_folder_callback, HL_MENU HL_STOCK_PIXMAP_BOOKMARK_FOLDER), GNOMEUIINFO_ITEM_STOCK(N_("Delete"),N_("Delete this bookmark"), delete_bkmark_callback, HL_MENU HL_STOCK_PIXMAP_DELETE), GNOMEUIINFO_END }; static char *list_names[]={N_(" Name "), N_(" IP "), N_(" Port "), N_(" Login "), N_(" Password ")}; void show_bookmarks() { GtkWidget *tmp; if(bookmark_window!=NULL){ guiutils_raise_window(GTK_WINDOW(bookmark_window)); return; } bookmark_window=gnome_app_new(PACKAGE "/Bookmarks",N_("Bookmarks")); gnome_app_create_toolbar(GNOME_APP(bookmark_window),toolbar); tmp=gtk_scrolled_window_new(NULL,NULL); gnome_app_set_contents(GNOME_APP(bookmark_window),tmp); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tmp), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); bookmark_list=gtk_ctree_new_with_titles(5,0,list_names); gtk_container_add(GTK_CONTAINER(tmp),bookmark_list); gtk_clist_set_selection_mode(GTK_CLIST(bookmark_list),GTK_SELECTION_SINGLE); gtk_clist_column_titles_passive(GTK_CLIST(bookmark_list)); gtk_ctree_set_expander_style(GTK_CTREE(bookmark_list),GTK_CTREE_EXPANDER_SQUARE); gtk_ctree_set_line_style(GTK_CTREE(bookmark_list),GTK_CTREE_LINES_DOTTED); gtk_ctree_set_reorderable(GTK_CTREE(bookmark_list),TRUE); guiprefs_add_clist(GTK_CLIST(bookmark_list), "Bookmarks/Window/List", "250,100,60,0,0"); populate_bklist(); gtk_signal_connect(GTK_OBJECT(bookmark_list), "tree-select-row", GTK_SIGNAL_FUNC(select_row_callback), NULL); gtk_signal_connect(GTK_OBJECT(bookmark_list), "tree-unselect-row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL); gtk_signal_connect(GTK_OBJECT(bookmark_list), "tree-expand", GTK_SIGNAL_FUNC(expand_tree_callback), NULL); gtk_signal_connect(GTK_OBJECT(bookmark_list), "tree-collapse", GTK_SIGNAL_FUNC(collapse_tree_callback), NULL); gtk_signal_connect(GTK_OBJECT(bookmark_list), "tree-move", GTK_SIGNAL_FUNC(bookmark_move_callback), NULL); gtk_signal_connect(GTK_OBJECT (bookmark_window), "delete_event", GTK_SIGNAL_FUNC(close_bookmark_window), NULL); gutils_clist_add_popup_menu(bookmark_list,menu_bookmarks,NULL); gutils_clist_on_dblclick(bookmark_list,handle_dblclick,NULL); guiprefs_add_window(GTK_WINDOW(bookmark_window),"Bookmarks/Window/Size"); selected_node=NULL; highlight_toolbar(NULL); gtk_widget_show_all(bookmark_window); register_window(bookmark_window,N_("_Bookmarks")); }