static void play_command(gpointer user_data, const char *param) { MpdData *data = advanced_search(param, TRUE); if (data) { play_path(data->song->file); mpd_data_free(data); } }
static gboolean serverstats_idle_handler(ss_str * s) { GtkTreeIter iter; MpdDBStats *stats = NULL; if (s->data == NULL || !mpd_check_connected(connection) || cancel_query) { if (gtk_tree_model_get_iter_first(s->model, &iter)) { do { guint d; gulong i; gchar *value = NULL; gtk_tree_model_get(s->model, &iter, 0, &i, -1); d = (guint) 100 *(i / (double)s->max_i); value = format_time_real(i, ""); gtk_list_store_set(GTK_LIST_STORE(s->model), &iter, 2, d, 3, value, -1); g_free(value); } while (gtk_tree_model_iter_next(s->model, &iter)); } if (s->data) mpd_data_free(s->data); gtk_tree_view_set_model(GTK_TREE_VIEW(serverstats_tree), s->model); gtk_tree_view_set_search_column(GTK_TREE_VIEW(serverstats_tree), 1); gtk_widget_set_sensitive(GTK_WIDGET(s->box), TRUE); gtk_widget_hide(gtk_widget_get_parent(s->pb)); if (cancel_query) gtk_list_store_clear(GTK_LIST_STORE(s->model)); g_free(s); cancel_query = FALSE; return FALSE; } mpd_database_search_stats_start(connection); mpd_database_search_add_constraint(connection, s->tag, s->data->tag); stats = mpd_database_search_stats_commit(connection); if (stats) { gtk_list_store_prepend(GTK_LIST_STORE(s->model), &iter); gtk_list_store_set(GTK_LIST_STORE(s->model), &iter, 0, (unsigned long)(stats->playTime), 1, s->data->tag, -1); s->max_i = MAX(s->max_i, stats->playTime); mpd_database_search_free_stats(stats); } /* limit the amount of updating to 0.2 % */ if ((int)((1000 * s->hits) / s->total) % 5 == 0) { gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(s->pb), s->hits / (double)s->total); } s->hits++; s->data = mpd_data_get_next(s->data); return TRUE; }
MpdData * mpd_playlist_get_changes_posid(MpdObj *mi,int old_playlist_id) { MpdData *data = NULL; mpd_InfoEntity *ent = NULL; debug_printf(DEBUG_INFO, "Fetching using new plchangesposid command"); if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_WARNING,"lock failed\n"); return NULL; } if(old_playlist_id == -1) { debug_printf(DEBUG_INFO,"get fresh playlist\n"); mpd_sendPlChangesPosIdCommand (mi->connection, 0); /* mpd_sendPlaylistIdCommand(mi->connection, -1); */ } else { mpd_sendPlChangesPosIdCommand (mi->connection, old_playlist_id); } while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if(ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* unlock */ if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_WARNING,"mpd_playlist_get_changes: unlock failed.\n"); mpd_data_free(data); return NULL; } if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
MpdData * mpd_playlist_search_commit(MpdObj *mi) { mpd_InfoEntity *ent = NULL; MpdData *data = NULL; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_WARNING,"not connected\n"); return NULL; } if(mi->search_type < MPD_SEARCH_TYPE_PLAYLIST_FIND ) { debug_printf(DEBUG_ERROR, "no or wrong search in progress to commit"); return NULL; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return NULL; } mpd_commitSearch(mi->connection); while (( ent = mpd_getNextInfoEntity(mi->connection)) != NULL) { if(ent->type == MPD_INFO_ENTITY_TYPE_SONG) { data = mpd_new_data_struct_append(data); data->type = MPD_DATA_TYPE_SONG; data->song = ent->info.song; ent->info.song = NULL; } mpd_freeInfoEntity(ent); } mpd_finishCommand(mi->connection); /* * reset search type */ mi->search_type = MPD_SEARCH_TYPE_NONE; mi->search_field = MPD_TAG_ITEM_ARTIST; /* unlock */ if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock connection"); if(data)mpd_data_free(data); return NULL; } if(data == NULL) { return NULL; } return mpd_data_get_first(data); }
MpdData * mpd_data_get_next_real(MpdData * const data, int kill_list) { MpdData_real *data_real = (MpdData_real*)data; if (data_real != NULL) { if (data_real->next != NULL ) { return (MpdData*)data_real->next; } else { if (kill_list) mpd_data_free((MpdData*)data_real); return NULL; } } return (MpdData*)data_real; }
/** * Deletes an item from the list. It returns the next item in the list. * if that is not available, it will return the last item */ MpdData * mpd_data_delete_item(MpdData *data) { MpdData_real *temp = NULL, *data_real = (MpdData_real*)data; if(data_real == NULL) return NULL; /* if there is a next item, fix the prev pointer of the next item */ if (data_real->next) { data_real->next->prev = data_real->prev; temp = data_real->next; } /* if there is a previous item, fix the next pointer of the previous item */ if (data_real->prev) { /* the next item of the previous is the next item of the current */ data_real->prev->next = data_real->next; /* temp is the previous item */ temp = data_real->prev; } /* fix first, if removed item is the first */ if(temp && temp->first == data_real) { MpdData_real *first,*node = temp; /* get first */ for(;node->prev;node = node->prev); first = node; while(node){ node->first = first; node = node->next; } } /* make the removed row a valid list, so I can use the default free function to free it */ data_real->next = NULL; data_real->prev = NULL; data_real->first = data_real; /* free it */ mpd_data_free((MpdData *)data_real); return (MpdData *)temp; }
/* searches in the mpd database for a given string and outputs the result (data contains a GtkEntry and a GtkWindow)*/ static void mpd_search(GtkWidget *widget, gpointer data) { GList *args,*vbox_content,*argument_list; gpointer list_data; GtkWidget *vbox, *entry, *label, *result_tree_view, *add_button, *scrolled_window, *window; GtkBox *box; GtkBoxChild *child; const gchar *entry_string; gchar *search_string; GtkListStore *list_store; GtkTreeSelection *tree_selection; GtkObject *h_adjustment, *v_adjustment; MpdData *result, *res_ptr; int result_count = 0; int i = 0; GList *song_handle_list; MpdPlContainer *result_list; args = (GList *)data; /* remove old results, if any */ vbox = g_list_nth_data(args, 1); box = GTK_BOX(vbox); vbox_content = box->children; list_data = g_list_nth_data(vbox_content, 4); if(list_data != NULL) { child = list_data; gtk_widget_destroy(child->widget); } list_data = g_list_nth_data(vbox_content, 3); if(list_data != NULL) { child = list_data; gtk_widget_destroy(child->widget); } if(debug) { fprintf(log_file, "[%s:%3i] %s(): Type = %i\n", __FILE__, __LINE__, __FUNCTION__, search_type); fflush(log_file); } /* search for the typed string */ entry = g_list_nth_data(args, 0); entry_string = gtk_entry_get_text(GTK_ENTRY(entry)); search_string = g_strdup(entry_string); /* table ^= search_type */ if(!mpd_check_connected(mpd_info.obj)) { if(mpd_connect(mpd_info.obj)!=MPD_OK) { msi_clear(&mpd_info); mpd_info.msi.connected = FALSE; return; } msi_fill(&mpd_info); mpd_info.msi.connected = TRUE; } /* * Last argument: TRUE -> only exact matches * FALSE -> more matches */ result = mpd_database_find(mpd_info.obj, search_type, search_string, FALSE); /* Iterate through the found songs, using * the function mpd_data_get_next_keep(md), which * calls mpd_data_get_next_real(md,FALSE) which * prevents the list being killed when reaching * the end. */ for( res_ptr = mpd_data_get_first(result); res_ptr != NULL; res_ptr = mpd_data_get_next_keep(res_ptr) ) { /* count only songs ... */ if(res_ptr->type == MPD_DATA_TYPE_SONG) ++result_count; } /* no matches */ if(result_count == 0) { label = gtk_label_new("No songs found!"); gtk_box_pack_end_defaults(GTK_BOX(vbox), label); gtk_widget_show(label); } /* output found songs */ else { song_handle_list = NULL; result_list = mpd_pl_container_new_alloc(result_count); //mpd_Song *result_list[result_count]; /* as above: the song info is still needed, as * the mpd_Song objects are *not* copied into the * result list */ for( res_ptr = mpd_data_get_first(result); res_ptr != NULL; res_ptr = mpd_data_get_next_keep(res_ptr) ) { /* only songs */ if(res_ptr->type == MPD_DATA_TYPE_SONG) { result_list->list[i++] = mpd_songDup(res_ptr->song); song_handle_list = g_list_append(song_handle_list, strdup(res_ptr->song->file)); } } list_store = pl_create_list_store(result_list); mpd_pl_container_free(result_list); result_tree_view = pl_create_tree_view(GTK_TREE_MODEL(list_store)); /* create a facility to select only some of the found songs for adding...*/ tree_selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(result_tree_view)); gtk_tree_selection_set_mode(tree_selection, GTK_SELECTION_MULTIPLE); /**********/ argument_list = NULL; argument_list = g_list_append(argument_list, song_handle_list); argument_list = g_list_append(argument_list, tree_selection); add_button = gtk_button_new_with_label("add selected songs"); g_signal_connect(GTK_BUTTON(add_button), "clicked", G_CALLBACK(mpd_add_song_list), argument_list); /* g_signal_connect_swapped(GTK_BUTTON(add_button), "clicked", G_CALLBACK(gtk_widget_destroy), g_list_nth_data(data, 2)); */ gtk_box_pack_end(GTK_BOX(vbox), add_button,FALSE,FALSE,0); /* put a scrolled window in between the treeview and the window... */ /* I just don't know how this works exactly, but the result is acceptable, so why bother */ h_adjustment = gtk_adjustment_new(0, 0, 4, 1, 4, 4); v_adjustment = gtk_adjustment_new(0, 0, 20, 1, 20, 20); scrolled_window = gtk_scrolled_window_new(GTK_ADJUSTMENT(h_adjustment), GTK_ADJUSTMENT(v_adjustment)); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE); /* display scrollbars only when needed */ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(scrolled_window), result_tree_view); gtk_box_pack_end_defaults(GTK_BOX(vbox), scrolled_window); gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE); gtk_widget_show_all(scrolled_window); gtk_widget_show_all(add_button); window = g_list_nth_data(args, 2); gtk_window_resize(GTK_WINDOW(window), 700, 500); } /* delete search result, have to do this ourselves * because we needed the song data until now */ mpd_data_free(result); return; }