Пример #1
0
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);
	}
}
Пример #2
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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;	
}
Пример #6
0
/** 
 * 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;
}
Пример #7
0
/* 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;
}