/* Copyright (C) 2000-2003 Markus Lausser (sgop@users.sf.net) This is free software distributed under the terms of the GNU Public License. See the file COPYING for details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lopster.h" #include "callbacks.h" #include "connection.h" #include "global.h" #include "search.h" #include "browse.h" #include "handler.h" #include "support.h" #include "transfer.h" #include "resume.h" #include "share2.h" #include "string_list.h" #include "whois.h" #include "ping.h" #include "clist_rename.h" #include "utils.h" #include "files.h" #include "filetips.h" #include "file_tree.h" #include "dialog.h" #include "sarray.h" GdkColor library_color = {0, 45874, 24247, 5242 }; GdkColor resume_color = {0, 0, 0, 65535}; GdkColor normal_color = {0, 0, 0, 0}; typedef int (*IntFunc) (char *str); #define WORD_CHAR(c) \ (isalnum((unsigned char)(c))||(c)=='\''||(unsigned char)(c) > 128) void search_pattern_destroy(search_pattern_t * search); static char *Destination(int id) { static char result[10]; int pos = 0; if (id & DEST_NAPSTER) result[pos++] = 'N'; if (id & DEST_BROWSE) result[pos++] = 'B'; if (id & DEST_LIBRARY) result[pos++] = 'L'; if (id & DEST_SEARCH) result[pos++] = 'S'; result[pos] = 0; return result; } static int get_real_speed(char *trans) { if (!g_strcasecmp(trans, "not specified")) return 0; else return speed2int(trans); } static int get_real_int(char *trans) { if (!g_strcasecmp(trans, "not specified")) return 0; else return atoi(trans); } int life2int(char *dest) { if (!g_strcasecmp(dest, "Ignore")) return PATTERN_IGNORE; else if (!g_strcasecmp(dest, "Save")) return PATTERN_SAVE; else if (!g_strcasecmp(dest, "Template")) return PATTERN_TEMPLATE; else if (!g_strcasecmp(dest, "Autosearch")) return PATTERN_SEARCH; else return PATTERN_TEMPORARY; } char* LifeTime(int id) { switch (id) { case PATTERN_IGNORE: return "Ignore"; case PATTERN_SAVE: return "Save"; case PATTERN_TEMPLATE: return "Template"; case PATTERN_SEARCH: return "Autosearch"; case PATTERN_TEMPORARY: default: return "Temporary"; } return "??"; } char *search_arg(char *data) { static char *string; char *pos; if (data) string = data; if (!string) return NULL; while (*string && !WORD_CHAR(*string)) string++; pos = string; while (WORD_CHAR(*string)) { string++; } if (pos == string) { string = NULL; return NULL; } else { if (*string != 0) *string++ = 0; return pos; } } void on_search_resize_column (GtkCList *clist, gint column, gint width, gpointer user_data ATTR_UNUSED) { GList* dlist; GtkCList* clist2; search_t* search; if (global.search_width[column] == width) return; global.search_width[column] = width; for (dlist = global.searches; dlist; dlist = dlist->next) { search = dlist->data; if (search->resume) continue; clist2 = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(search->link), "ctree")); if (clist == clist2) continue; gtk_clist_set_column_width (clist2, column, width); } } static gboolean on_list_leave_notify_event(GtkWidget * widget ATTR_UNUSED, GdkEventCrossing* event, gpointer user_data ATTR_UNUSED) { filetips_show(NULL, event->x_root, event->y_root, NULL); return FALSE; } static gboolean on_search_motion_notify_event(GtkWidget * widget, GdkEventMotion * event, gpointer user_data ATTR_UNUSED) { int row, column; file_t *file; if (!gtk_clist_get_selection_info(GTK_CLIST(widget), (int) event->x, (int) event->y, &row, &column)) { filetips_show(NULL, event->x_root, event->y_root, NULL); return FALSE; } if (row < 0) return FALSE; file = gtk_clist_get_row_data(GTK_CLIST(widget), row); if (!file) return FALSE; filetips_show(widget, event->x_root, event->y_root, file); return FALSE; } void search_create_page(search_t * search) { GtkWidget *scrolledwindow; GtkWidget *search_list; GtkWidget *label; search_pattern_t *pattern; GtkWidget *tab_label; GtkWidget *button; GtkWidget *pix1; char *str; GtkNotebook *notebook; pattern = search->pattern; if (!pattern) { printf("no pattern in search\n"); return; } scrolledwindow = gtk_scrolled_window_new(NULL, NULL); gtk_widget_show(scrolledwindow); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); search->link = (void *) scrolledwindow; search_list = gtk_ctree_new(9, 1); gtk_widget_show(search_list); gtk_widget_set_events(search_list, GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); gtk_ctree_set_line_style(GTK_CTREE(search_list), GTK_CTREE_LINES_DOTTED); gtk_clist_set_sort_column(GTK_CLIST(search_list), 1); // gtk_clist_set_auto_sort(GTK_CLIST(search_list), TRUE); gtk_clist_set_compare_func(GTK_CLIST(search_list), search_compare); gtk_container_add(GTK_CONTAINER(scrolledwindow), search_list); gtk_clist_set_column_width(GTK_CLIST(search_list), 0, global.search_width[0]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 0, global.search_show[0]); gtk_clist_set_column_width(GTK_CLIST(search_list), 1, global.search_width[1]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 1, global.search_show[1]); gtk_clist_set_column_width(GTK_CLIST(search_list), 2, global.search_width[2]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 2, global.search_show[2]); gtk_clist_set_column_width(GTK_CLIST(search_list), 3, global.search_width[3]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 3, global.search_show[3]); gtk_clist_set_column_width(GTK_CLIST(search_list), 4, global.search_width[4]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 4, global.search_show[4]); gtk_clist_set_column_width(GTK_CLIST(search_list), 5, global.search_width[5]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 5, global.search_show[5]); gtk_clist_set_column_width(GTK_CLIST(search_list), 6, global.search_width[6]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 6, global.search_show[6]); gtk_clist_set_column_width(GTK_CLIST(search_list), 7, global.search_width[7]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 7, global.search_show[7]); gtk_clist_set_column_width(GTK_CLIST(search_list), 8, global.search_width[8]); gtk_clist_set_column_visibility(GTK_CLIST(search_list), 8, global.search_show[8]); // gtk_clist_set_column_auto_resize (GTK_CLIST(search_list), 0, TRUE); gtk_clist_set_selection_mode(GTK_CLIST(search_list), GTK_SELECTION_EXTENDED); gtk_clist_column_titles_show(GTK_CLIST(search_list)); label = gtk_label_new("#"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 0, label); label = gtk_label_new("Filename"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 1, label); label = gtk_label_new("Size"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 2, label); label = gtk_label_new("Bitrate"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 3, label); label = gtk_label_new("Length"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 4, label); label = gtk_label_new("User"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 5, label); label = gtk_label_new("IP"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 6, label); label = gtk_label_new("Line Speed"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 7, label); label = gtk_label_new("Ping"); gtk_widget_show(label); gtk_clist_set_column_widget(GTK_CLIST(search_list), 8, label); gtk_signal_connect(GTK_OBJECT(search_list), "click_column", GTK_SIGNAL_FUNC(on_list_click_column), NULL); gtk_signal_connect(GTK_OBJECT(search_list), "button_press_event", GTK_SIGNAL_FUNC(on_search_list_button_press_event), NULL); gtk_signal_connect(GTK_OBJECT(search_list), "motion_notify_event", GTK_SIGNAL_FUNC(on_search_motion_notify_event), NULL); gtk_signal_connect(GTK_OBJECT(search_list), "leave_notify_event", GTK_SIGNAL_FUNC(on_list_leave_notify_event), NULL); gtk_signal_connect (GTK_OBJECT (search_list), "resize_column", GTK_SIGNAL_FUNC (on_search_resize_column), NULL); str = g_strdup_printf("%s: %s\n%s", Destination(pattern->destination), int2media(pattern->media_type, 1), pattern->include); tab_label = gtk_hbox_new (FALSE, 2); gtk_widget_ref (tab_label); gtk_widget_show (tab_label); label = gtk_label_new(str); gtk_widget_show(label); gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0); g_free(str); button = gtk_button_new(); gtk_widget_show(button); gtk_box_pack_start (GTK_BOX (tab_label), button, FALSE, FALSE, 0); GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); // gtk_widget_set_sensitive(button, FALSE); pix1 = create_pixmap (global.win, "close.xpm"); gtk_widget_show (pix1); gtk_container_add (GTK_CONTAINER (button), pix1); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (on_search_close_clicked), search); gtk_object_set_data(GTK_OBJECT(search_list), "search", search); gtk_object_set_data(GTK_OBJECT(scrolledwindow), "ctree", search_list); notebook = GTK_NOTEBOOK(lookup_widget(global.win, "notebook5")); gtk_notebook_append_page(notebook, scrolledwindow, tab_label); gtk_notebook_set_page(notebook, gtk_notebook_page_num(GTK_NOTEBOOK(notebook), scrolledwindow)); } static void on_download_resume2_activate(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data) { GtkCList *list; socket_t *socket; file_t* file; list = GTK_CLIST(global.popup_list); file = gtk_clist_get_row_data(list, global.popup_row); if (file && file->net) { socket = download_create(file, user_data, NULL, NULL, 0); if (socket) download_start(socket, FALSE); } } GtkWidget *create_search_list_popup(file_t * file) { GtkWidget *popup; GtkWidget *user_popup; GtkWidget *item; GtkAccelGroup *popup_accels; GtkWidget *download; GtkWidget *download_selected; GtkWidget *clear_selected; GtkWidget *clear_users_files; GtkWidget *clear_all; GtkWidget *trennlinie13; GtkWidget *trennlinie17; GtkWidget *customize_list3; GtkCList *clist; char item_str[1024]; int item_num; GList* resume_list; GList* dlist; resume_t* resume; search_t* search; popup = gtk_menu_new(); popup_accels = gtk_menu_ensure_uline_accel_group(GTK_MENU(popup)); clist = GTK_CLIST(global.popup_list); item_num = g_list_length(clist->selection); search = gtk_object_get_data(GTK_OBJECT(clist), "search"); if (file) { if (!file->user || file->user[0] == 0) { item = create_open_menu(file->media_type, file->longname, 1); gtk_container_add(GTK_CONTAINER(popup), item); } else if (item_num < 2) { download = gtk_menu_item_new_with_label("Download"); gtk_widget_show(download); gtk_container_add(GTK_CONTAINER(popup), download); gtk_signal_connect(GTK_OBJECT(download), "activate", GTK_SIGNAL_FUNC(on_download_activate), search); download = gtk_menu_item_new_with_label("Download with Foldername"); gtk_widget_show(download); gtk_container_add(GTK_CONTAINER(popup), download); gtk_signal_connect(GTK_OBJECT(download), "activate", GTK_SIGNAL_FUNC(on_download_wd_activate), search); } else { sprintf(item_str, "Download Selected (%d)", item_num); download_selected = gtk_menu_item_new_with_label(item_str); gtk_widget_show(download_selected); gtk_container_add(GTK_CONTAINER(popup), download_selected); gtk_signal_connect(GTK_OBJECT(download_selected), "activate", GTK_SIGNAL_FUNC(on_download_selected_activate), search); sprintf(item_str, "Download Selected (%d) with Foldername", item_num); download_selected = gtk_menu_item_new_with_label(item_str); gtk_widget_show(download_selected); gtk_container_add(GTK_CONTAINER(popup), download_selected); gtk_signal_connect(GTK_OBJECT(download_selected), "activate", GTK_SIGNAL_FUNC(on_download_selected_wd_activate), search); } if ((resume_list = resume_search_size(file->size)) != NULL) { item = gtk_menu_item_new_with_label("Resume File"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); user_popup = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), user_popup); for (dlist = resume_list; dlist; dlist = dlist->next) { resume = dlist->data; item = gtk_menu_item_new_with_label(get_file_name(resume->filename)); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(user_popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_download_resume2_activate), (gpointer)resume); } g_list_free(resume_list); trennlinie17 = gtk_menu_item_new(); gtk_widget_show(trennlinie17); gtk_container_add(GTK_CONTAINER(popup), trennlinie17); gtk_widget_set_sensitive(trennlinie17, FALSE); } trennlinie13 = gtk_menu_item_new(); gtk_widget_show(trennlinie13); gtk_container_add(GTK_CONTAINER(popup), trennlinie13); gtk_widget_set_sensitive(trennlinie13, FALSE); sprintf(item_str, "Remove Selected (%d)", item_num); clear_selected = gtk_menu_item_new_with_label(item_str); gtk_widget_show(clear_selected); gtk_container_add(GTK_CONTAINER(popup), clear_selected); gtk_signal_connect(GTK_OBJECT(clear_selected), "activate", GTK_SIGNAL_FUNC(on_clear_selected_activate), NULL); clear_users_files = gtk_menu_item_new_with_label("Remove Users Files"); gtk_widget_show(clear_users_files); gtk_container_add(GTK_CONTAINER(popup), clear_users_files); gtk_signal_connect(GTK_OBJECT(clear_users_files), "activate", GTK_SIGNAL_FUNC(on_clear_users_files_activate), NULL); if (!file->net) gtk_widget_set_sensitive(clear_users_files, FALSE); } trennlinie13 = gtk_menu_item_new(); gtk_widget_show(trennlinie13); gtk_container_add(GTK_CONTAINER(popup), trennlinie13); gtk_widget_set_sensitive(trennlinie13, FALSE); clear_all = gtk_menu_item_new_with_label("Remove Search"); gtk_widget_show(clear_all); gtk_container_add(GTK_CONTAINER(popup), clear_all); gtk_signal_connect(GTK_OBJECT(clear_all), "activate", GTK_SIGNAL_FUNC(on_clear_all_activate), NULL); clear_all = gtk_menu_item_new_with_label("Remove All Searches"); gtk_widget_show(clear_all); gtk_container_add(GTK_CONTAINER(popup), clear_all); gtk_signal_connect(GTK_OBJECT(clear_all), "activate", GTK_SIGNAL_FUNC(on_clear_all_searches_activate), NULL); clear_all = gtk_menu_item_new_with_label("Remove Searches with no matches"); gtk_widget_show(clear_all); gtk_container_add(GTK_CONTAINER(popup), clear_all); gtk_signal_connect(GTK_OBJECT(clear_all), "activate", GTK_SIGNAL_FUNC(on_clear_all_match_activate), NULL); trennlinie13 = gtk_menu_item_new(); gtk_widget_show(trennlinie13); gtk_container_add(GTK_CONTAINER(popup), trennlinie13); gtk_widget_set_sensitive(trennlinie13, FALSE); clear_all = gtk_menu_item_new_with_label("Search again"); gtk_widget_show(clear_all); gtk_container_add(GTK_CONTAINER(popup), clear_all); gtk_signal_connect(GTK_OBJECT(clear_all), "activate", GTK_SIGNAL_FUNC(on_search_again_activate), NULL); clear_all = gtk_menu_item_new_with_label("Search all again"); gtk_widget_show(clear_all); gtk_container_add(GTK_CONTAINER(popup), clear_all); gtk_signal_connect(GTK_OBJECT(clear_all), "activate", GTK_SIGNAL_FUNC(on_search_all_again_activate), NULL); trennlinie17 = gtk_menu_item_new(); gtk_widget_show(trennlinie17); gtk_container_add(GTK_CONTAINER(popup), trennlinie17); gtk_widget_set_sensitive(trennlinie17, FALSE); if (file && file->net) { item = gtk_menu_item_new_with_label("User Menu"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); user_popup = create_user_popup(M_SEARCH, file); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), user_popup); trennlinie17 = gtk_menu_item_new(); gtk_widget_show(trennlinie17); gtk_container_add(GTK_CONTAINER(popup), trennlinie17); gtk_widget_set_sensitive(trennlinie17, FALSE); } customize_list3 = gtk_menu_item_new_with_label("Customize List"); gtk_widget_show(customize_list3); gtk_container_add(GTK_CONTAINER(popup), customize_list3); gtk_signal_connect(GTK_OBJECT(customize_list3), "activate", GTK_SIGNAL_FUNC(on_customize_list_activate), GINT_TO_POINTER(1)); return popup; } gint search_compare(GtkCList * clist, gconstpointer ptr1, gconstpointer ptr2) { file_t *file1; file_t *file2; char *text1 = NULL; char *text2 = NULL; GtkCListRow *row1 = (GtkCListRow *) ptr1; GtkCListRow *row2 = (GtkCListRow *) ptr2; file1 = row1->data; file2 = row2->data; if (!file2) return (file1 != NULL); if (!file1) return -1; if (clist->sort_column == 0) { text1 = GTK_CELL_TEXT(row1->cell[0])->text; text2 = GTK_CELL_TEXT(row2->cell[0])->text; if (atoi(text1) < atoi(text2)) return -1; else if (atoi(text1) > atoi(text2)) return 1; else return 0; } else if (clist->sort_column == 1) { return g_strcasecmp(file1->shortname, file2->shortname); } else if (clist->sort_column == 2) { if (file1->size < file2->size) return -1; if (file1->size > file2->size) return 1; return 0; } else if (clist->sort_column == 3) { if (file1->bitrate < file2->bitrate) return -1; if (file1->bitrate > file2->bitrate) return 1; return 0; } else if (clist->sort_column == 4) { if (file1->duration < file2->duration) return -1; if (file1->duration > file2->duration) return 1; return 0; } else if (clist->sort_column == 5) { return g_strcasecmp(file1->user, file2->user); } else if (clist->sort_column == 6) { unsigned long ip1 = ntohl(file1->ip); unsigned long ip2 = ntohl(file2->ip); if (ip1 < ip2) return -1; if (ip1 > ip2) return +1; return 0; } else if (clist->sort_column == 7) { if (file1->linespeed < file2->linespeed) return -1; if (file1->linespeed > file2->linespeed) return +1; return 0; } else if (clist->sort_column == 8) { if (!file1->ping) return (file2->ping != 0); if (!file2->ping) return -1; if (file1->ping < file2->ping) return -1; if (file1->ping > file2->ping) return 1; return 0; } else { return 0; } } gint check_search_timeout(gpointer data) { search_t *search = ((void **)data)[0]; search_info_t *si = ((void **)data)[1]; if (si->last_result + global.options.search_timeout < global.current_time) { search_finish(search, si->net, 1); g_free(data); return 0; } return 1; } int search_show(search_t* search, int count) { GtkCTree* ctree; file_t* file; int cnt = 0; int i1; if (!search) return 0; if (search->resume) return 0; if (!search->link) return 0; ctree = GTK_CTREE(gtk_object_get_data(GTK_OBJECT(search->link), "ctree")); gtk_clist_freeze(GTK_CLIST(ctree)); for (i1 = 0; i1 < sarray_size(search->results); i1++) { file = sarray_item(search->results, i1); if (count && cnt >= count) break; if (search->invisible == 0) break; if (file->visible) continue; search_insert_file_real(ctree, file); search->invisible--; cnt++; } gtk_clist_thaw(GTK_CLIST(ctree)); search_update_stats(search, 1); return cnt; } gint search_update(gpointer data) { search_t *search = data; int cnt; cnt = search_show(search, 10); if (cnt == 0 && search->updater >= 0) { if (search->invisible != 0) g_warning("search has %d invisible results", search->invisible); gtk_idle_remove(search->updater); search->updater = -1; } return 1; } search_info_t* search_info_new(net_t* net) { search_info_t* st; st = g_malloc(sizeof(*st)); st->net = net; st->timer = -1; st->timeout = 0; st->active = 0; st->last_result = global.current_time; return st; } void search_info_add(search_t* search, net_t* net) { search_info_t* si; si = search_info_new(net); search->net_info = g_list_append(search->net_info, si); } void search_info_destroy(search_info_t* si) { if (si->timer != -1) { gtk_timeout_remove(si->timer); } g_free(si); } void search_info_remove(search_t* search, net_t* net) { search_info_t* si; GList* dlist; for (dlist = search->net_info; dlist; dlist = dlist->next) { si = dlist->data; if (si->net == net) { search->net_info = g_list_remove(search->net_info, si); search_info_destroy(si); return; } } #ifdef SEARCH_DEBUG printf("search info not found\n"); #endif return; } search_info_t* search_info_find(search_t* search, net_t* net) { search_info_t* si; GList* dlist; for (dlist = search->net_info; dlist; dlist = dlist->next) { si = dlist->data; if (si->net == net) return si; } return NULL; } void napster_search(search_t * search, net_t* net) { search_pattern_t* pattern; search_info_t* si; if (!search->pattern) return; pattern = search->pattern; net->cur_searches++; net->search_cnt++; net->queued_searches = g_list_remove(net->queued_searches, search); net->active_searches = g_list_append(net->active_searches, search); search_update_counter(); if (!pattern->include || !pattern->include[0]) { search_finish(search, net, 1); return; } si = search_info_find(search, net); if (si) { void **p; si->active = 1; si->last_result = global.current_time; if (si->timeout > 0 && si->timer == -1 && (p=(void **)g_malloc(sizeof(void *)*2))){ p[0] = search; p[1] = si; si->timer = gtk_timeout_add(SEARCH_TO_IVAL, check_search_timeout, p); } } command_send(net, CMD_SEARCH, pattern->include, pattern->exclude, pattern->max_results, pattern->media_type, pattern->bitrate_lo, pattern->bitrate_hi, pattern->freq_lo, pattern->freq_hi, pattern->speed_lo, pattern->speed_hi, pattern->size_lo, pattern->size_hi, pattern->duration_lo, pattern->duration_hi); #ifdef SEARCH_DEBUG printf("[SEARCH] doing (%s) on %s (%d)\n", search->pattern->include, net->name, net->cur_searches); #endif } static void search_pattern_add_template(search_pattern_t* pattern) { GtkWidget* list; GtkCombo* combo; GtkWidget *li; combo = GTK_COMBO(lookup_widget(global.win, "combo42")); list = combo->list; li = gtk_list_item_new_with_label ((gchar *) pattern->name); gtk_object_set_data(GTK_OBJECT(li), "data", pattern); gtk_widget_show (li); gtk_container_add (GTK_CONTAINER (list), li); } static void search_pattern_remove_template(search_pattern_t* pattern) { GtkWidget* list; GtkCombo* combo; GtkWidget* child; GList* children; search_pattern_t* pattern2; combo = GTK_COMBO(lookup_widget(global.win, "combo42")); list = combo->list; children = GTK_LIST(list)->children; while (children) { child = children->data; children = children->next; pattern2 = gtk_object_get_data(GTK_OBJECT(child), "data"); if (pattern2 == pattern) { gtk_container_remove(GTK_CONTAINER(list), child); return; } } } static void search_pattern_update_template(search_pattern_t* pattern) { GtkWidget* list; GtkCombo* combo; GtkWidget* child; GList* children; search_pattern_t* pattern2; combo = GTK_COMBO(lookup_widget(global.win, "combo42")); list = combo->list; children = GTK_LIST(list)->children; while (children) { child = children->data; children = children->next; pattern2 = gtk_object_get_data(GTK_OBJECT(child), "data"); if (pattern2 == pattern) { // child is a list item, get the label child = GTK_BIN(child)->child; if (child) gtk_label_set_text(GTK_LABEL(child), pattern->name); return; } } } void search_pattern_insert(search_pattern_t* pattern, int save) { GtkCList* clist; int row; if (pattern->level < PATTERN_TEMPORARY) { search_pattern_destroy(pattern); return; } clist = GTK_CLIST(lookup_widget(global.win, "clist34")); global.search_pattern = g_list_append(global.search_pattern, pattern); strcpy(tstr[0], pattern->name); sprintf(tstr[1], "%s: %s", Destination(pattern->destination), int2media(pattern->media_type, 1)); strcpy(tstr[2], LifeTime(pattern->level)); row = gtk_clist_append(clist, list); gtk_clist_set_row_data(clist, row, (gpointer) pattern); if (save && (pattern->level >= PATTERN_SAVE)) search_pattern_save(); if (pattern->level == PATTERN_TEMPLATE) search_pattern_add_template(pattern); } int search_pattern_cmp(search_pattern_t* p1, search_pattern_t* p2) { if (g_strcasecmp(p1->include, p2->include)) return 1; if (g_strcasecmp(p1->exclude, p2->exclude)) return 1; if (p1->max_results != p2->max_results) return 1; if (p1->media_type != p2->media_type) return 1; if (p1->destination != p2->destination) return 1; if (p1->bitrate_lo != p2->bitrate_lo) return 1; if (p1->bitrate_hi != p2->bitrate_hi) return 1; if (p1->freq_lo != p2->freq_lo) return 1; if (p1->freq_hi != p2->freq_hi) return 1; if (p1->speed_lo != p2->speed_lo) return 1; if (p1->speed_hi != p2->speed_hi) return 1; if (p1->size_lo != p2->size_lo) return 1; if (p1->size_hi != p2->size_hi) return 1; if (p1->duration_lo != p2->duration_lo) return 1; if (p1->duration_hi != p2->duration_hi) return 1; return 0; } static search_pattern_t* search_pattern_find_same(search_pattern_t* pattern) { search_pattern_t* result; search_t* search; GList* dlist; for (dlist = global.search_pattern; dlist; dlist = dlist->next) { result = dlist->data; if (!search_pattern_cmp(pattern, result)) return result; } for (dlist = global.searches; dlist; dlist = dlist->next) { search = dlist->data; if (search->resume) continue; if (!search_pattern_cmp(pattern, search->pattern)) return search->pattern; } return NULL; } static search_pattern_t* search_pattern_find_template(char* text) { search_pattern_t* result; GList* dlist; for (dlist = global.search_pattern; dlist; dlist = dlist->next) { result = dlist->data; if (result->level != PATTERN_TEMPLATE) continue; if (!strcmp(result->name, text)) return result; } return NULL; } static search_pattern_t* find_pattern_id(int id) { search_pattern_t* pattern; GList* dlist; for (dlist = global.search_pattern; dlist; dlist = dlist->next) { pattern = dlist->data; if (id == pattern->id) return pattern; } return NULL; } static int find_free_pattern_id() { int id = 0; while (1) { if (!find_pattern_id(id)) return id; id++; } return -1; } static void search_pattern_reset(search_pattern_t* search) { if (search->include) g_free(search->include); if (search->exclude) g_free(search->exclude); search->include = NULL; search->exclude = NULL; search->media_type = MEDIA_MP3; search->destination = DEST_NAPSTER; search->bitrate_lo = 0; search->bitrate_hi = 0; search->freq_lo = 0; search->freq_hi = 0; search->speed_lo = 0; search->speed_hi = 0; search->max_results = 200; search->size_lo = 0; search->size_hi = 0; search->duration_lo = 0; search->duration_hi = 0; } search_pattern_t *search_pattern_new() { search_pattern_t *pattern; pattern = g_malloc(sizeof(*pattern)); pattern->name = NULL; pattern->include = NULL; pattern->exclude = NULL; pattern->level = PATTERN_TEMPORARY; pattern->id = find_free_pattern_id(); //find free id search_pattern_reset(pattern); return pattern; } static int search_get_destination() { int result = 0; GtkToggleButton* button; button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton83")); if (gtk_toggle_button_get_active(button)) result |= DEST_NAPSTER; button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton84")); if (gtk_toggle_button_get_active(button)) result |= DEST_BROWSE; button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton85")); if (gtk_toggle_button_get_active(button)) result |= DEST_LIBRARY; button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton86")); if (gtk_toggle_button_get_active(button)) result |= DEST_SEARCH; return result; } static int extract_destination(char* pos) { int dest = 0; if (!pos) return 0; while (*pos) { if (*pos == 'N') dest |= DEST_NAPSTER; else if (*pos == 'L') dest |= DEST_LIBRARY; else if (*pos == 'B') dest |= DEST_BROWSE; else if (*pos == 'S') dest |= DEST_SEARCH; pos++; } return dest; } static void search_pattern_get(search_pattern_t* search) { GtkWidget *temp; char* text; char* pos; temp = lookup_widget(global.win, "search_artist"); search->destination = 0; text = g_strdup(gtk_entry_get_text(GTK_ENTRY(temp))); if (text[0] == ':') { pos = arg(text, 0)+1; search->destination = extract_destination(pos); pos = arg(NULL, 1); } else { pos = text; } if (pos) search->include = g_strdup(pos); else search->include = g_strdup(""); search->name = g_strdup(search->include); g_free(text); temp = lookup_widget(global.win, "entry69"); search->exclude = g_strdup(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "search_results"); search->max_results = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(temp)); temp = lookup_widget(global.win, "combo_entry17"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->media_type = media2int(gtk_entry_get_text(GTK_ENTRY(temp))); /* if not specified with the search string, get destination * from buttons */ if (!search->destination) search->destination = search_get_destination(); temp = lookup_widget(global.win, "entry76"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->bitrate_lo = get_real_int(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "combo_bitrate2"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->bitrate_hi = get_real_int(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry77"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->freq_lo = get_real_int(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "combo_freq2"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->freq_hi = get_real_int(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry78"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->speed_lo = get_real_speed(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "combo_speed2"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->speed_hi = get_real_speed(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry127"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->size_lo = extract_bytes(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry129"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->size_hi = extract_bytes(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry128"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->duration_lo = extract_duration(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "entry130"); if (GTK_WIDGET_IS_SENSITIVE(temp)) search->duration_hi = extract_duration(gtk_entry_get_text(GTK_ENTRY(temp))); temp = lookup_widget(global.win, "combo_entry28"); search->level = life2int(gtk_entry_get_text(GTK_ENTRY(temp))); } static search_pattern_t* search_pattern_create() { search_pattern_t *search; search = search_pattern_new(); search_pattern_get(search); if (search->include[0] == 0) { search_pattern_destroy(search); if (search->level == PATTERN_TEMPLATE) info_dialog("Template name is empty! Specify it in the search line"); else info_dialog("Empty search string!"); return NULL; } return search; } static void search_pattern_include(search_pattern_t* pattern, char* token) { char* new_inc; if (!token || *token == 0) return; if (pattern->include) { new_inc = g_strdup_printf("%s %s", pattern->include, token); g_free(pattern->include); } else { new_inc = g_strdup(token); } pattern->include = new_inc; } static void search_pattern_exclude(search_pattern_t* pattern, char* token) { char* new_exc; if (!token || *token == 0) return; if (pattern->exclude) { new_exc = g_strdup_printf("%s %s", pattern->exclude, token); g_free(pattern->exclude); } else { new_exc = g_strdup(token); } pattern->exclude = new_exc; } void send_search_request_from_string(char* data) { search_pattern_t *pattern; search_pattern_t *pattern2; search_t *search; char* token; token = arg(data, 0); if (!token) return; pattern = search_pattern_new(); while (token) { if (*token == ':') { token++; pattern->destination = extract_destination(token); } else if (*token == '-') { token++; search_pattern_exclude(pattern, token); } else if (*token == '<') { token++; pattern->media_type = media2int(token); } else { if (*token == '+') token++; search_pattern_include(pattern, token); } token = arg(NULL, 0); } if (!pattern->include) { search_pattern_destroy(pattern); return; } pattern->name = g_strdup(pattern->include); pattern2 = search_pattern_find_same(pattern); if (pattern2) { search_pattern_destroy(pattern); search_pattern_search(pattern2, NULL); return; } search_pattern_insert(search_pattern_copy(pattern), 1); ////// search = search_new(); search->pattern = pattern; search_create_page(search); ///// search_queue(search, NULL, 1); } void search_show_template(char* text) { search_pattern_t* pattern; pattern = search_pattern_find_template(text); if (pattern) search_pattern_show(pattern, 0); } static net_t* search_get_net() { GtkWidget* list; GtkCombo* combo; GtkWidget *li; GList* selection; net_t* net; combo = GTK_COMBO(lookup_widget(global.win, "combo43")); list = combo->list; selection = GTK_LIST(list)->selection; if (!selection) return NULL; li = selection->data; if (!li) return NULL; net = gtk_object_get_data(GTK_OBJECT(li), "data"); return net; } void send_search_request(gboolean local) { search_pattern_t *pattern; search_pattern_t *pattern2; search_t *search; net_t* net; pattern = search_pattern_create(); if (!pattern) return; net = search_get_net(); pattern2 = search_pattern_find_same(pattern); if (pattern2) { if (pattern->level == PATTERN_TEMPLATE) { search_pattern_destroy(pattern); info_dialog("Search template is already existent!"); } else { search_pattern_destroy(pattern); search_pattern_search(pattern2, net); } return; } if (pattern->level == PATTERN_TEMPLATE) { search_pattern_insert(pattern, 1); return; } else { search_pattern_insert(search_pattern_copy(pattern), 1); } ////// search = search_new(); search->pattern = pattern; search->local = local; search_create_page(search); ///// search_queue(search, net, 1); } int search_insert_file(search_t* search, file_t * file) { if (search->resume) { /* creating a transfer for the result * the file isnt really inserted */ return resume_insert_file((resume_t*)(search->link), file); } else { if (sarray_find(search->results, file)) return 0; file = file_duplicate(file); sarray_insert(search->results, file); file->visible = 0; search->invisible++; if (search->updater == -1) search->updater = gtk_idle_add(search_update, search); return 1; } } GtkCTreeNode* search_find_node(GtkCTree* ctree, file_t* file) { GtkCTreeNode* node; file_t* file2; node = GTK_CTREE_NODE (GTK_CLIST (ctree)->row_list); while (node) { file2 = gtk_ctree_node_get_row_data(ctree, node); if (file2->size == file->size) return node; node = GTK_CTREE_ROW (node)->sibling; } return NULL; } int count_siblings(GtkCTreeNode* node) { int cnt = 0; while (node) { node = GTK_CTREE_ROW (node)->sibling; cnt++; } return cnt; } static void ping_update_file(GtkWidget * widget, file_t * file) { char str[1024]; GtkCTree *ctree; GtkCTreeNode* node; if (!widget) return; ctree = GTK_CTREE(gtk_object_get_data(GTK_OBJECT(widget), "ctree")); node = gtk_ctree_find_by_row_data(ctree, NULL, file); if (!node) return; if (file->ping) { sprintf(str, "%d ms", file->ping); } else { sprintf(str, "n/a"); } gtk_ctree_node_set_text(ctree, node, 8, str); } void ping_update(unsigned long ip, int ptime) { search_t *search; GList *dlist; file_t *file; int i1; for (dlist = global.searches; dlist; dlist = dlist->next) { search = dlist->data; for (i1 = 0; i1 < sarray_size(search->results); i1++) { file = sarray_item(search->results, i1); if (file->ip == ip) { file->ping = ptime; if (!search->resume) ping_update_file(search->link, file); } } } } void search_insert_file_real(GtkCTree* ctree, file_t * file) { GdkPixmap *pixmap = NULL; GdkBitmap *mask = NULL; GtkCTreeNode* node; GList * tmp_list; node = search_find_node(ctree, file); file->visible = 1; if (global.options.search_show_folder) strcpy(tstr[1], file->shortname); else strcpy(tstr[1], file->filename); sprintf(tstr[2], "%.2f MB", (double) (file->size) / 1024 / 1024); sprintf(tstr[3], "%d", file->bitrate); print_time_short(tstr[4], file->duration); if (!file->user || file->user[0] == 0) { sprintf(tstr[5], "[%s]", file->net?NetType[file->net->type]:"Library"); } else { sprintf(tstr[5], "[%s] %s", file->net?NetType[file->net->type]:"???", file->user); } if (!file->user || file->user[0] == 0) strcpy(tstr[6], "localhost"); else if (!file->net) strcpy(tstr[6], "???"); else sprintf(tstr[6], "%s", ntoa(file->ip)); if (!file->user || file->user[0] == 0) strcpy(tstr[7], "Local File"); else if (!file->net) strcpy(tstr[7], LineSpeed(0)); else strcpy(tstr[7], LineSpeed(file->linespeed)); if (global.options.ping_search && file->net) { int ptime = ping(file->ip); if (ptime == 0) sprintf(tstr[8], "n/a"); else if (ptime == -1) sprintf(tstr[8], "eval.."); else sprintf(tstr[8], "%d ms", ptime); } else { strcpy(tstr[8], ""); } detect_line_pixs(file->linespeed, &pixmap, &mask); if (node) { if (GTK_CTREE_ROW(node)->children) sprintf(tstr[0], "%d", count_siblings(GTK_CTREE_ROW(node)->children)+2); else sprintf(tstr[0], "2"); gtk_ctree_node_set_text(ctree, node, 0, tstr[0]); } strcpy(tstr[0], ""); node = gtk_ctree_insert_node(ctree, node, NULL, list, 5, pixmap, mask, pixmap, mask, FALSE, FALSE); gtk_ctree_node_set_row_data(ctree, node, file); /* mark library file and resume with color */ if((tmp_list = resume_search_size_real(file->size)) != NULL) { gtk_ctree_node_set_foreground(ctree, node, &resume_color); g_list_free(tmp_list); } else if ((tmp_list = file_tree_search_filesize(FILE_TREE(global.lib), file)) != NULL) { gtk_ctree_node_set_foreground(ctree, node, &library_color); g_list_free(tmp_list); } } int file_cmp(file_t * file1, file_t * file2) { if (file1->size != file2->size) return 1; if (strcmp(file1->winname, file2->winname)) return 2; if (g_strcasecmp(file1->user, file2->user)) return 3; // if (file1->bitrate != file2->bitrate) return 4; // if (file1->frequency != file2->frequency) return 5; // if (file1->duration != file2->duration) return 6; return 0; } // destination should always be DEST_NAPSTER, as the other search routines // do not use this function // inserts a file in all possible searches void file_insert_search(file_t * file, int destination) { search_t *search; GList *dlist; int cnt = 0; search_info_t* si; if ((destination != DEST_NAPSTER) || !file->net) { g_warning("file_insert_search: error"); } for (dlist = file->net->active_searches; dlist; dlist = dlist->next) { search = dlist->data; /* check whether search still exists in global.searches * if it is not existent, then its was already deleted * but the search end tag wasnt received yet from the network */ if (!g_list_find(global.searches, search)) return; if (!search->link) { g_warning("search has on link"); continue; } if (search_pattern_fits_file(search->pattern, file, 0)) { cnt++; search_insert_file(search, file); } si = search_info_find(search, file->net); if (si) si->last_result = global.current_time; } #ifdef SEARCH_DEBUG if (cnt == 0) { printf("[SEARCH] (%s) could not find search for\n\t[%s] %ld\n", file->net?file->net->name:"local", file->longname, file->size); } #endif } void search_pattern_load() { FILE *file; char* filename; char line[2048]; search_pattern_t *search = NULL; char *pos; char *pos2; filename = g_strdup_printf("%s%csearches.save", global.options.config_dir, DIR_SEP); if ((file = fopen(filename, "r")) == NULL) { global.status.search_read = 1; g_free(filename); return; } g_free(filename); search = NULL; while (mfgets(line, sizeof(line), file)) { if ((line[0] == '#') || (line[0] == ' ') || (line[0] == 0)) { } else if (!strncasecmp(line, "Pattern", 7)) { pos = strchr(line, '[') + 1; pos2 = strrchr(line, ']'); if (!pos || !pos2) { g_warning("corrupted searches.save"); } else { pos2[0] = 0; if (search) search_pattern_insert(search, 0); search = search_pattern_new(); search->name = g_strdup(pos); } } else if (search) { if (!strncasecmp(line, "contains", 8)) { pos = strchr(line, '=') + 1; search->include = g_strdup(pos); } else if (!strncasecmp(line, "excludes", 8)) { pos = strchr(line, '=') + 1; search->exclude = g_strdup(pos); } else if (!strncasecmp(line, "MaxResults", 10)) { pos = strchr(line, '=') + 1; search->max_results = atoi(pos); } else if (!strncasecmp(line, "MediaType", 9)) { pos = strchr(line, '=') + 1; if (*pos == 0) // backward compatible search->media_type = MEDIA_MP3; else search->media_type = media2int(pos); } else if (!strncasecmp(line, "Destination", 11)) { pos = strchr(line, '=') + 1; search->destination = atoi(pos); if (search->destination == 0) // backward compatible search->destination = DEST_NAPSTER; } else if (!strncasecmp(line, "Bitrate", 7)) { pos = strchr(line, '=') + 1; pos2 = strchr(pos, ':'); pos2[0] = 0; pos2++; if (*pos) search->bitrate_lo = atoi(pos); if (*pos2) search->bitrate_hi = atoi(pos2); } else if (!strncasecmp(line, "Frequency", 9)) { pos = strchr(line, '=') + 1; pos2 = strchr(pos, ':'); pos2[0] = 0; pos2++; if (*pos) search->freq_lo = atoi(pos); if (*pos2) search->freq_hi = atoi(pos2); } else if (!strncasecmp(line, "LineSpeed", 9)) { pos = strchr(line, '=') + 1; pos2 = strchr(pos, ':'); pos2[0] = 0; pos2++; if (*pos) search->speed_lo = atoi(pos); if (*pos2) search->speed_hi = atoi(pos2); } else if (!strncasecmp(line, "Size", 4)) { pos = strchr(line, '=') + 1; pos2 = strchr(pos, ':'); pos2[0] = 0; pos2++; search->size_lo = strtoul(pos, NULL, 10); search->size_hi = strtoul(pos2, NULL, 10); } else if (!strncasecmp(line, "Duration", 8)) { pos = strchr(line, '=') + 1; pos2 = strchr(pos, ':'); pos2[0] = 0; pos2++; search->duration_lo = atoi(pos); search->duration_hi = atoi(pos2); } else if (!strncasecmp(line, "Level", 5)) { pos = strchr(line, '=') + 1; search->level = atoi(pos); } else { g_warning("unknown tag in section Search Pattern [%s]\n[%s]", search->name, line); } } else { g_warning("no search name is given"); } } if (search) search_pattern_insert(search, 0); fclose(file); global.status.search_read = 1; } void search_pattern_save() { search_pattern_t *search; FILE *file; char* filename; char *pos; char *pos2; GtkCList* clist; int row; clist = GTK_CLIST(lookup_widget(global.win, "clist34")); if (!clist) return; filename = g_strdup_printf("%s%csearches.save", global.options.config_dir, DIR_SEP); if ((file = fopen(filename, "w")) == NULL) { g_warning("Could not write searches"); g_free(filename); return; } g_free(filename); for (row = 0; row < clist->rows; row++) { search = gtk_clist_get_row_data(clist, row); if (!search || search->level < PATTERN_SAVE) continue; pos2 = g_strdup(search->name); for (pos = pos2; *pos; pos++) if (*pos == '\n') *pos = ' '; fprintf(file, "PATTERN [%s]\n", pos2); g_free(pos2); fprintf(file, "Contains=%s\n", search->include?search->include:""); fprintf(file, "Excludes=%s\n", search->exclude?search->exclude:""); fprintf(file, "MaxResults=%d\n", search->max_results); fprintf(file, "MediaType=%s\n", int2media(search->media_type, 1)); fprintf(file, "Destination=%d\n", search->destination); fprintf(file, "Bitrate=%d:%d\n", search->bitrate_lo, search->bitrate_hi); fprintf(file, "Frequency=%d:%d\n", search->freq_lo, search->freq_hi); fprintf(file, "LineSpeed=%d:%d\n", search->speed_lo, search->speed_hi); fprintf(file, "Size=%ld:%ld\n", search->size_lo, search->size_hi); fprintf(file, "Duration=%d:%d\n", search->duration_lo, search->duration_hi); fprintf(file, "Level=%d\n\n", search->level); } fclose(file); } void search_pattern_destroy(search_pattern_t * search) { if (!search) return; if (search->name) g_free(search->name); if (search->include) g_free(search->include); if (search->exclude) g_free(search->exclude); g_free(search); } int search_pattern_fits_file(search_pattern_t * search, file_t * file, int with_type) { static char *pos; static char *text; if ((search->bitrate_lo && file->bitrate < search->bitrate_lo) || (search->bitrate_hi && file->bitrate > search->bitrate_hi)) return 0; if ((search->freq_lo && file->frequency < search->freq_lo) || (search->freq_hi && file->frequency > search->freq_hi)) return 0; if ((search->size_lo && file->size < search->size_lo) || (search->size_hi && file->size > search->size_hi)) return 0; if ((search->duration_lo && file->duration < search->duration_lo) || (search->duration_hi && file->duration > search->duration_hi)) return 0; text = g_strdup(search->include); pos = search_arg(text); while (pos) { if (!strcasestr(file->longname, pos)) { g_free(text); return 0; } pos = search_arg(NULL); } g_free(text); text = g_strdup(search->exclude); pos = arg(text, 0); while (pos) { if (strcasestr(file->longname, pos)) return 0; pos = arg(NULL, 0); } g_free(text); if (with_type && search->media_type != MEDIA_NONE && search->media_type != file->media_type) return 0; if (!file->net) return 1; if ((search->speed_lo && file->linespeed < search->speed_lo) || (search->speed_hi && file->linespeed > search->speed_hi)) return 0; return 1; } static void search_set_destination(int dest) { GtkToggleButton* button; button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton83")); gtk_toggle_button_set_active(button, dest & DEST_NAPSTER); button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton84")); gtk_toggle_button_set_active(button, dest & DEST_BROWSE); button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton85")); gtk_toggle_button_set_active(button, dest & DEST_LIBRARY); button = GTK_TOGGLE_BUTTON(lookup_widget(global.win, "checkbutton86")); gtk_toggle_button_set_active(button, dest & DEST_SEARCH); } void search_pattern_show(search_pattern_t * pattern, int mode) { GtkWidget *temp; char *text; char str[1024]; if (pattern) { if (pattern->level != PATTERN_TEMPLATE) { temp = lookup_widget(global.win, "search_artist"); if (pattern->include) gtk_entry_set_text(GTK_ENTRY(temp), pattern->include); else gtk_entry_set_text(GTK_ENTRY(temp), ""); } temp = lookup_widget(global.win, "entry69"); if (pattern->exclude) gtk_entry_set_text(GTK_ENTRY(temp), pattern->exclude); else gtk_entry_set_text(GTK_ENTRY(temp), ""); temp = lookup_widget(global.win, "search_results"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(temp), pattern->max_results); temp = lookup_widget(global.win, "combo_entry17"); gtk_entry_set_text(GTK_ENTRY(temp), int2media(pattern->media_type, 1)); search_set_destination(pattern->destination); temp = lookup_widget(global.win, "entry76"); if (pattern->bitrate_lo) sprintf(str, "%d", pattern->bitrate_lo); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "combo_bitrate2"); if (pattern->bitrate_hi) sprintf(str, "%d", pattern->bitrate_hi); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry77"); if (pattern->freq_lo) sprintf(str, "%d", pattern->freq_lo); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "combo_freq2"); if (pattern->freq_hi) sprintf(str, "%d", pattern->freq_hi); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry78"); if (pattern->speed_lo) sprintf(str, "%s", LineSpeed(pattern->speed_lo)); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "combo_speed2"); if (pattern->speed_hi) sprintf(str, "%s", LineSpeed(pattern->speed_hi)); else strcpy(str, "not specified"); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry127"); print_bytes(str, pattern->size_lo); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry129"); if (pattern->size_hi == 0) sprintf(str, "unlimited"); else print_bytes(str, pattern->size_hi); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry128"); print_duration(str, pattern->duration_lo); gtk_entry_set_text(GTK_ENTRY(temp), str); temp = lookup_widget(global.win, "entry130"); if (pattern->duration_hi == 0) sprintf(str, "unlimited"); else print_duration(str, pattern->duration_hi); gtk_entry_set_text(GTK_ENTRY(temp), str); if (pattern->level != PATTERN_TEMPLATE) { temp = lookup_widget(global.win, "combo_entry28"); gtk_entry_set_text(GTK_ENTRY(temp), LifeTime(pattern->level)); } } else if (mode == 0) { temp = lookup_widget(global.win, "search_artist"); text = gtk_entry_get_text(GTK_ENTRY(temp)); if (!text || !(*text)) { temp = lookup_widget(global.win, "search_results"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(temp), 200); search_set_destination(DEST_NAPSTER); temp = lookup_widget(global.win, "entry76"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "combo_bitrate2"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "entry77"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "combo_freq2"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "entry78"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "combo_speed2"); gtk_entry_set_text(GTK_ENTRY(temp), "not specified"); temp = lookup_widget(global.win, "entry127"); gtk_entry_set_text(GTK_ENTRY(temp), "0B"); temp = lookup_widget(global.win, "entry129"); gtk_entry_set_text(GTK_ENTRY(temp), "unlimited"); temp = lookup_widget(global.win, "entry128"); gtk_entry_set_text(GTK_ENTRY(temp), "0s"); temp = lookup_widget(global.win, "entry130"); gtk_entry_set_text(GTK_ENTRY(temp), "unlimited"); temp = lookup_widget(global.win, "combo_entry28"); gtk_entry_set_text(GTK_ENTRY(temp), LifeTime(PATTERN_TEMPORARY)); } temp = lookup_widget(global.win, "search_artist"); gtk_entry_set_text(GTK_ENTRY(temp), ""); temp = lookup_widget(global.win, "entry69"); gtk_entry_set_text(GTK_ENTRY(temp), ""); } else if (mode == 1) { temp = lookup_widget(global.win, "combo_entry17"); gtk_entry_set_text(GTK_ENTRY(temp), "mp3"); temp = lookup_widget(global.win, "entry127"); gtk_entry_set_text(GTK_ENTRY(temp), "0B"); } else if (mode == 2) { temp = lookup_widget(global.win, "combo_entry17"); gtk_entry_set_text(GTK_ENTRY(temp), "any"); temp = lookup_widget(global.win, "entry127"); gtk_entry_set_text(GTK_ENTRY(temp), "20M"); temp = lookup_widget(global.win, "entry129"); gtk_entry_set_text(GTK_ENTRY(temp), "unlimited"); } } search_pattern_t *search_pattern_copy(search_pattern_t * search) { search_pattern_t *pattern; pattern = search_pattern_new(); if (search->name) pattern->name = g_strdup(search->name); if (search->include) pattern->include = g_strdup(search->include); if (search->exclude) pattern->exclude = g_strdup(search->exclude); pattern->media_type = search->media_type; pattern->destination = search->destination; pattern->bitrate_lo = search->bitrate_lo; pattern->bitrate_hi = search->bitrate_hi; pattern->freq_lo = search->freq_lo; pattern->freq_hi = search->freq_hi; pattern->speed_lo = search->speed_lo; pattern->speed_hi = search->speed_hi; pattern->max_results = search->max_results; pattern->size_lo = search->size_lo; pattern->size_hi = search->size_hi; pattern->duration_lo = search->duration_lo; pattern->duration_hi = search->duration_hi; pattern->id = search->id; pattern->level = search->level; return pattern; } static int search_compare_item(void* item1, void* item2) { file_t* file1 = item1; file_t* file2 = item2; int result; if (file1->size < file2->size) return -1; if (file1->size > file2->size) return 1; if (file1->ip < file2->ip) return -1; if (file1->ip > file2->ip) return 1; // ok, ip matches, now also check the filename to prevent // rar-archives to get dropped result = strcmp(file1->winname, file2->winname); if (result) return result; // only compare user names if we dont have an ip given // (results from the library or saved browses) if (file1->ip) return 0; else return strcasecmp(file1->user, file2->user); } static void search_delete(void* item) { file_destroy((file_t*)item); } search_t *search_new() { search_t *search; search = g_malloc(sizeof(search_t)); search->results = sarray_new(search_compare_item, search_delete); search->resume = 0; search->local = 0; search->pattern = NULL; search->link = NULL; search->net_info = NULL; search->updater = -1; search->invisible = 0; global.searches = g_list_append(global.searches, search); return search; } void search_clear(search_t * search) { GtkCList *clist; sarray_clear(search->results); search->invisible = 0; if (!search->resume) { clist = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(search->link), "ctree")); gtk_clist_clear(clist); } search_update_stats(search, 1); } void search_remove_file(GtkCTree* ctree, file_t* file) { GtkCTreeNode* node; GtkCTreeNode* first_child; GtkCTreeNode* node3; GtkCTreeNode* node4; int cnt; node = gtk_ctree_find_by_row_data(ctree, NULL, file); if (!node) return; if (GTK_CTREE_ROW(node)->children) { cnt = 1; first_child = GTK_CTREE_ROW(node)->children; // making all siblings of the first child to childs of the // first child while (GTK_CTREE_ROW(first_child)->sibling) { node3 = GTK_CTREE_ROW(first_child)->sibling; gtk_ctree_move(ctree, node3, first_child, NULL); cnt++; } if (cnt > 1) sprintf(tstr[0], "%d", cnt); else tstr[0][0] = 0; sprintf(tstr[0], "%d", cnt); gtk_ctree_node_set_text(ctree, first_child, 0, tstr[0]); // now moving the first child up. node3 = GTK_CTREE_ROW(node)->parent; node4 = GTK_CTREE_ROW(node)->sibling; gtk_ctree_move(ctree, first_child, node3, node4); // finally remove that node (it should have children any more) gtk_ctree_remove_node(ctree, node); } else { node3 = GTK_CTREE_ROW(node)->parent; if (node3) { first_child = GTK_CTREE_ROW(node3)->children; cnt = count_siblings(first_child); if (cnt > 1) sprintf(tstr[0], "%d", cnt); else tstr[0][0] = 0; gtk_ctree_node_set_text(ctree, node3, 0, tstr[0]); } gtk_ctree_remove_node(ctree, node); } } void search_clear_old(search_t * search, net_t* net) { file_t *file; GtkCList *clist = NULL; // initialize to get rid of GtkCTree *ctree = NULL; // compiler warnings int i1; // must not be a resume search clist = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(search->link), "ctree")); ctree = GTK_CTREE(clist); gtk_clist_freeze(clist); for (i1 = 0; i1 < sarray_size(search->results); i1++) { file = sarray_item(search->results, i1); if (!file->net) continue; if (file->net == net || !NET_CONNECTED(file->net)) { // freeing results if (!file->visible) search->invisible--; search_remove_file(ctree, file); sarray_remove(search->results, i1); i1--; // we deleted the file, so dec index } } gtk_clist_thaw(clist); search_update_stats(search, 1); } void search_destroy(search_t * search) { GList* dlist; search_info_t* si; net_t* net; if (!search) return; // clean up queued and active searches dlist = search->net_info; while (dlist) { si = dlist->data; net = si->net; dlist = dlist->next; if (si->timer >= 0) gtk_timeout_remove(si->timer); if (si->active) { if (si->timeout) search_finish(search, si->net, 1); /* dont touch the active napster searches, because the server does still returns the search_end tag which has to be processed by lopster to keep the searches_per_server counter up to date */ } else { net->queued_searches = g_list_remove(net->queued_searches, search); } g_free(si); } if (search->updater != -1) { gtk_idle_remove(search->updater); search->updater = -1; } search_clear(search); search_pattern_destroy(search->pattern); g_list_free(search->net_info); g_free(search); } void search_remove(search_t * search) { GtkNotebook *notebook; int i1; global.searches = g_list_remove(global.searches, search); if (!search->resume) { notebook = GTK_NOTEBOOK(lookup_widget(global.win, "notebook5")); i1 = gtk_notebook_page_num(notebook, GTK_WIDGET(search->link)); search_destroy(search); gtk_notebook_remove_page(notebook, i1); } else { search_destroy(search); } } void search_update_stats(search_t * search, int check) { char t[1024]; GtkWidget *label; GtkNotebook* notebook; int row; GtkWidget* temp; if (!search || search->resume) return; notebook = GTK_NOTEBOOK(lookup_widget(global.win, "notebook5")); row = gtk_notebook_get_current_page(notebook); temp = gtk_notebook_get_nth_page(notebook, row); if (!check || (temp == search->link)) { label = lookup_widget(global.win, "label597"); sprintf(t, "%d", sarray_size(search->results)); gtk_label_set_text(GTK_LABEL(label), t); label = lookup_widget(global.win, "label1677"); row = g_list_length(search->net_info); sprintf(t, "%d remaining", row); gtk_label_set_text(GTK_LABEL(label), t); } } void search_update_counter() { GList* dlist; int cnt = 0; GtkWidget *label; char t[1024]; net_t* net; for (dlist = global.net_active; dlist; dlist = dlist->next) { net = dlist->data; cnt += net->cur_searches; } label = lookup_widget(global.win, "label598"); sprintf(t, "%d", cnt); gtk_label_set_text(GTK_LABEL(label), t); } gboolean on_search_fields_delete(GtkWidget * widget, GdkEvent * event ATTR_UNUSED, gpointer user_data ATTR_UNUSED) { GtkWidget *win; GtkWidget *temp; GtkWidget *vbox; win = widget; if (win->window) { gdk_window_get_origin(win->window, &global.geometry[G_SIZE-1].x, &global.geometry[G_SIZE-1].y); } global.geometry[G_SIZE-1].width = win->allocation.width; global.geometry[G_SIZE-1].height = win->allocation.height; temp = GTK_BIN(win)->child; if (!temp) return FALSE; gtk_widget_ref(temp); gtk_container_remove(GTK_CONTAINER(win), temp); vbox = lookup_widget(global.win, "vbox5"); gtk_box_pack_start(GTK_BOX(vbox), temp, FALSE, FALSE, 0); gtk_box_reorder_child(GTK_BOX(vbox), temp, 1); gtk_widget_unref(temp); widget = lookup_widget(global.win, "button115"); gtk_widget_set_sensitive(widget, TRUE); widget = lookup_widget(global.win, "button218"); gtk_widget_set_sensitive(widget, TRUE); widget = lookup_widget(global.win, "hbox711"); gtk_widget_show(widget); global.extra_win &= (0xFFF) ^ (1 << (G_SIZE-1)); return FALSE; } GtkWidget *search_fields_detach() { GtkWidget *window; GtkWidget *widget; widget = lookup_widget(global.win, "hbox710"); if (!widget) return NULL; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(window), 5); gtk_object_set_data(GTK_OBJECT(global.win), "fields", window); gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE); gtk_window_set_title(GTK_WINDOW(window), "Search Fields"); gtk_window_set_wmclass(GTK_WINDOW(window), "Search Fields", "Lopster"); gtk_my_widget_show(window); gtk_widget_ref(widget); gtk_container_remove(GTK_CONTAINER(widget->parent), widget); gtk_container_add(GTK_CONTAINER(window), widget); gtk_widget_unref(widget); gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(on_search_fields_delete), NULL); widget = lookup_widget(global.win, "button115"); set_button_state(widget, 1); gtk_widget_set_sensitive(widget, FALSE); widget = lookup_widget(global.win, "hbox711"); gtk_widget_hide(widget); widget = lookup_widget(global.win, "button218"); gtk_widget_set_sensitive(widget, FALSE); global.extra_win |= (1 << (G_SIZE - 1)); if ((global.geometry[G_SIZE-1].x >= 0) && (global.geometry[G_SIZE-1].y >= 0)) { gtk_window_reposition(GTK_WINDOW(window), global.geometry[G_SIZE - 1].x, global.geometry[G_SIZE - 1].y); } if ((global.geometry[G_SIZE-1].width >= 0) && (global.geometry[G_SIZE-1].height >= 0)) { gtk_window_set_default_size(GTK_WINDOW(window), global.geometry[G_SIZE - 1].width, global.geometry[G_SIZE - 1].height); } return window; } gboolean on_search_fields_delete2(GtkWidget * widget, GdkEvent * event ATTR_UNUSED, gpointer user_data ATTR_UNUSED) { GtkWidget *win; GtkWidget *temp; GtkWidget *vbox; win = widget; if (win->window) { gdk_window_get_origin(win->window, &global.geometry[G_SIZE-2].x, &global.geometry[G_SIZE-2].y); } global.geometry[G_SIZE-2].width = win->allocation.width; global.geometry[G_SIZE-2].height = win->allocation.height; temp = GTK_BIN(win)->child; if (!temp) return FALSE; gtk_widget_ref(temp); gtk_container_remove(GTK_CONTAINER(win), temp); vbox = lookup_widget(global.win, "hbox710"); gtk_box_pack_start(GTK_BOX(vbox), temp, TRUE, TRUE, 0); // gtk_box_reorder_child(GTK_BOX(vbox), temp, 1); gtk_widget_unref(temp); widget = lookup_widget(global.win, "button337"); gtk_widget_set_sensitive(widget, TRUE); widget = lookup_widget(global.win, "button331"); gtk_widget_set_sensitive(widget, TRUE); widget = lookup_widget(global.win, "vbox205"); gtk_widget_show(widget); global.extra_win &= (0xFFF) ^ (1 << (G_SIZE-2)); return FALSE; } GtkWidget *search_fields_detach2() { GtkWidget *window; GtkWidget *widget; widget = lookup_widget(global.win, "scrolledwindow96"); if (!widget) return NULL; window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width(GTK_CONTAINER(window), 5); gtk_object_set_data(GTK_OBJECT(global.win), "fields2", window); gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE); gtk_window_set_title(GTK_WINDOW(window), "Search History"); gtk_window_set_wmclass(GTK_WINDOW(window), "Search History", "Lopster"); gtk_my_widget_show(window); gtk_widget_ref(widget); gtk_container_remove(GTK_CONTAINER(widget->parent), widget); gtk_container_add(GTK_CONTAINER(window), widget); gtk_widget_unref(widget); gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(on_search_fields_delete2), NULL); widget = lookup_widget(global.win, "button331"); set_button_state(widget, 1); gtk_widget_set_sensitive(widget, FALSE); widget = lookup_widget(global.win, "vbox205"); gtk_widget_hide(widget); widget = lookup_widget(global.win, "button337"); gtk_widget_set_sensitive(widget, FALSE); global.extra_win |= (1 << (G_SIZE - 2)); if ((global.geometry[G_SIZE-2].x >= 0) && (global.geometry[G_SIZE-2].y >= 0)) { gtk_window_reposition(GTK_WINDOW(window), global.geometry[G_SIZE - 2].x, global.geometry[G_SIZE - 2].y); } if ((global.geometry[G_SIZE-2].width >= 0) && (global.geometry[G_SIZE-2].height >= 0)) { gtk_window_set_default_size(GTK_WINDOW(window), global.geometry[G_SIZE - 2].width, global.geometry[G_SIZE - 2].height); } return window; } void search_search(search_t * search) { GList *dlist; file_t *file; int cnt = 0; search_t *tsearch; int i1; for (dlist = global.searches; dlist; dlist = dlist->next) { tsearch = dlist->data; // dont search in resume searches if (tsearch->resume) continue; // dont search in search itself if (tsearch == search) continue; for (i1 = 0; i1 < sarray_size(tsearch->results); i1++) { file = sarray_item(tsearch->results, i1); if (search_pattern_fits_file(search->pattern, file, 1)) { search_insert_file(search, file); cnt++; } if (search->pattern->max_results && (cnt >= search->pattern->max_results)) break; } } search_finish(search, NULL, 0); } void search_queue(search_t * search, net_t* net, int top) { GList* dlist; if (top) { if (search->pattern->destination & DEST_LIBRARY) search_do(search, NULL, DEST_LIBRARY); if (search->pattern->destination & DEST_BROWSE) search_do(search, NULL, DEST_BROWSE); if (search->pattern->destination & DEST_SEARCH) search_do(search, NULL, DEST_SEARCH); } if (!(search->pattern->destination & DEST_NAPSTER)) return; if (!net) { for (dlist = global.net_active; dlist; dlist = dlist->next) { net = dlist->data; search_queue(search, net, 0); } } else { if (g_list_find(net->queued_searches, search)) return; if (g_list_find(net->active_searches, search)) return; search_info_add(search, net); net->queued_searches = g_list_append(net->queued_searches, search); // clearing old results of finished searches if (!search->resume) search_clear_old(search, net); else ((resume_t*)(search->link))->needs_update = 1; } } void search_do(search_t * search, net_t* net, int dest) { if ((dest == DEST_NAPSTER) && !net) { g_warning("no server for search"); search_finish(search, net, 1); } if (dest == DEST_LIBRARY) { lib_do_search(search); } else if (dest == DEST_BROWSE) { browse_do_search(search); } else if (dest == DEST_NAPSTER) { napster_search(search, net); } else if (dest == DEST_SEARCH) { search_search(search); } else { g_warning("invalid search destination"); } } int search_finish(search_t* search, net_t* net, int next) { int valid_search; valid_search = (g_list_find(global.searches, search) != NULL); if (net) { // napster search net->cur_searches--; net->active_searches = g_list_remove(net->active_searches, search); if (valid_search) { #ifdef SEARCH_DEBUG printf("[SEARCH] finish (%s) on %s (%d)\n", search->pattern->include, net->name, net->cur_searches); #endif search_info_remove(search, net); if (search->resume) ((resume_t*)(search->link))->needs_update = 1; else if (search->updater == -1) { search->updater = gtk_idle_add(search_update, search); } } else { #ifdef SEARCH_DEBUG printf("[SEARCH] finish () on %s (%d)\n", net->name, net->cur_searches); #endif } if (next) search_next(net); search_update_counter(); } else { if (valid_search && search->updater == -1) { search->updater = gtk_idle_add(search_update, search); } } return valid_search; } void search_next(net_t* net) { search_t *search; search_t *winner; GList* dlist; GList* dlist2; if (net) { if (global.current_time - net->search_stamp > 61) { // reset the search counter per minute net->search_stamp = global.current_time; net->search_cnt = 0; } if (!net->queued_searches) return; // dont search if we dont know network subtype if (net->subtype == -1) return; // search limit reached? if (net->max_searches_pm && net->max_searches_pm <= net->search_cnt) return; if (net->cur_searches >= net->max_searches) return; winner = NULL; for (dlist2 = net->queued_searches; dlist2; dlist2 = dlist2->next) { search = dlist2->data; if (search->resume) { if (!winner) winner = search; } else { search_do(search, net, DEST_NAPSTER); return; } } if (winner) search_do(winner, net, DEST_NAPSTER); } else { for (dlist = global.net_active; dlist; dlist = dlist->next) { net = dlist->data; search_next(net); } } } search_t* search_finish_oldest(net_t* net) { search_t* search; GList* dlist; if (!net->active_searches) return NULL; dlist = g_list_first(net->active_searches); search = dlist->data; search_finish(search, net, 1); return NULL; } search_t* search_finish_latest(net_t* net) { search_t* search; GList* dlist; if (!net->active_searches) return NULL; dlist = g_list_last(net->active_searches); search = dlist->data; if (search_finish(search, net, 1)) return search; else return NULL; // search is not valid, so dont requeue } void search_pattern_visual_update(search_pattern_t* pattern) { GtkCList* clist; int row; clist = GTK_CLIST(lookup_widget(global.win, "clist34")); row = gtk_clist_find_row_from_data(clist, pattern); if (row < 0) return; gtk_clist_set_text(clist, row, 0, pattern->name); strcpy(tstr[3], LifeTime(pattern->level)); gtk_clist_set_text(clist, row, 2, tstr[3]); if (pattern->level != PATTERN_TEMPLATE) return; search_pattern_update_template(pattern); } int search_pattern_rename_func(clist_rename_t* cr) { int row; search_pattern_t* pattern; if (!cr || !cr->new_text || !cr->data) return 0; row = gtk_clist_find_row_from_data(cr->clist, cr->data); if (row < 0) return 0; pattern = cr->data; if (pattern->name) g_free(pattern->name); pattern->name = g_strdup(cr->new_text); // gtk_clist_set_text(cr->clist, row, cr->col, pattern->name); search_pattern_visual_update(pattern); search_pattern_save(); return 1; } void search_pattern_rename(search_pattern_t* pattern) { GtkCList* clist; clist = GTK_CLIST(lookup_widget(global.win, "clist34")); if (!clist) return; clist_rename(clist, 0, search_pattern_rename_func, pattern, pattern->name); } search_t* search_find_id(int id) { GList* dlist; search_t* search; for (dlist = global.searches; dlist; dlist = dlist->next) { search = dlist->data; if (search->resume) continue; if (search->pattern->id == id) return search; } return NULL; } void search_pattern_search(search_pattern_t* pattern, net_t* net) { search_t *search; GtkNotebook* notebook; if (pattern->level == PATTERN_TEMPLATE) return; // first search for pattern id, if found do not create new search search = search_find_id(pattern->id); if (search) { notebook = GTK_NOTEBOOK(lookup_widget(global.win, "notebook5")); gtk_notebook_set_page(notebook, gtk_notebook_page_num(GTK_NOTEBOOK(notebook), GTK_WIDGET(search->link))); } else { search = search_new(); search->pattern = search_pattern_copy(pattern); search_create_page(search); } search_queue(search, net, 1); } void on_search_pattern_rename(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data) { search_pattern_rename((search_pattern_t*)user_data); } static void on_search_pattern_delete(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data ATTR_UNUSED) { GtkCList *clist; GList *row_list; search_pattern_t *pattern; int row; clist = GTK_CLIST(global.popup_list); row_list = clist->selection; gtk_clist_freeze(clist); while (row_list) { row = (int) row_list->data; row_list = row_list->next; pattern = gtk_clist_get_row_data(clist, row); gtk_clist_remove(clist, row); global.search_pattern = g_list_remove(global.search_pattern, pattern); if (pattern->level == PATTERN_TEMPLATE) { search_pattern_remove_template(pattern); } search_pattern_destroy(pattern); } gtk_clist_thaw(clist); search_pattern_save(); } void on_search_pattern_search(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data ATTR_UNUSED) { GtkCList *clist; GList *row_list; search_pattern_t *pattern; int row; clist = GTK_CLIST(global.popup_list); row_list = clist->selection; while (row_list) { row = (int) row_list->data; pattern = gtk_clist_get_row_data(clist, row); search_pattern_search(pattern, NULL); row_list = row_list->next; } } void on_search_pattern_search_all(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data ATTR_UNUSED) { GList *dlist; search_pattern_t *pattern; for (dlist = global.search_pattern; dlist; dlist = dlist->next) { pattern = dlist->data; search_pattern_search(pattern, NULL); } } void on_search_pattern_level(GtkMenuItem * menuitem ATTR_UNUSED, gpointer user_data) { GtkCList *clist; GList *row_list; search_pattern_t *pattern; int row; clist = GTK_CLIST(global.popup_list); row_list = clist->selection; while (row_list) { row = (int) row_list->data; pattern = gtk_clist_get_row_data(clist, row); pattern->level = (int)user_data; search_pattern_visual_update(pattern); row_list = row_list->next; } search_pattern_save(); } GtkWidget *create_search_pattern_popup(search_pattern_t *pattern) { GtkWidget *popup; GtkWidget *item; GtkWidget *item2; GtkWidget *item3; GtkAccelGroup *popup_accels; char item_str[1024]; int item_num; GtkCList* clist; GSList *level_group = NULL; if (!pattern) return NULL; popup = gtk_menu_new(); popup_accels = gtk_menu_ensure_uline_accel_group(GTK_MENU(popup)); clist = GTK_CLIST(global.popup_list); item_num = g_list_length(clist->selection); if (pattern->level != PATTERN_TEMPLATE) { if (item_num > 1) sprintf(item_str, "Search Selected (%d)", item_num); else strcpy(item_str, "Search"); item = gtk_menu_item_new_with_label(item_str); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_search_pattern_search), NULL); } item = gtk_menu_item_new_with_label("Search All"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_search_pattern_search_all), NULL); item = gtk_menu_item_new(); gtk_widget_show(item); gtk_widget_set_sensitive(item, FALSE); gtk_container_add(GTK_CONTAINER(popup), item); if (item_num > 1) sprintf(item_str, "Delete Selected (%d)", item_num); else strcpy(item_str, "Delete"); item = gtk_menu_item_new_with_label(item_str); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_search_pattern_delete), NULL); item = gtk_menu_item_new_with_label("Rename"); gtk_widget_show(item); gtk_container_add(GTK_CONTAINER(popup), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_search_pattern_rename), (gpointer)pattern); if (pattern->level != PATTERN_TEMPLATE) { item = gtk_menu_item_new(); gtk_widget_show(item); gtk_widget_set_sensitive(item, FALSE); gtk_container_add(GTK_CONTAINER(popup), item); item = gtk_radio_menu_item_new_with_label (level_group, LifeTime(PATTERN_TEMPORARY)); level_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item)); gtk_widget_show (item); gtk_container_add (GTK_CONTAINER (popup), item); if (pattern->level == PATTERN_TEMPORARY) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (item), TRUE); item2 = gtk_radio_menu_item_new_with_label (level_group, LifeTime(PATTERN_SAVE)); level_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item2)); gtk_widget_show (item2); gtk_container_add (GTK_CONTAINER (popup), item2); if (pattern->level == PATTERN_SAVE) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item2), TRUE); gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (item2), TRUE); item3 = gtk_radio_menu_item_new_with_label (level_group, LifeTime(PATTERN_SEARCH)); level_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item3)); gtk_widget_show (item3); gtk_container_add (GTK_CONTAINER (popup), item3); if (pattern->level == PATTERN_SEARCH) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item3), TRUE); gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (item3), TRUE); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(on_search_pattern_level), (gpointer)PATTERN_TEMPORARY); gtk_signal_connect(GTK_OBJECT(item2), "activate", GTK_SIGNAL_FUNC(on_search_pattern_level), (gpointer)PATTERN_SAVE); gtk_signal_connect(GTK_OBJECT(item3), "activate", GTK_SIGNAL_FUNC(on_search_pattern_level), (gpointer)PATTERN_SEARCH); } return popup; } void setup_search_fields() { int mp3; int template; char *text; GtkWidget *temp; if (!GTK_WIDGET_REALIZED(global.win)) return; temp = lookup_widget(global.win, "combo_entry17"); text = gtk_entry_get_text(GTK_ENTRY(temp)); if (!strcmp("mp3", text)) mp3 = 1; else mp3 = 0; temp = lookup_widget(global.win, "combo_entry28"); text = gtk_entry_get_text(GTK_ENTRY(temp)); if (!strcmp("Template", text)) template = 1; else template = 0; temp = lookup_widget(global.win, "entry128"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "entry130"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "combo11"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "search_bitrate2"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "combo12"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "search_frequency2"); gtk_widget_set_sensitive(temp, mp3); temp = lookup_widget(global.win, "button328"); temp = GTK_BIN(temp)->child; if (template) gtk_label_set_text(GTK_LABEL(temp), "Add Template"); else gtk_label_set_text(GTK_LABEL(temp), "Go!"); } void search_add_network(net_t* net) { GtkWidget* list; GtkCombo* combo; GtkWidget *li; if (!net) return; combo = GTK_COMBO(lookup_widget(global.win, "combo43")); list = combo->list; li = gtk_list_item_new_with_label ((gchar *) net->name); gtk_object_set_data(GTK_OBJECT(li), "data", net); gtk_widget_show (li); gtk_container_add (GTK_CONTAINER (list), li); } void search_remove_network(net_t* net) { GtkWidget* list; GtkCombo* combo; GtkWidget* child; GList* children; net_t* net2; combo = GTK_COMBO(lookup_widget(global.win, "combo43")); list = combo->list; children = GTK_LIST(list)->children; while (children) { child = children->data; children = children->next; net2 = gtk_object_get_data(GTK_OBJECT(child), "data"); if (net2 == net) { gtk_container_remove(GTK_CONTAINER(list), child); return; } } } GtkWidget* create_search_legend_menu (void) { GtkWidget *menu1; GtkAccelGroup *menu1_accels; GtkWidget *library1; GtkWidget *resume1; GtkWidget *normal1; GtkStyle * style; GdkColor white = {0, 65535, 65535, 65535}; menu1 = gtk_menu_new (); gtk_object_set_data (GTK_OBJECT (menu1), "menu1", menu1); menu1_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (menu1)); style = gtk_style_copy(gtk_widget_get_style(menu1)); style->bg[GTK_STATE_NORMAL] = white; style->bg[GTK_STATE_ACTIVE] = white; style->bg[GTK_STATE_PRELIGHT] = white; style->bg[GTK_STATE_SELECTED] = white; gtk_widget_set_style(menu1, style); normal1 = gtk_menu_item_new_with_label ("- Normal"); gtk_widget_show (normal1); gtk_container_add (GTK_CONTAINER (menu1), normal1); gtk_menu_item_right_justify (GTK_MENU_ITEM (normal1)); GTK_WIDGET_UNSET_FLAGS (normal1, GTK_SENSITIVE); style = gtk_style_copy(gtk_widget_get_style(GTK_BIN(normal1)->child)); style->fg[GTK_STATE_NORMAL] = normal_color; style->fg[GTK_STATE_ACTIVE] = normal_color; style->fg[GTK_STATE_PRELIGHT] = normal_color; style->fg[GTK_STATE_SELECTED] = normal_color; gtk_widget_set_style(GTK_BIN(normal1)->child, style); style = gtk_style_copy(gtk_widget_get_style(normal1)); style->bg[GTK_STATE_NORMAL] = white; style->bg[GTK_STATE_ACTIVE] = white; style->bg[GTK_STATE_PRELIGHT] = white; style->bg[GTK_STATE_SELECTED] = white; gtk_widget_set_style(normal1, style); library1 = gtk_menu_item_new_with_label ("- Already in library"); gtk_widget_show (library1); gtk_container_add (GTK_CONTAINER (menu1), library1); gtk_menu_item_right_justify (GTK_MENU_ITEM (library1)); GTK_WIDGET_UNSET_FLAGS (library1, GTK_SENSITIVE); style = gtk_style_copy(gtk_widget_get_style(GTK_BIN(library1)->child)); style->fg[GTK_STATE_NORMAL] = library_color; style->fg[GTK_STATE_ACTIVE] = library_color; style->fg[GTK_STATE_PRELIGHT] = library_color; style->fg[GTK_STATE_SELECTED] = library_color; gtk_widget_set_style(GTK_BIN(library1)->child, style); style = gtk_style_copy(gtk_widget_get_style(library1)); style->bg[GTK_STATE_NORMAL] = white; style->bg[GTK_STATE_ACTIVE] = white; style->bg[GTK_STATE_PRELIGHT] = white; style->bg[GTK_STATE_SELECTED] = white; gtk_widget_set_style(library1, style); resume1 = gtk_menu_item_new_with_label ("- Can be used for resume"); gtk_widget_show (resume1); gtk_container_add (GTK_CONTAINER (menu1), resume1); gtk_menu_item_right_justify (GTK_MENU_ITEM (resume1)); GTK_WIDGET_UNSET_FLAGS (resume1, GTK_SENSITIVE); style = gtk_style_copy(gtk_widget_get_style(GTK_BIN(resume1)->child)); style->fg[GTK_STATE_NORMAL] = resume_color; style->fg[GTK_STATE_ACTIVE] = resume_color; style->fg[GTK_STATE_PRELIGHT] = resume_color; style->fg[GTK_STATE_SELECTED] = resume_color; gtk_widget_set_style(GTK_BIN(resume1)->child, style); style = gtk_style_copy(gtk_widget_get_style(resume1)); style->bg[GTK_STATE_NORMAL] = white; style->bg[GTK_STATE_ACTIVE] = white; style->bg[GTK_STATE_PRELIGHT] = white; style->bg[GTK_STATE_SELECTED] = white; gtk_widget_set_style(resume1, style); return menu1; }