It seems like the best I can do is just place "Send to specified playlist" at the top of the context menu. It's a bit mucky though, I'd prefer something else.
For what it's worth, I wrote a simple custom component with two functions for the context menu:
Send to Now Playing - clears the "Now Playing" playlist and sends the current selection to "Now Playing"
Append to Now Playing - adds the current selection to "Now Playing"
Nothing special, but it just makes it easier to manipulate the current playing selection in my config. Here is the code, if you are interested:
#include "../SDK/foobar2000.h"
#include "../helpers/helpers.h"
/*-----------------------------------------------
Providing information about a component.
Viewed under Preferences > Components.
-------------------------------------------------*/
DECLARE_COMPONENT_VERSION(
// component name
"Playlist Context Menu Helpers",
// component version
"0.1.3",
// about text, use \n to separate multiple lines
// If you don't want any about text, set this parameter to NULL.
"Context menu playlist helpers\n"
"for foobar2000 v0.9\n"
"\n"
"contributors:\n"
"John Bell\n")
/*-----------------------------------------------
Component initialize and release
on_init is called after main window has been created,
on_quit is called before main window is destroyed
-------------------------------------------------*/
class initquit_foo_playlist_helpers : public initquit {
virtual void on_init()
{
// foobar2000 has a 'playing' playlist and an 'active' playlist
// force the playing playlist to "Now Playing"
static_api_ptr_t<playlist_manager> pm;
pfc::string8 playlist("Now Playing");
t_size play_ndx = pm->find_playlist(playlist, playlist.length());
pm->set_playing_playlist(play_ndx);
//pm->playback_order_set_active(0); //resets the order to start at the top
}
//virtual void on_quit() {}
};
static initquit_factory_t< initquit_foo_playlist_helpers > foo_initquit;
/*-----------------------------------------------
Context menu item implementations
-------------------------------------------------*/
class contextmenu_commands_foo_playlist_helpers : public contextmenu_item_simple
{
enum menu_index {
mnuSendToNowPlaying,
mnuAppendToNowPlaying
};
virtual unsigned get_num_items() {
return 2;
}
virtual GUID get_item_guid(unsigned p_index) {
static const GUID guid_context_send_to_now_playing = { 0xd3499f7c, 0xebf3, 0x4d98, { 0x94, 0xaf, 0x36, 0x5a, 0x95, 0x5d, 0x12, 0x2c } };
static const GUID guid_context_append_to_now_playing = { 0x6afbf8c0, 0x828f, 0x4d06, { 0xa4, 0x96, 0xa2, 0x39, 0x76, 0xe8, 0x6b, 0x8e } };
if( p_index == mnuSendToNowPlaying )
return guid_context_send_to_now_playing;
else if( p_index == mnuAppendToNowPlaying )
return guid_context_append_to_now_playing;
return pfc::guid_null;
}
virtual void get_item_name(unsigned p_index,pfc::string_base& p_out) {
if( p_index == mnuSendToNowPlaying )
p_out = "Send to Now Playing";
else if( p_index == mnuAppendToNowPlaying )
p_out = "Append to Now Playing";
}
virtual void get_item_default_path(unsigned p_index,pfc::string_base& p_out) {
if( p_index == mnuSendToNowPlaying )
p_out = "";
else if( p_index == mnuAppendToNowPlaying )
p_out = "";
}
virtual bool get_item_description(unsigned p_index,pfc::string_base& p_out) {
if( p_index == mnuSendToNowPlaying ) {
p_out = "Clears the Now Playing playlist and then sends the selected item(s) to the Now Playing playlist";
return true;
}
else if( p_index == mnuAppendToNowPlaying ) {
p_out = "Appends item(s) to the Now Playing playlist";
return true;
}
return false;
}
virtual void context_command(unsigned p_index,const pfc::list_base_const_t<metadb_handle_ptr>& p_data,const GUID& p_caller) {
if( core_api::assert_main_thread() )
{
if( p_index == mnuSendToNowPlaying || p_index == mnuAppendToNowPlaying )
{
static_api_ptr_t<playlist_manager> pm;
pfc::string8 playlist("Browser");
t_size browser_ndx = pm->find_playlist(playlist, playlist.length());
playlist = "Now Playing";
t_size play_ndx = pm->find_playlist(playlist, playlist.length());
metadb_handle_list list;
pm->playlist_get_selected_items(browser_ndx, list);
if( p_index == mnuSendToNowPlaying ) {
pm->set_playing_playlist(play_ndx);
pm->playlist_clear(play_ndx);
}
pm->playlist_add_items(play_ndx, list, bit_array_false());
}
}
}
};
// We need to create a service factory for our menu item class,
// otherwise the menu commands won't be known to the system.
static contextmenu_item_factory_t< contextmenu_commands_foo_playlist_helpers > foo_menu;
Since you use the playist tree component to make your selections this code will not work for you, I think. I'm offering it for others that may be browsing this post, and for you, you might be able to tweak it to work with the playlist tree component, I don't know.
I can upload the compiled dll if you want but I would recommend compiling it yourself for a couple reasons:
0) It's simple to do, thanks to foobar's extremely well designed API and published base projects.
1) This code hard codes the browser playlist to "Browser" and the now playing playlist to "Now Playing", so you'll have to setup your config accordingly. Also, it sets the playing playlist to the "Now Playing" playlist when foobar2000 starts up, which may not be what you want.
2) I have no intention of actively supporting this as a bona fide component, not only do I not have the time, but by the nature of this type of component (a Playlist Helpers component), every config would want something different.
3) It gives you a simple template to add any other customizations you want.