├── .gitignore ├── COPYING.txt ├── README.md ├── common ├── generic_menu.h ├── menu_stuff.h ├── string_functions.h └── titleformatting_variable_callback.h ├── foo_browser ├── foo_browser.cpp ├── foo_browser.rc ├── foo_browser.vcproj └── resource.h ├── foo_cwb_hooks ├── checkstates.bmp ├── foo_cwb_hooks.cpp ├── foo_cwb_hooks.rc ├── foo_cwb_hooks.vcproj ├── foo_new_file_stamper.cpp ├── foo_uie_tagger.cpp ├── new_file_stamper.h ├── resource.h └── timestamp_action.h ├── foo_cwbowron ├── foo_cwbowron.cpp ├── foo_cwbowron.rc ├── foo_cwbowron.vcproj └── resource.h ├── foo_dock ├── buffer_reader.h ├── dock_preferences.h ├── foo_dock.cpp ├── foo_dock.rc ├── foo_dock.vcproj └── resource.h ├── foo_notitlebar ├── foo_notitlebar.cpp └── foo_notitlebar.vcproj ├── foo_playlist_tree ├── bitmap1.bmp ├── foo_playlist_tree.rc ├── foo_playlist_tree.vcproj ├── foo_ui_playlist_tree.cpp ├── guids.h ├── mainmenu.h ├── node.h ├── playlist_tree.txt ├── playlist_tree_scheme.h ├── preferences.h ├── query_node.h ├── readme.txt ├── resource.h ├── sexp_reader.h ├── trackfinder.h ├── tree_drop_source.h ├── tree_drop_target.h └── tree_search.h ├── foo_sendtodevice ├── foo_sendtodevice.rc ├── foo_sendtodevice.vcproj ├── main.cpp └── resource.h ├── foo_tcp_interface ├── foo_network_server.cpp ├── foo_tcp_interface.rc ├── foo_tcp_interface.vcproj └── resource.h ├── foo_trackfinder ├── foo_trackfinder.rc ├── foo_trackfinder.vcproj ├── resource.h └── trackfinder.cpp └── lib ├── libmzgc360_000.lib └── libmzsch360_000.lib /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | 9 | # Compiled Static libraries 10 | *.lai 11 | *.la 12 | *.a 13 | -------------------------------------------------------------------------------- /COPYING.txt: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2012 Christopher Bowron 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | foobar2000-plugins 2 | ================== -------------------------------------------------------------------------------- /common/generic_menu.h: -------------------------------------------------------------------------------- 1 | 2 | class generic_group : public mainmenu_group_popup 3 | { 4 | public: 5 | GUID m_guid; 6 | GUID m_parent; 7 | const char * m_name; 8 | unsigned m_priority; 9 | 10 | generic_group( const char * name, GUID guid, GUID parent, unsigned priority = mainmenu_commands::sort_priority_dontcare ) 11 | { 12 | m_guid = guid; 13 | m_parent = parent; 14 | m_name = name; 15 | m_priority = priority; 16 | } 17 | 18 | virtual GUID get_guid() { return m_guid; } 19 | virtual GUID get_parent() { return m_parent; } 20 | virtual t_uint32 get_sort_priority() { return m_priority; } 21 | virtual void get_display_string(pfc::string_base & p_out) { p_out.set_string( m_name ); } 22 | }; 23 | -------------------------------------------------------------------------------- /common/string_functions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef META_QUERY_START 4 | #define META_QUERY_START "%<" 5 | #define META_QUERY_STOP ">%" 6 | #endif 7 | 8 | bool string_get_function_param( pfc::string_base & out, const char *in, const char *tag, int *first = NULL, int *last = NULL ); 9 | 10 | 11 | static void string_split( const char *in, const char *delim, pfc::ptr_list_t & out ) 12 | { 13 | pfc::string8 str = in; 14 | t_size start = 0; 15 | int count = 0; 16 | int pos; 17 | 18 | start = 0; 19 | count = 0; 20 | 21 | while ( ( pos = str.find_first( delim, start ) ) >=0 ) 22 | { 23 | pfc::string8 *blip = new pfc::string8( str.get_ptr() + start, pos - start ); 24 | count ++; 25 | start = pos + strlen( delim ); 26 | out.add_item( blip ); 27 | } 28 | 29 | pfc::string8 *last = new pfc::string8( str.get_ptr() + start ); 30 | out.add_item( last ); 31 | } 32 | 33 | static int string_replace( pfc::string_base & out, const char * in, int start, int end, const char * replacement ) 34 | { 35 | out.reset(); 36 | 37 | int max = strlen( in ); 38 | int n; 39 | 40 | if ( start > max ) start = max; 41 | 42 | for ( n = 0; n < start; n++ ) 43 | { 44 | out.add_byte( in[n] ); 45 | } 46 | 47 | out.add_string( replacement ); 48 | 49 | for ( n = end; n < max; n++ ) 50 | { 51 | out.add_byte( in[n] ); 52 | } 53 | return true; 54 | } 55 | 56 | static int string_replace( pfc::string_base & out, 57 | const char * in, 58 | const char * replaceme, 59 | const char * withme, 60 | int start = 0 ) 61 | { 62 | const char * first = strstr( in + start, replaceme ); 63 | 64 | if ( first ) 65 | { 66 | out.set_string( in, first - in ); 67 | out.add_string( withme ); 68 | out.add_string( first + strlen( replaceme ) ); 69 | return first - in + strlen( withme ); 70 | } 71 | else 72 | { 73 | out.set_string( in ); 74 | return -1; 75 | } 76 | } 77 | 78 | 79 | static bool string_remove_tag_simple( pfc::string_base & out, const char * in, const char * tag ) 80 | { 81 | return ( string_replace( out, in, tag, "" ) != -1 ); 82 | } 83 | 84 | static bool string_remove_tag_complex( pfc::string_base & out, const char * in, const char * tag ) 85 | { 86 | int start,end; 87 | pfc::string8 blip; 88 | 89 | if ( string_get_function_param( blip, in, tag, &start, &end ) ) 90 | { 91 | string_replace( out, in, start, end+1, "" ); 92 | return true; 93 | } 94 | else 95 | { 96 | return false; 97 | } 98 | } 99 | 100 | static int find_close_paren( const char * str, int start ) 101 | { 102 | const char delimit_open = '<'; 103 | const char delimit_clse = '>'; 104 | 105 | int i; 106 | int paren_total = 0; 107 | 108 | int len = strlen( str ); 109 | 110 | for ( i = start; start < len; i++ ) 111 | { 112 | if ( str[i] == 0 ) 113 | break; 114 | 115 | if ( str[i] == delimit_open ) 116 | { 117 | paren_total++; 118 | } 119 | 120 | if ( str[i] == delimit_clse ) 121 | { 122 | paren_total--; 123 | if ( paren_total < 0 ) 124 | return i; 125 | } 126 | } 127 | return -1; 128 | } 129 | 130 | static bool string_substr( pfc::string_base & out, const char * in, int start, int end = ~0 ) 131 | { 132 | if ( end == ~0 ) 133 | { 134 | out.set_string( in + start, end ); 135 | } 136 | else 137 | { 138 | out.set_string( in + start, end - start ); 139 | } 140 | return true; 141 | } 142 | 143 | static bool string_get_function_param( 144 | pfc::string_base & out, 145 | const char *in, 146 | const char *tag, 147 | int *first , 148 | int *last ) 149 | { 150 | const char *start_ptr = strstr( in, tag ); 151 | 152 | if ( !start_ptr ) 153 | return false; 154 | 155 | int start = start_ptr - in; 156 | 157 | int l_paren = start + strlen( tag ) + 1; 158 | 159 | int r_paren = find_close_paren( in, l_paren ); 160 | 161 | if ( r_paren < 0 ) 162 | { 163 | console::printf("Unbalanced Parenthesis '%s' [string_sub::get_function_param]", in ); 164 | return 0; 165 | } 166 | 167 | string_substr( out, in, l_paren, r_paren ); 168 | 169 | if ( first ) 170 | *first = start; 171 | if ( last ) 172 | *last = r_paren; 173 | 174 | return 1; 175 | } 176 | 177 | static pfc::string8 quoted_string( const char * input ) 178 | { 179 | if ( strlen( input ) == 0 ) 180 | { 181 | return "nil"; 182 | } 183 | else 184 | { 185 | pfc::string8 result = "\""; 186 | 187 | int n, m = strlen( input ); 188 | for ( n = 0; n < m; n++) 189 | { 190 | if ( input[n] == '\"' ) 191 | { 192 | result.add_string( "\"\"" ); 193 | } 194 | else 195 | { 196 | result.add_byte( input[n] ); 197 | } 198 | } 199 | 200 | result.add_char( '\"' ); 201 | return result; 202 | } 203 | } 204 | 205 | static bool string_make_format_friendly( pfc::string_base & out, const char * in ) 206 | { 207 | bool affected = false; 208 | static const char replaced_characters[] = "'$%[]()@"; 209 | 210 | int i = 0; 211 | int in_length = strlen( in ); 212 | 213 | out.reset(); 214 | 215 | for ( i = 0; i < in_length; i++ ) 216 | { 217 | if ( strchr( replaced_characters, in[i] ) ) 218 | { 219 | affected = true; 220 | out.add_string( pfc::string_printf( "$char(%d)", in[i] ) ); 221 | } 222 | else 223 | { 224 | out.add_byte( in[i] ); 225 | } 226 | } 227 | 228 | return affected; 229 | } 230 | 231 | 232 | // returns index of next character after replacement or -1 if no replacement 233 | class query_ready_string : public pfc::string8 234 | { 235 | public: 236 | query_ready_string() : pfc::string8() 237 | { 238 | } 239 | 240 | query_ready_string( const char * in ) : pfc::string8() 241 | { 242 | convert( in ); 243 | } 244 | 245 | void convert( const char * in ) 246 | { 247 | pfc::string8_fastalloc tmp( in ); 248 | 249 | if ( tmp[tmp.get_length()-1] != '|' ) 250 | { 251 | tmp.add_byte( '|' ); 252 | } 253 | 254 | while ( string_replace( *this, tmp, "||", "|" ) >= 0 ) 255 | { 256 | tmp.set_string( get_ptr() ); 257 | } 258 | 259 | int n; 260 | int m = length(); 261 | 262 | for ( n = 0; n < m; n++ ) 263 | { 264 | if ( m_data[n] == '|' ) 265 | m_data[n] = '\0'; 266 | } 267 | } 268 | }; 269 | 270 | static bool has_tags( const char * s ) 271 | { 272 | if ( strstr( s, "%" ) ) 273 | return true; 274 | if ( strstr( s, "$" ) ) 275 | return true; 276 | return false; 277 | } 278 | 279 | static bool generate_meta_query_strings( pfc::string_base & in, metadb_handle_ptr handle, pfc::ptr_list_t & strings, bool add_if_empty = false ) 280 | { 281 | if ( !strstr ( in, META_QUERY_START ) ) 282 | { 283 | strings.add_item( new pfc::string8( in ) ); 284 | return false; 285 | } 286 | else 287 | { 288 | int s = in.find_first( META_QUERY_START ); 289 | int e = in.find_first( META_QUERY_STOP ); 290 | 291 | if ( s == infinite || e == infinite ) 292 | { 293 | return false; 294 | } 295 | else 296 | { 297 | pfc::string8_fastalloc t2; 298 | pfc::string8_fastalloc t1; 299 | 300 | string_substr( t1, in, s + strlen(META_QUERY_START), e ); 301 | 302 | if ( strstr( t1, "," ) ) 303 | { 304 | pfc::ptr_list_t tags; 305 | 306 | string_split( t1, ",", tags ); 307 | 308 | bool res = false; 309 | for ( int tag_index = 0; tag_index < tags.get_count(); tag_index++ ) 310 | { 311 | string_replace( t2, in, s, e + 2, 312 | pfc::string_printf( "%s%s%s", 313 | META_QUERY_START, 314 | tags[tag_index]->get_ptr(), 315 | META_QUERY_STOP ) ); 316 | 317 | if ( generate_meta_query_strings( t2, handle, strings, add_if_empty ) ) 318 | { 319 | res = true; 320 | } 321 | } 322 | return res; 323 | } 324 | else 325 | { 326 | //const file_info * info; 327 | file_info_impl info; 328 | 329 | handle->get_info( info ); 330 | //handle->get_info_locked( info ); 331 | 332 | bool res = false; 333 | 334 | int tag_index = info.meta_find( t1 ); 335 | 336 | if ( add_if_empty || tag_index != infinite ) 337 | { 338 | int max_meta; 339 | if ( tag_index != infinite ) 340 | { 341 | res = true; 342 | max_meta = info.meta_enum_value_count( tag_index ); 343 | } 344 | else 345 | { 346 | max_meta = 1; 347 | } 348 | 349 | for ( int meta_index = 0; meta_index < max_meta; meta_index++ ) 350 | { 351 | /* 352 | string_replace( t2, in, s, e + 2, 353 | info.meta_enum_value( tag_index, meta_index ) ); 354 | */ 355 | string_replace( t2, in, s, e+2, 356 | pfc::string_printf( "$meta(%s,%d)", (const char *)t1, meta_index ) ); 357 | 358 | generate_meta_query_strings( t2, handle, strings, add_if_empty ); 359 | } 360 | } 361 | 362 | return res; 363 | } 364 | } 365 | } 366 | } 367 | -------------------------------------------------------------------------------- /common/titleformatting_variable_callback.h: -------------------------------------------------------------------------------- 1 | class NOVTABLE titleformatting_variable_callback : public service_base 2 | { 3 | public: 4 | virtual void on_var_change( const char * var ) = 0; 5 | 6 | FB2K_MAKE_SERVICE_INTERFACE_ENTRYPOINT(titleformatting_variable_callback); 7 | }; 8 | 9 | const GUID titleformatting_variable_callback::class_guid = 10 | { 0xfcb81645, 0xe7b2, 0x4bc1, { 0x92, 0xb0, 0xf6, 0xfb, 0x4b, 0x43, 0x70, 0xe3 } }; 11 | 12 | class var_notify_callback : public main_thread_callback 13 | { 14 | pfc::string8_fastalloc m_var; 15 | 16 | public: 17 | var_notify_callback( const char * var ) : main_thread_callback() 18 | { 19 | m_var = var; 20 | } 21 | 22 | void callback_run() 23 | { 24 | service_enum_t e; 25 | service_ptr_t ptr; 26 | while( e.next( ptr ) ) 27 | { 28 | ptr->on_var_change( m_var ); 29 | } 30 | } 31 | }; 32 | 33 | void post_variable_callback_notification( const char * str ) 34 | { 35 | if ( core_api::are_services_available() && !core_api::is_initializing() && !core_api::is_shutting_down() ) 36 | // if ( false ) 37 | { 38 | service_ptr_t p_callback = new service_impl_t( str ); 39 | static_api_ptr_t man; 40 | man->add_callback( p_callback ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /foo_browser/foo_browser.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_BLANK DIALOGEX 0, 0, 186, 90 56 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 57 | EXSTYLE WS_EX_CONTROLPARENT 58 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 59 | BEGIN 60 | END 61 | 62 | IDD_CONFIG DIALOGEX 0, 0, 327, 315 63 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 64 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 65 | BEGIN 66 | PUSHBUTTON "Text Color",IDC_BUTTON_TEXT_COLOR,11,174,44,12 67 | PUSHBUTTON "Bkgnd Color",IDC_BUTTON_BACKGROUND_COLOR,59,174,44,12 68 | GROUPBOX "Panels",IDC_STATIC,7,3,318,90 69 | GROUPBOX "Appearance",IDC_STATIC,7,165,318,67 70 | GROUPBOX "Browser Playlist",IDC_STATIC,7,94,318,38 71 | EDITTEXT IDC_PLAYLIST,10,104,310,12,ES_AUTOHSCROLL 72 | CONTROL "Automatically Activate",IDC_AUTO_ACTIVATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,119,89,9 73 | PUSHBUTTON "Font",IDC_BUTTON_FONT,108,175,44,12 74 | GROUPBOX "Double Click Action",IDC_STATIC,7,134,318,31 75 | COMBOBOX IDC_DOUBLE_CLICK,10,144,310,88,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 76 | CONTROL "Hide Horizontal Scrollbar",IDC_SCROLLBAR_MAGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,193,114,10 77 | GROUPBOX "Edge Style",IDC_STATIC,187,170,135,26 78 | COMBOBOX IDC_EDGE_STYLE,194,179,123,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 79 | CONTROL "Hide Column Headers",IDC_HIDE_HEADERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,205,84,10 80 | CONTROL "Replace Previous Playlist With New Playlist",IDC_REPLACE_LAST, 81 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,119,164,10 82 | CONTROL "Custom Selection Colors:",IDC_CUSTOM_COLORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,217,91,8 83 | PUSHBUTTON "Hilite Color (Focus)",IDC_COLOR_SELECTION,113,209,80,11 84 | PUSHBUTTON "Hilite Color (Non-Focus)",IDC_COLOR_SELECTIONNONFOCUS,113,220,80,11 85 | PUSHBUTTON "Text Color (Focus)",IDC_COLOR_SEL_TEXT,196,209,80,11 86 | PUSHBUTTON "Text Color (Non-Focus)",IDC_COLOR_SEL_TEXT_NON,196,220,80,11 87 | CONTROL "Populate browsers on startup",IDC_POPULATE_ON_STARTUP, 88 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,233,111,10 89 | PUSHBUTTON "Edit",IDC_BUTTON_EDIT,237,15,50,14 90 | PUSHBUTTON "Add",IDC_BUTTON_ADD,237,32,50,14 91 | PUSHBUTTON "Remove",IDC_BUTTON_REMOVE,238,49,50,14 92 | CONTROL "",IDC_LIST_PANELS,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,10,15,223,73 93 | CONTROL "Populate playlist on startup",IDC_POPULATE_PLAYLIST_ON_STARTUP, 94 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,245,103,10 95 | CONTROL "Show item counts in [All]",IDC_SHOW_ITEMCOUNTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,257,94,10 96 | CONTROL "Show [All]",IDC_SHOWALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,269,48,10 97 | END 98 | 99 | IDD_PANEL_SETUP DIALOGEX 0, 0, 334, 95 100 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 101 | CAPTION "Panel Setup" 102 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 103 | BEGIN 104 | DEFPUSHBUTTON "OK",IDOK,115,74,50,14 105 | PUSHBUTTON "Cancel",IDCANCEL,169,74,50,14 106 | EDITTEXT IDC_EDIT_LABEL,50,7,277,14,ES_AUTOHSCROLL 107 | EDITTEXT IDC_EDIT_FORMAT,50,24,277,14,ES_AUTOHSCROLL 108 | EDITTEXT IDC_EDIT_SORT,50,41,277,14,ES_AUTOHSCROLL 109 | LTEXT "Label:",IDC_STATIC,27,11,20,8 110 | LTEXT "Format:",IDC_STATIC,21,27,26,8 111 | LTEXT "Sort:",IDC_STATIC,30,44,17,8 112 | COMBOBOX IDC_COMBO_PREC,50,59,48,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 113 | LTEXT "Precedence:",IDC_STATIC,6,61,41,8 114 | END 115 | 116 | 117 | ///////////////////////////////////////////////////////////////////////////// 118 | // 119 | // DESIGNINFO 120 | // 121 | 122 | #ifdef APSTUDIO_INVOKED 123 | GUIDELINES DESIGNINFO 124 | BEGIN 125 | IDD_BLANK, DIALOG 126 | BEGIN 127 | LEFTMARGIN, 7 128 | RIGHTMARGIN, 179 129 | TOPMARGIN, 7 130 | BOTTOMMARGIN, 83 131 | END 132 | 133 | IDD_CONFIG, DIALOG 134 | BEGIN 135 | LEFTMARGIN, 7 136 | RIGHTMARGIN, 325 137 | VERTGUIDE, 10 138 | VERTGUIDE, 36 139 | VERTGUIDE, 85 140 | VERTGUIDE, 86 141 | VERTGUIDE, 188 142 | VERTGUIDE, 190 143 | VERTGUIDE, 320 144 | TOPMARGIN, 7 145 | BOTTOMMARGIN, 305 146 | END 147 | 148 | IDD_PANEL_SETUP, DIALOG 149 | BEGIN 150 | LEFTMARGIN, 7 151 | RIGHTMARGIN, 327 152 | VERTGUIDE, 50 153 | TOPMARGIN, 7 154 | BOTTOMMARGIN, 88 155 | END 156 | END 157 | #endif // APSTUDIO_INVOKED 158 | 159 | #endif // English (U.S.) resources 160 | ///////////////////////////////////////////////////////////////////////////// 161 | 162 | 163 | 164 | #ifndef APSTUDIO_INVOKED 165 | ///////////////////////////////////////////////////////////////////////////// 166 | // 167 | // Generated from the TEXTINCLUDE 3 resource. 168 | // 169 | 170 | 171 | ///////////////////////////////////////////////////////////////////////////// 172 | #endif // not APSTUDIO_INVOKED 173 | 174 | -------------------------------------------------------------------------------- /foo_browser/foo_browser.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 55 | 58 | 61 | 64 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 99 | 100 | 109 | 112 | 115 | 118 | 121 | 124 | 134 | 137 | 140 | 143 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 176 | 179 | 180 | 181 | 182 | 183 | 184 | 189 | 192 | 193 | 194 | 199 | 202 | 203 | 204 | 209 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /foo_browser/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_browser.rc 4 | // 5 | #define IDD_BLANK 101 6 | #define IDD_CONFIG 102 7 | #define IDD_PANEL_SETUP 103 8 | #define IDC_BUTTON_TEXT_COLOR 1012 9 | #define IDC_BUTTON_BACKGROUND_COLOR 1013 10 | #define IDC_PLAYLIST 1019 11 | #define IDC_AUTO_ACTIVATE 1020 12 | #define IDC_BUTTON_FONT 1021 13 | #define IDC_DOUBLE_CLICK 1022 14 | #define IDC_SCROLLBAR_MAGIC 1026 15 | #define IDC_EDGE_STYLE 1028 16 | #define IDC_HIDE_HEADERS 1029 17 | #define IDC_REPLACE_LAST 1030 18 | #define IDC_EDIT_FORMAT 1030 19 | #define IDC_CUSTOM_COLORS 1031 20 | #define IDC_EDIT_SORT 1031 21 | #define IDC_COLOR_SELECTION 1032 22 | #define IDC_COLOR_SELECTIONNONFOCUS 1033 23 | #define IDC_COLOR_SEL_TEXT 1034 24 | #define IDC_COLOR_SEL_TEXT_NON 1035 25 | #define IDC_POPULATE_ON_STARTUP 1036 26 | #define IDC_POPULATE_PLAYLIST_ON_STARTUP 1037 27 | #define IDC_SHOW_ITEMCOUNTS 1038 28 | #define IDC_EDIT_LABEL 1039 29 | #define IDC_SHOW_All 1039 30 | #define IDC_SHOWALL 1039 31 | #define IDC_COMBO_PREC 1040 32 | #define IDC_BUTTON_EDIT 1042 33 | #define IDC_BUTTON_ADD 1043 34 | #define IDC_BUTTON_REMOVE 1044 35 | #define IDC_LIST_PANELS 1045 36 | 37 | // Next default values for new objects 38 | // 39 | #ifdef APSTUDIO_INVOKED 40 | #ifndef APSTUDIO_READONLY_SYMBOLS 41 | #define _APS_NEXT_RESOURCE_VALUE 104 42 | #define _APS_NEXT_COMMAND_VALUE 40001 43 | #define _APS_NEXT_CONTROL_VALUE 1046 44 | #define _APS_NEXT_SYMED_VALUE 101 45 | #endif 46 | #endif 47 | -------------------------------------------------------------------------------- /foo_cwb_hooks/checkstates.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwbowron/foobar2000-plugins/6ba30d7b3afc0ee85f5cc2903012c1dfcee132bd/foo_cwb_hooks/checkstates.bmp -------------------------------------------------------------------------------- /foo_cwb_hooks/foo_cwb_hooks.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // DESIGNINFO 53 | // 54 | 55 | #ifdef APSTUDIO_INVOKED 56 | GUIDELINES DESIGNINFO 57 | BEGIN 58 | IDD_PREFERENCES, DIALOG 59 | BEGIN 60 | LEFTMARGIN, 7 61 | RIGHTMARGIN, 278 62 | TOPMARGIN, 7 63 | BOTTOMMARGIN, 212 64 | END 65 | 66 | IDD_TAG_SELECTION, DIALOG 67 | BEGIN 68 | LEFTMARGIN, 7 69 | RIGHTMARGIN, 179 70 | TOPMARGIN, 7 71 | BOTTOMMARGIN, 39 72 | END 73 | 74 | IDD_STAMP_PREFERENCES, DIALOG 75 | BEGIN 76 | LEFTMARGIN, 7 77 | RIGHTMARGIN, 302 78 | TOPMARGIN, 7 79 | BOTTOMMARGIN, 216 80 | END 81 | 82 | IDD_TAGGER, DIALOG 83 | BEGIN 84 | RIGHTMARGIN, 240 85 | BOTTOMMARGIN, 99 86 | END 87 | 88 | IDD_TAGGER_OPTIONS, DIALOG 89 | BEGIN 90 | LEFTMARGIN, 7 91 | RIGHTMARGIN, 278 92 | TOPMARGIN, 6 93 | BOTTOMMARGIN, 106 94 | END 95 | 96 | IDD_TAGGER_WINDOW_STANDALONE, DIALOG 97 | BEGIN 98 | LEFTMARGIN, 7 99 | RIGHTMARGIN, 179 100 | TOPMARGIN, 7 101 | BOTTOMMARGIN, 83 102 | END 103 | END 104 | #endif // APSTUDIO_INVOKED 105 | 106 | 107 | ///////////////////////////////////////////////////////////////////////////// 108 | // 109 | // Dialog 110 | // 111 | 112 | IDD_PREFERENCES DIALOGEX 0, 0, 285, 219 113 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 114 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 115 | BEGIN 116 | LTEXT "http://wiki.bowron.us/index.php/Foobar2000",IDC_STATIC,7,204,146,8 117 | LTEXT "foo_cwb_hooks by Christopher Bowron ",IDC_STATIC,7,193,194,8 118 | EDITTEXT IDC_EDIT_NEXT_USER1,12,16,254,12,ES_AUTOHSCROLL 119 | GROUPBOX "User defined next strings (cwb_next_user1, cwb_next_user2)",IDC_STATIC,7,7,263,42 120 | EDITTEXT IDC_EDIT_NEXT_USER2,12,32,254,12,ES_AUTOHSCROLL 121 | CONTROL "Notify other components of variable changes",IDC_CHECK_NOTIFY, 122 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,55,221,10 123 | CONTROL "Perform Action on Skipped Files:",IDC_SKIP_TAG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,81,119,10 124 | COMBOBOX IDC_SKIP_TAG_ACTION,7,95,271,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 125 | END 126 | 127 | IDD_TAG_SELECTION DIALOGEX 0, 0, 186, 46 128 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 129 | EXSTYLE WS_EX_TOOLWINDOW 130 | CAPTION "Timestamp Tag..." 131 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 132 | BEGIN 133 | DEFPUSHBUTTON "OK",IDOK,49,25,50,14 134 | PUSHBUTTON "Cancel",IDCANCEL,103,25,50,14 135 | EDITTEXT IDC_EDIT_TAG,7,7,172,14,ES_AUTOHSCROLL 136 | END 137 | 138 | IDD_STAMP_PREFERENCES DIALOGEX 0, 0, 309, 223 139 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 140 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 141 | BEGIN 142 | CONTROL "Process files added to the library:",IDC_CHECK_PROCESS_FILES, 143 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,195,10 144 | COMBOBOX IDC_COMBO_COMMAND,18,20,266,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 145 | END 146 | 147 | IDD_TAGGER DIALOGEX 0, 0, 241, 103 148 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 149 | EXSTYLE WS_EX_CONTROLPARENT 150 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 151 | BEGIN 152 | DEFPUSHBUTTON "Apply",IDOK,183,85,27,14 153 | PUSHBUTTON "Revert",IDCANCEL,213,85,27,14 154 | CONTROL "",IDC_LIST_TAGS,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,19,188,64 155 | EDITTEXT IDC_EDIT_MORE_TAGS,4,87,175,12,ES_AUTOHSCROLL 156 | CONTROL "N",IDC_RATING_NONE,"Button",BS_AUTORADIOBUTTON,199,59,17,10 157 | CONTROL "1",IDC_RATING_1,"Button",BS_AUTORADIOBUTTON,199,48,20,10 158 | CONTROL "2",IDC_RATING_2,"Button",BS_AUTORADIOBUTTON,199,37,20,10 159 | CONTROL "3",IDC_RATING_3,"Button",BS_AUTORADIOBUTTON,199,26,20,10 160 | CONTROL "4",IDC_RATING_4,"Button",BS_AUTORADIOBUTTON,199,15,20,10 161 | CONTROL "5",IDC_RATING_5,"Button",BS_AUTORADIOBUTTON,199,4,20,10 162 | LTEXT "filename.mp3",IDC_STATIC_FILENAME,6,3,185,8,SS_PATHELLIPSIS 163 | END 164 | 165 | IDD_TAGGER_OPTIONS DIALOGEX 0, 0, 285, 113 166 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 167 | CAPTION "Tagger Window Options" 168 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 169 | BEGIN 170 | LTEXT "Metadata Field:",IDC_STATIC,7,6,51,8 171 | EDITTEXT IDC_EDIT_TAGGER_META,7,19,95,14,ES_AUTOHSCROLL 172 | CONTROL "Show rating buttons",IDC_CHECK_USE_RATINGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,151,10,81,10 173 | EDITTEXT IDC_EDIT_TAGGER_TAGS,7,49,271,14,ES_AUTOHSCROLL 174 | DEFPUSHBUTTON "OK",IDOK,39,92,50,14 175 | PUSHBUTTON "Cancel",IDCANCEL,95,92,50,14 176 | LTEXT "Tags: (semi-colon between tags)",IDC_STATIC,7,37,106,8 177 | CONTROL "Show files",IDC_CHECK_SHOW_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,151,24,48,10 178 | CONTROL "Scan library for more tags",IDC_CHECK_SCAN_LIBRARY, 179 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,99,10 180 | END 181 | 182 | IDD_TAGGER_WINDOW_STANDALONE DIALOGEX 0, 0, 241, 103 183 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 184 | CAPTION "Tagger Window" 185 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 186 | BEGIN 187 | DEFPUSHBUTTON "Apply",IDOK,183,85,27,14 188 | PUSHBUTTON "Revert",IDCANCEL,213,85,27,14 189 | CONTROL "",IDC_LIST_TAGS,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,19,188,64 190 | EDITTEXT IDC_EDIT_MORE_TAGS,4,87,175,12,ES_AUTOHSCROLL 191 | CONTROL "N",IDC_RATING_NONE,"Button",BS_AUTORADIOBUTTON,199,59,17,10 192 | CONTROL "1",IDC_RATING_1,"Button",BS_AUTORADIOBUTTON,199,48,20,10 193 | CONTROL "2",IDC_RATING_2,"Button",BS_AUTORADIOBUTTON,199,37,20,10 194 | CONTROL "3",IDC_RATING_3,"Button",BS_AUTORADIOBUTTON,199,26,20,10 195 | CONTROL "4",IDC_RATING_4,"Button",BS_AUTORADIOBUTTON,199,15,20,10 196 | CONTROL "5",IDC_RATING_5,"Button",BS_AUTORADIOBUTTON,199,4,20,10 197 | LTEXT "filename.mp3",IDC_STATIC_FILENAME,6,3,185,8,SS_PATHELLIPSIS 198 | END 199 | 200 | 201 | ///////////////////////////////////////////////////////////////////////////// 202 | // 203 | // Bitmap 204 | // 205 | 206 | IDB_BITMAP1 BITMAP "checkstates.bmp" 207 | #endif // English (U.S.) resources 208 | ///////////////////////////////////////////////////////////////////////////// 209 | 210 | 211 | 212 | #ifndef APSTUDIO_INVOKED 213 | ///////////////////////////////////////////////////////////////////////////// 214 | // 215 | // Generated from the TEXTINCLUDE 3 resource. 216 | // 217 | 218 | 219 | ///////////////////////////////////////////////////////////////////////////// 220 | #endif // not APSTUDIO_INVOKED 221 | 222 | -------------------------------------------------------------------------------- /foo_cwb_hooks/foo_cwb_hooks.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 55 | 58 | 61 | 64 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 97 | 98 | 107 | 110 | 113 | 116 | 119 | 122 | 131 | 134 | 137 | 140 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 177 | 178 | 179 | 180 | 181 | 182 | 187 | 190 | 191 | 194 | 195 | 198 | 199 | 200 | 205 | 208 | 209 | 212 | 213 | 216 | 217 | 218 | 223 | 226 | 227 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /foo_cwb_hooks/foo_new_file_stamper.cpp: -------------------------------------------------------------------------------- 1 | #pragma warning(disable:4996) 2 | #pragma warning(disable:4312) 3 | #pragma warning(disable:4244) 4 | 5 | #include "../foobar2000/SDK/foobar2000.h" 6 | #include "../foobar2000/helpers/helpers.h" 7 | #include "../columns_ui-sdk/ui_extension.h" 8 | 9 | #include "resource.h" 10 | #include "../common/string_functions.h" 11 | #include "../common/menu_stuff.h" 12 | 13 | #define URL_HELP "http://wiki.bowron.us/index.php/Foobar2000" 14 | 15 | static const GUID cfg_stamper_000 = { 0xee6605c1, 0x3838, 0x48d4, { 0x9d, 0x9b, 0xcb, 0x29, 0x35, 0xd, 0x2a, 0x74 } }; 16 | static const GUID cfg_stamper_001 = { 0xde6a9099, 0x9c8c, 0x45e9, { 0x9f, 0x35, 0xb6, 0x6b, 0x88, 0x71, 0xa5, 0x4 } }; 17 | static const GUID cfg_stamper_002 = { 0x159d9072, 0xf3fc, 0x4e6a, { 0x9d, 0x7e, 0x75, 0x22, 0x26, 0xb1, 0x70, 0xc5 } }; 18 | static const GUID cfg_stamper_003 = { 0x12087db, 0x514b, 0x4062, { 0x98, 0x11, 0xf4, 0xeb, 0xd4, 0xac, 0xac, 0x65 } }; 19 | 20 | static cfg_int cfg_stamp( cfg_stamper_003, 0 ); 21 | static cfg_string cfg_stamp_action( cfg_stamper_000, "" ); 22 | static cfg_guid cfg_stamp_command( cfg_stamper_001, pfc::guid_null ); 23 | static cfg_guid cfg_stamp_subcommand( cfg_stamper_002, pfc::guid_null ); 24 | 25 | static const GUID guid_stamper_preferences = { 0xdcae7227, 0x2fb3, 0x44a1, { 0xb0, 0x94, 0x41, 0x6a, 0x1a, 0x98, 0xda, 0xf0 } }; 26 | 27 | bool_map bool_stamp_var_map[] = 28 | { 29 | { IDC_CHECK_PROCESS_FILES, &cfg_stamp }, 30 | }; 31 | 32 | script_map context_stamp_var_map[] = 33 | { 34 | { IDC_COMBO_COMMAND, &cfg_stamp_action, &cfg_stamp_command, &cfg_stamp_subcommand }, 35 | }; 36 | 37 | class stamper_preferences : public preferences_page, public cwb_menu_helpers 38 | { 39 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 40 | { 41 | switch ( msg ) 42 | { 43 | case WM_INITDIALOG: 44 | setup_bool_maps( wnd, bool_stamp_var_map, tabsize(bool_stamp_var_map) ); 45 | setup_script_maps( wnd, context_stamp_var_map, tabsize(context_stamp_var_map) ); 46 | 47 | EnableWindow( GetDlgItem( wnd, IDC_COMBO_COMMAND ), cfg_stamp ? TRUE : FALSE ); 48 | break; 49 | 50 | case WM_COMMAND: 51 | process_script_map( wnd, wp, context_stamp_var_map, tabsize(context_stamp_var_map) ); 52 | 53 | if ( process_bool_map( wnd, wp, bool_stamp_var_map, tabsize(bool_stamp_var_map) ) ) 54 | { 55 | EnableWindow( GetDlgItem( wnd, IDC_COMBO_COMMAND ), cfg_stamp ? TRUE : FALSE ); 56 | } 57 | break; 58 | } 59 | return false; 60 | } 61 | 62 | virtual HWND create(HWND parent) 63 | { 64 | return uCreateDialog( IDD_STAMP_PREFERENCES, parent, dialog_proc ); 65 | } 66 | 67 | virtual const char * get_name() 68 | { 69 | return "New File Tagger"; 70 | } 71 | 72 | virtual GUID get_guid() 73 | { 74 | return guid_stamper_preferences; 75 | } 76 | 77 | virtual GUID get_parent_guid() 78 | { 79 | return preferences_page::guid_tools; 80 | } 81 | 82 | //! Queries whether this page supports "reset page" feature. 83 | virtual bool reset_query() 84 | { 85 | return false; 86 | } 87 | 88 | virtual void reset() 89 | { 90 | } 91 | 92 | virtual bool get_help_url(pfc::string_base & p_out) 93 | { 94 | p_out.set_string( URL_HELP ); 95 | return true; 96 | } 97 | }; 98 | 99 | static service_factory_single_t g_stamper_pref; 100 | 101 | 102 | class new_file_stamper : public library_callback 103 | { 104 | public: 105 | //! Called when new items are added to the Media Library. 106 | virtual void on_items_added(const pfc::list_base_const_t & p_data) 107 | { 108 | if ( !core_api::is_initializing() ) 109 | { 110 | if ( cfg_stamp ) 111 | { 112 | console::printf( "Processing new files with %s", cfg_stamp_action.get_ptr() ); 113 | menu_helpers::run_command_context( cfg_stamp_command, cfg_stamp_subcommand, p_data ); 114 | } 115 | } 116 | } 117 | 118 | //! Called when some items have been removed from the Media Library. 119 | virtual void on_items_removed(const pfc::list_base_const_t & p_data) 120 | { 121 | } 122 | 123 | //! Called when some items in the Media Library have been modified. 124 | virtual void on_items_modified(const pfc::list_base_const_t & p_data) 125 | { 126 | } 127 | }; 128 | 129 | //static service_factory_single_t g_stamper; 130 | library_callback_factory_t g_stamper; -------------------------------------------------------------------------------- /foo_cwb_hooks/new_file_stamper.h: -------------------------------------------------------------------------------- 1 | #if 0 2 | static const GUID cfg_stamper_000 = { 0xee6605c1, 0x3838, 0x48d4, { 0x9d, 0x9b, 0xcb, 0x29, 0x35, 0xd, 0x2a, 0x74 } }; 3 | static const GUID cfg_stamper_001 = { 0xde6a9099, 0x9c8c, 0x45e9, { 0x9f, 0x35, 0xb6, 0x6b, 0x88, 0x71, 0xa5, 0x4 } }; 4 | static const GUID cfg_stamper_002 = { 0x159d9072, 0xf3fc, 0x4e6a, { 0x9d, 0x7e, 0x75, 0x22, 0x26, 0xb1, 0x70, 0xc5 } }; 5 | static const GUID cfg_stamper_003 = { 0x12087db, 0x514b, 0x4062, { 0x98, 0x11, 0xf4, 0xeb, 0xd4, 0xac, 0xac, 0x65 } }; 6 | 7 | static cfg_int cfg_stamp( cfg_stamper_003, 0 ); 8 | static cfg_string cfg_stamp_action( cfg_stamper_000, "" ); 9 | static cfg_guid cfg_stamp_command( cfg_stamper_001, pfc::guid_null ); 10 | static cfg_guid cfg_stamp_subcommand( cfg_stamper_002, pfc::guid_null ); 11 | 12 | static const GUID guid_stamper_preferences = { 0xdcae7227, 0x2fb3, 0x44a1, { 0xb0, 0x94, 0x41, 0x6a, 0x1a, 0x98, 0xda, 0xf0 } }; 13 | 14 | bool_map bool_stamp_var_map[] = 15 | { 16 | { IDC_CHECK_PROCESS_FILES, &cfg_stamp }, 17 | }; 18 | 19 | script_map context_stamp_var_map[] = 20 | { 21 | { IDC_COMBO_COMMAND, &cfg_stamp_action, &cfg_stamp_command, &cfg_stamp_subcommand }, 22 | }; 23 | 24 | class stamper_preferences : public preferences_page 25 | { 26 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 27 | { 28 | switch ( msg ) 29 | { 30 | case WM_INITDIALOG: 31 | setup_bool_maps( wnd, bool_stamp_var_map, tabsize(bool_stamp_var_map) ); 32 | setup_script_maps( wnd, context_stamp_var_map, tabsize(context_stamp_var_map) ); 33 | 34 | EnableWindow( GetDlgItem( wnd, IDC_COMBO_COMMAND ), cfg_stamp ? TRUE : FALSE ); 35 | break; 36 | 37 | case WM_COMMAND: 38 | process_script_map( wnd, wp, context_stamp_var_map, tabsize(context_stamp_var_map) ); 39 | 40 | if ( process_bool_map( wnd, wp, bool_stamp_var_map, tabsize(bool_stamp_var_map) ) ) 41 | { 42 | EnableWindow( GetDlgItem( wnd, IDC_COMBO_COMMAND ), cfg_stamp ? TRUE : FALSE ); 43 | } 44 | break; 45 | } 46 | return false; 47 | } 48 | 49 | virtual HWND create(HWND parent) 50 | { 51 | return uCreateDialog( IDD_STAMP_PREFERENCES, parent, dialog_proc ); 52 | } 53 | 54 | virtual const char * get_name() 55 | { 56 | return "New File Tagger"; 57 | } 58 | 59 | virtual GUID get_guid() 60 | { 61 | return guid_stamper_preferences; 62 | } 63 | 64 | virtual GUID get_parent_guid() 65 | { 66 | return preferences_page::guid_tools; 67 | } 68 | 69 | //! Queries whether this page supports "reset page" feature. 70 | virtual bool reset_query() 71 | { 72 | return false; 73 | } 74 | 75 | virtual void reset() 76 | { 77 | } 78 | 79 | virtual bool get_help_url(pfc::string_base & p_out) 80 | { 81 | p_out.set_string( URL_HELP ); 82 | return true; 83 | } 84 | }; 85 | 86 | static service_factory_single_t g_stamper_pref; 87 | 88 | 89 | class new_file_stamper : public library_callback 90 | { 91 | public: 92 | //! Called when new items are added to the Media Library. 93 | virtual void on_items_added(const pfc::list_base_const_t & p_data) 94 | { 95 | if ( !core_api::is_initializing() ) 96 | { 97 | if ( cfg_stamp ) 98 | { 99 | console::printf( "Processing new files with %s", cfg_stamp_action.get_ptr() ); 100 | menu_helpers::run_command_context( cfg_stamp_command, cfg_stamp_subcommand, p_data ); 101 | } 102 | } 103 | } 104 | 105 | //! Called when some items have been removed from the Media Library. 106 | virtual void on_items_removed(const pfc::list_base_const_t & p_data) 107 | { 108 | } 109 | 110 | //! Called when some items in the Media Library have been modified. 111 | virtual void on_items_modified(const pfc::list_base_const_t & p_data) 112 | { 113 | } 114 | }; 115 | 116 | //static service_factory_single_t g_stamper; 117 | library_callback_factory_t g_stamper; 118 | #endif 119 | -------------------------------------------------------------------------------- /foo_cwb_hooks/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_cwb_hooks.rc 4 | // 5 | #define IDD_PREFERENCES 101 6 | #define IDD_STAMP_PREFERENCES 102 7 | #define IDD_TAG_SELECTION 103 8 | #define IDD_TAGGER 104 9 | #define IDB_BITMAP1 105 10 | #define IDD_TAGGER_OPTIONS 106 11 | #define IDD_DIALOG1 107 12 | #define IDD_TAGGER_WINDOW_STANDALONE 107 13 | #define IDC_EDIT_NEXT_USER1 1001 14 | #define IDC_EDIT_NEXT_USER2 1002 15 | #define IDC_CHECK_NOTIFY 1003 16 | #define IDC_CHECK_PROCESS_FILES 1004 17 | #define IDC_COMBO_COMMAND 1005 18 | #define IDC_SKIP_TAG 1006 19 | #define IDC_EDIT_TAG 1007 20 | #define IDC_SKIP_TAG_ACTION 1007 21 | #define IDC_LIST_TAGS 1008 22 | #define IDC_EDIT_TAGGER_TAGS 1009 23 | #define IDC_EDIT_MORE_TAGS 1010 24 | #define IDC_EDIT_TAGGER_META 1011 25 | #define IDC_RATING_NONE 1012 26 | #define IDC_RATING_1 1013 27 | #define IDC_RATING_2 1014 28 | #define IDC_RATING_3 1015 29 | #define IDC_RATING_4 1016 30 | #define IDC_RATING_5 1017 31 | #define IDC_STATIC_FILENAME 1018 32 | #define IDC_CHECK_USE_RATINGS 1019 33 | #define IDC_CHECK_SHOW_FILES 1020 34 | #define IDC_CHECK_SCAN_LIBRARY 1021 35 | 36 | // Next default values for new objects 37 | // 38 | #ifdef APSTUDIO_INVOKED 39 | #ifndef APSTUDIO_READONLY_SYMBOLS 40 | #define _APS_NEXT_RESOURCE_VALUE 108 41 | #define _APS_NEXT_COMMAND_VALUE 40001 42 | #define _APS_NEXT_CONTROL_VALUE 1022 43 | #define _APS_NEXT_SYMED_VALUE 101 44 | #endif 45 | #endif 46 | -------------------------------------------------------------------------------- /foo_cwb_hooks/timestamp_action.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /// 4 | static const GUID cfg_var_000 = { 0xb778d58f, 0x813e, 0x4306, { 0xba, 0x2, 0xbb, 0x8a, 0xd7, 0x20, 0x7c, 0xf9 } }; 5 | static const GUID cfg_var_001 = { 0xa0bb8d40, 0x38ad, 0x4859, { 0xa5, 0x88, 0xf6, 0xdb, 0x23, 0x1a, 0xa8, 0x4b } }; 6 | 7 | static cfg_string cfg_last_tag( cfg_var_000, "TIMESTAMP" ); 8 | static cfg_string cfg_creation_tag( cfg_var_001, "DATE_CREATED" ); 9 | /// 10 | 11 | void get_current_time( pfc::string_base & p_out ) 12 | { 13 | static CHAR date_string[30]; 14 | SYSTEMTIME st; 15 | GetLocalTime(&st); 16 | sprintf(date_string, "%d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, 17 | st.wHour, st.wMinute, st.wSecond); 18 | 19 | p_out.set_string( date_string ); 20 | } 21 | 22 | bool get_file_creation_time( const playable_location & p_location, pfc::string_base & p_out ) 23 | { 24 | pfc::string8 filename; 25 | FILETIME creation; 26 | SYSTEMTIME stUTC, stLocal; 27 | 28 | if ( strstr( p_location.get_path(), "file://") ) 29 | { 30 | filesystem::g_get_display_path( p_location.get_path(), filename ); 31 | 32 | HANDLE file_handle = uCreateFile( filename, FILE_READ_ATTRIBUTES, 33 | FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 34 | 35 | if ( file_handle != INVALID_HANDLE_VALUE ) 36 | { 37 | GetFileTime( file_handle, &creation, NULL, NULL ); 38 | CloseHandle( file_handle ); 39 | 40 | // Convert the last-write time to local time. 41 | FileTimeToSystemTime( &creation, &stUTC ); 42 | SystemTimeToTzSpecificLocalTime( NULL, &stUTC, &stLocal ); 43 | 44 | static CHAR date_string[30]; 45 | 46 | sprintf(date_string, "%d-%02d-%02d %02d:%02d:%02d", stLocal.wYear, stLocal.wMonth, stLocal.wDay, 47 | stLocal.wHour, stLocal.wMinute, stLocal.wSecond); 48 | 49 | p_out.set_string( date_string ); 50 | return true; 51 | } 52 | } 53 | return false; 54 | } 55 | 56 | 57 | static BOOL CALLBACK tag_selection_callback( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 58 | { 59 | static pfc::string_base * in_out = NULL; 60 | 61 | switch ( msg ) 62 | { 63 | case WM_INITDIALOG: 64 | { 65 | in_out = ( pfc::string_base * ) lp; 66 | uSetDlgItemText( wnd, IDC_EDIT_TAG, in_out->get_ptr() ); 67 | SetFocus( GetDlgItem( wnd, IDC_EDIT_TAG ) ); 68 | return FALSE; 69 | } 70 | break; 71 | 72 | case WM_COMMAND: 73 | switch ( wp ) 74 | { 75 | case IDOK: 76 | uGetDlgItemText( wnd, IDC_EDIT_TAG, *in_out ); 77 | // fallthrough 78 | case IDCANCEL: 79 | EndDialog( wnd, wp ); 80 | break; 81 | } 82 | } 83 | return false; 84 | } 85 | 86 | 87 | class timestamp_action : public masstagger_action 88 | { 89 | public: 90 | pfc::string8 m_tag; 91 | 92 | /** 93 | * Get name to display on list of available actions. 94 | * \param p_out store name in here 95 | */ 96 | virtual void get_name(pfc::string_base & p_out) 97 | { 98 | p_out.set_string( "Stamp Current Date and Time..." ); 99 | } 100 | 101 | /** 102 | * Initialize and show configuration with default values, if appropriate. 103 | * \param p_parent handle to parent window 104 | * \returns true iff succesful 105 | */ 106 | virtual bool initialize(HWND p_parent) 107 | { 108 | m_tag.set_string( cfg_last_tag ); 109 | if ( IDOK == uDialogBox( IDD_TAG_SELECTION, p_parent, tag_selection_callback, (LPARAM) &m_tag ) ) 110 | { 111 | cfg_last_tag = m_tag; 112 | return true; 113 | } 114 | return false; 115 | } 116 | 117 | /** 118 | * Initialize and get configuration from parameter. 119 | * \param p_data a zero-terminated string containing previously stored configuration data. 120 | * \returns true iff succesful 121 | */ 122 | virtual bool initialize_fromconfig(const char * p_data) 123 | { 124 | m_tag.set_string( p_data ); 125 | return true; 126 | } 127 | 128 | /** 129 | * Show configuration with current values. 130 | * \param parent handle to parent window 131 | * \returns true if display string needs to be updated. 132 | */ 133 | virtual bool configure(HWND p_parent) 134 | { 135 | if ( IDOK == uDialogBox( IDD_TAG_SELECTION, p_parent, tag_selection_callback, (LPARAM) &m_tag ) ) 136 | { 137 | cfg_last_tag = m_tag; 138 | return true; 139 | } 140 | return false; 141 | } 142 | 143 | /** 144 | * Get name to display on list of configured actions. 145 | * You should include value of settings, if possible. 146 | * \param p_name store name in here 147 | */ 148 | virtual void get_display_string(pfc::string_base & p_name) 149 | { 150 | p_name.set_string( "Time Stamp: " ); 151 | p_name.add_string( m_tag ); 152 | } 153 | 154 | /** 155 | * Get current settings as zero-terminated string. 156 | * \param p_data store settings in here 157 | */ 158 | virtual void get_config(pfc::string_base & p_data) 159 | { 160 | p_data.set_string( m_tag ); 161 | } 162 | 163 | /** 164 | * Apply action on file info. 165 | * \param p_location location of current item 166 | * \param p_info file info of current item, contains modifications from previous actions 167 | * \param p_index zero-based index of current item in list of processed items 168 | * \param p_count number of processed items 169 | */ 170 | virtual void run(const playable_location & p_location, file_info * p_info, t_size p_index, t_size p_count) 171 | { 172 | pfc::string8 timestamp; 173 | 174 | get_current_time( timestamp ); 175 | 176 | p_info->meta_set( m_tag, timestamp ); 177 | } 178 | 179 | virtual const GUID & get_guid() 180 | { 181 | static const GUID guid = { 0x8e883ae2, 0x63dc, 0x446d, { 0x9b, 0xe9, 0xc8, 0x41, 0x7e, 0xd3, 0x93, 0x9f } }; 182 | return guid; 183 | } 184 | }; 185 | 186 | static service_factory_single_t g_timestamp_action; 187 | 188 | 189 | class created_stamp_action : public masstagger_action 190 | { 191 | public: 192 | pfc::string8 m_tag; 193 | 194 | /** 195 | * Get name to display on list of available actions. 196 | * \param p_out store name in here 197 | */ 198 | virtual void get_name(pfc::string_base & p_out) 199 | { 200 | p_out.set_string( "Stamp File Creation Time..." ); 201 | } 202 | 203 | /** 204 | * Initialize and show configuration with default values, if appropriate. 205 | * \param p_parent handle to parent window 206 | * \returns true iff succesful 207 | */ 208 | virtual bool initialize(HWND p_parent) 209 | { 210 | m_tag.set_string( cfg_creation_tag ); 211 | if ( IDOK == uDialogBox( IDD_TAG_SELECTION, p_parent, tag_selection_callback, (LPARAM) &m_tag ) ) 212 | { 213 | cfg_creation_tag = m_tag; 214 | return true; 215 | } 216 | return false; 217 | } 218 | 219 | /** 220 | * Initialize and get configuration from parameter. 221 | * \param p_data a zero-terminated string containing previously stored configuration data. 222 | * \returns true iff succesful 223 | */ 224 | virtual bool initialize_fromconfig(const char * p_data) 225 | { 226 | m_tag.set_string( p_data ); 227 | return true; 228 | } 229 | 230 | /** 231 | * Show configuration with current values. 232 | * \param parent handle to parent window 233 | * \returns true if display string needs to be updated. 234 | */ 235 | virtual bool configure(HWND p_parent) 236 | { 237 | if ( IDOK == uDialogBox( IDD_TAG_SELECTION, p_parent, tag_selection_callback, (LPARAM) &m_tag ) ) 238 | { 239 | cfg_creation_tag = m_tag; 240 | return true; 241 | } 242 | return false; 243 | } 244 | 245 | /** 246 | * Get name to display on list of configured actions. 247 | * You should include value of settings, if possible. 248 | * \param p_name store name in here 249 | */ 250 | virtual void get_display_string(pfc::string_base & p_name) 251 | { 252 | p_name.set_string( "File Creation Stamp: " ); 253 | p_name.add_string( m_tag ); 254 | } 255 | 256 | /** 257 | * Get current settings as zero-terminated string. 258 | * \param p_data store settings in here 259 | */ 260 | virtual void get_config(pfc::string_base & p_data) 261 | { 262 | p_data.set_string( m_tag ); 263 | } 264 | 265 | /** 266 | * Apply action on file info. 267 | * \param p_location location of current item 268 | * \param p_info file info of current item, contains modifications from previous actions 269 | * \param p_index zero-based index of current item in list of processed items 270 | * \param p_count number of processed items 271 | */ 272 | virtual void run(const playable_location & p_location, file_info * p_info, t_size p_index, t_size p_count) 273 | { 274 | pfc::string8 timestamp; 275 | 276 | if ( get_file_creation_time( p_location, timestamp ) ) 277 | { 278 | p_info->meta_set( m_tag, timestamp ); 279 | } 280 | } 281 | 282 | virtual const GUID & get_guid() 283 | { 284 | static const GUID guid = { 0x251f2d55, 0x84eb, 0x487e, { 0x9a, 0xa3, 0xb0, 0x4e, 0x17, 0x23, 0x36, 0x0 } }; 285 | return guid; 286 | } 287 | }; 288 | 289 | static service_factory_single_t g_created_stamp_action; 290 | -------------------------------------------------------------------------------- /foo_cwbowron/foo_cwbowron.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_ART_LIST DIALOGEX 0, 0, 246, 225 56 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 57 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 58 | BEGIN 59 | CONTROL "",IDC_LIST_IMAGES,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,232,211 60 | END 61 | 62 | IDD_OPTIONS DIALOGEX 0, 0, 250, 209 63 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 64 | CAPTION "Options" 65 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 66 | BEGIN 67 | DEFPUSHBUTTON "OK",IDOK,73,188,50,14 68 | PUSHBUTTON "Cancel",IDCANCEL,126,188,50,14 69 | EDITTEXT IDC_EDIT_ART_FORMAT,7,24,236,14,ES_AUTOHSCROLL 70 | EDITTEXT IDC_EDIT_LABEL_FORMAT,7,53,236,14,ES_AUTOHSCROLL 71 | EDITTEXT IDC_EDIT_THUMBNAIL_WIDTH,38,88,40,14,ES_AUTOHSCROLL 72 | EDITTEXT IDC_EDIT_THUMBNAIL_HEIGHT,38,104,40,14,ES_AUTOHSCROLL 73 | PUSHBUTTON "Text",IDC_BUTTON_TEXT,171,86,50,14 74 | PUSHBUTTON "Background",IDC_BUTTON_BACKGROUND,171,104,50,14 75 | LTEXT "Image Labels:",IDC_STATIC,11,41,186,8 76 | LTEXT "Album Art Location:",IDC_STATIC,11,15,186,8 77 | GROUPBOX "Formatting",IDC_STATIC,7,7,236,68 78 | GROUPBOX "Thumbnail",IDC_STATIC,7,78,78,44 79 | LTEXT "Width:",IDC_STATIC,11,91,22,8 80 | LTEXT "Height:",IDC_STATIC,12,106,24,8 81 | GROUPBOX "Colors",IDC_STATIC,88,78,155,44 82 | PUSHBUTTON "Button1",IDC_BUTTON_FILL_TEXT,118,86,50,14 83 | PUSHBUTTON "Button1",IDC_BUTTON_FILL_BACK,118,104,50,14 84 | GROUPBOX "Actions",IDC_STATIC,7,126,236,47 85 | COMBOBOX IDC_COMBO_SELECTION_ACTION,59,137,184,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 86 | COMBOBOX IDC_COMBO_DOUBLE_CLICK_ACTION,59,154,184,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 87 | LTEXT "Selection:",IDC_STATIC,22,139,32,8 88 | LTEXT "Double Click:",IDC_STATIC,12,155,42,8 89 | END 90 | 91 | IDD_STARTUP_PREFERENCES DIALOGEX 0, 0, 308, 222 92 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 93 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 94 | BEGIN 95 | CONTROL "",IDC_LIST_ACTIONS,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,11,21,222,190 96 | PUSHBUTTON "Add",IDC_BUTTON_ADD,237,20,50,14 97 | PUSHBUTTON "Remove",IDC_BUTTON_REMOVE,237,37,50,14 98 | GROUPBOX "Startup Actions",IDC_STATIC,7,7,301,215 99 | END 100 | 101 | IDD_ADD_ACTION DIALOGEX 0, 0, 186, 49 102 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 103 | CAPTION "Add Action..." 104 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 105 | BEGIN 106 | DEFPUSHBUTTON "OK",IDOK,41,28,50,14 107 | PUSHBUTTON "Cancel",IDCANCEL,94,28,50,14 108 | COMBOBOX IDC_COMBO_ACTIONS,7,7,172,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 109 | END 110 | 111 | 112 | ///////////////////////////////////////////////////////////////////////////// 113 | // 114 | // DESIGNINFO 115 | // 116 | 117 | #ifdef APSTUDIO_INVOKED 118 | GUIDELINES DESIGNINFO 119 | BEGIN 120 | IDD_ART_LIST, DIALOG 121 | BEGIN 122 | LEFTMARGIN, 7 123 | RIGHTMARGIN, 239 124 | TOPMARGIN, 7 125 | BOTTOMMARGIN, 218 126 | END 127 | 128 | IDD_OPTIONS, DIALOG 129 | BEGIN 130 | LEFTMARGIN, 7 131 | RIGHTMARGIN, 243 132 | TOPMARGIN, 7 133 | BOTTOMMARGIN, 202 134 | END 135 | 136 | IDD_STARTUP_PREFERENCES, DIALOG 137 | BEGIN 138 | LEFTMARGIN, 7 139 | RIGHTMARGIN, 301 140 | TOPMARGIN, 7 141 | BOTTOMMARGIN, 215 142 | END 143 | 144 | IDD_ADD_ACTION, DIALOG 145 | BEGIN 146 | LEFTMARGIN, 7 147 | RIGHTMARGIN, 179 148 | TOPMARGIN, 7 149 | BOTTOMMARGIN, 42 150 | END 151 | END 152 | #endif // APSTUDIO_INVOKED 153 | 154 | #endif // English (U.S.) resources 155 | ///////////////////////////////////////////////////////////////////////////// 156 | 157 | 158 | 159 | #ifndef APSTUDIO_INVOKED 160 | ///////////////////////////////////////////////////////////////////////////// 161 | // 162 | // Generated from the TEXTINCLUDE 3 resource. 163 | // 164 | 165 | 166 | ///////////////////////////////////////////////////////////////////////////// 167 | #endif // not APSTUDIO_INVOKED 168 | 169 | -------------------------------------------------------------------------------- /foo_cwbowron/foo_cwbowron.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 98 | 99 | 108 | 111 | 114 | 117 | 120 | 123 | 132 | 135 | 138 | 141 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 178 | 179 | 180 | 181 | 182 | 183 | 188 | 191 | 192 | 193 | 198 | 201 | 202 | 203 | 208 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /foo_cwbowron/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_cwbowron.rc 4 | // 5 | #define IDD_ART_LIST 101 6 | #define IDD_OPTIONS 102 7 | #define IDD_STARTUP_PREFERENCES 103 8 | #define IDD_ADD_ACTION 104 9 | #define IDC_LIST_IMAGES 1001 10 | #define IDC_EDIT_ART_FORMAT 1002 11 | #define IDC_EDIT_LABEL_FORMAT 1003 12 | #define IDC_EDIT_THUMBNAIL_WIDTH 1004 13 | #define IDC_EDIT_THUMBNAIL_HEIGHT 1005 14 | #define IDC_BUTTON_BACKGROUND 1006 15 | #define IDC_BUTTON_TEXT 1007 16 | #define IDC_BUTTON_FILL_TEXT 1010 17 | #define IDC_BUTTON_FILL_BACK 1011 18 | #define IDC_COMBO_SELECTION_ACTION 1012 19 | #define IDC_COMBO_DOUBLE_CLICK_ACTION 1013 20 | #define IDC_LIST_ACTIONS 1015 21 | #define IDC_BUTTON_ADD 1016 22 | #define IDC_BUTTON_REMOVE 1017 23 | #define IDC_COMBO1 1017 24 | #define IDC_COMBO_ACTIONS 1017 25 | 26 | // Next default values for new objects 27 | // 28 | #ifdef APSTUDIO_INVOKED 29 | #ifndef APSTUDIO_READONLY_SYMBOLS 30 | #define _APS_NEXT_RESOURCE_VALUE 105 31 | #define _APS_NEXT_COMMAND_VALUE 40001 32 | #define _APS_NEXT_CONTROL_VALUE 1018 33 | #define _APS_NEXT_SYMED_VALUE 101 34 | #endif 35 | #endif 36 | -------------------------------------------------------------------------------- /foo_dock/buffer_reader.h: -------------------------------------------------------------------------------- 1 | #include "../foobar2000/SDK/foobar2000.h" 2 | 3 | class buffer_reader : public stream_reader 4 | { 5 | char * m_data; 6 | t_size m_size; 7 | t_size m_index; 8 | 9 | public: 10 | buffer_reader( stream_reader * in, t_size size, foobar2000_io::abort_callback & abort ) : stream_reader() 11 | { 12 | m_index = 0; 13 | m_size = size; 14 | m_data = new char[size]; 15 | in->read( m_data, m_size, abort ); 16 | } 17 | 18 | ~buffer_reader() 19 | { 20 | delete m_data; 21 | } 22 | 23 | virtual t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) 24 | { 25 | if ( p_bytes + m_index <= m_size ) 26 | { 27 | memcpy( p_buffer, m_data + m_index, p_bytes ); 28 | m_index += p_bytes; 29 | return p_bytes; 30 | } 31 | else 32 | { 33 | t_size bytes = m_size - m_index; 34 | memcpy( p_buffer, m_data + m_index, bytes ); 35 | m_index = m_size; 36 | return bytes; 37 | } 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /foo_dock/dock_preferences.h: -------------------------------------------------------------------------------- 1 | // PREFERENCES ///////////////////////////////////// 2 | #include "../common/menu_stuff.h" 3 | 4 | static const GUID guid_preferences = { 0x4e35cce5, 0xbbcf, 0x49cc, { 0xbc, 0x8f, 0x20, 0x95, 0x1a, 0xd6, 0xac, 0xbc } }; 5 | 6 | bool_map bool_var_map[] = 7 | { 8 | { IDC_SHOW_ARROWS, &cfg_show_dock_arrows }, 9 | { IDC_MIN_ON_MAIN_MIN, &cfg_minimize_on_main_minimize }, 10 | { IDC_USE_EXPANSION_TAGZ, &cfg_use_expansion_tagz }, 11 | { IDC_USE_TRANSPARENCY, &cfg_use_transparency }, 12 | }; 13 | 14 | int_map int_var_map[] = 15 | { 16 | { IDC_EDIT_OPACITY_ACTIVE, &cfg_opacity_active }, 17 | { IDC_EDIT_OPACITY_INACTIVE, &cfg_opacity_inactive }, 18 | { IDC_EDIT_SNAPPING_DISTANCE, &cfg_snapping_distance }, 19 | }; 20 | 21 | class dockable_panel_preferences : public preferences_page 22 | { 23 | static bool m_initialized; 24 | 25 | static void enable_shit( HWND wnd ) 26 | { 27 | if ( cfg_use_transparency ) 28 | { 29 | EnableWindow( GetDlgItem( wnd, IDC_EDIT_OPACITY_ACTIVE ), TRUE ); 30 | EnableWindow( GetDlgItem( wnd, IDC_EDIT_OPACITY_INACTIVE ), TRUE ); 31 | EnableWindow( GetDlgItem( wnd, IDC_SPIN_OPACITY_ACTIVE ), TRUE ); 32 | EnableWindow( GetDlgItem( wnd, IDC_SPIN_OPACITY_INACTIVE ), TRUE ); 33 | } 34 | else 35 | { 36 | EnableWindow( GetDlgItem( wnd, IDC_EDIT_OPACITY_ACTIVE ), FALSE ); 37 | EnableWindow( GetDlgItem( wnd, IDC_EDIT_OPACITY_INACTIVE ), FALSE ); 38 | EnableWindow( GetDlgItem( wnd, IDC_SPIN_OPACITY_ACTIVE ), FALSE ); 39 | EnableWindow( GetDlgItem( wnd, IDC_SPIN_OPACITY_INACTIVE ), FALSE ); 40 | } 41 | } 42 | 43 | static void set_spinner_status( HWND hwnd, int min, int max, int pos ) 44 | { 45 | SendMessage( hwnd, UDM_SETRANGE, 0, MAKELONG(max,min) ); 46 | SendMessage( hwnd, UDM_SETPOS, 0, MAKELONG(pos,0) ); 47 | } 48 | 49 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 50 | { 51 | switch ( msg ) 52 | { 53 | case WM_INITDIALOG: 54 | { 55 | m_initialized = true; 56 | 57 | int opacity_active = cfg_opacity_active; 58 | int opacity_inactive = cfg_opacity_inactive; 59 | 60 | set_spinner_status( GetDlgItem( wnd, IDC_SPIN_OPACITY_ACTIVE ), 0, 255, opacity_active ); 61 | set_spinner_status( GetDlgItem( wnd, IDC_SPIN_OPACITY_INACTIVE ), 0, 255, opacity_inactive ); 62 | set_spinner_status( GetDlgItem( wnd, IDC_SPIN_SNAPPING_DISTANCE), 0, 10, cfg_snapping_distance ); 63 | 64 | setup_bool_maps( wnd, bool_var_map, tabsize(bool_var_map) ); 65 | setup_int_maps( wnd, int_var_map, tabsize(int_var_map) ); 66 | 67 | enable_shit( wnd ); 68 | } 69 | break; 70 | 71 | case WM_COMMAND: 72 | { 73 | if ( m_initialized ) 74 | { 75 | bool b1 = process_bool_map( wnd, wp, bool_var_map, tabsize(bool_var_map) ); 76 | bool b2 = process_int_maps( wnd, wp, int_var_map, tabsize(int_var_map) ); 77 | 78 | if ( b1 || b2 ) 79 | { 80 | for ( int n = 0; n < g_host_windows.get_count(); n++ ) 81 | { 82 | g_host_windows[n]->update_title(); 83 | g_host_windows[n]->update_style(); 84 | } 85 | 86 | enable_shit( wnd ); 87 | } 88 | } 89 | } 90 | break; 91 | } 92 | return false; 93 | } 94 | 95 | virtual HWND create(HWND parent) 96 | { 97 | m_initialized = false; 98 | return uCreateDialog( IDD_PREFERENCES, parent, dialog_proc ); 99 | } 100 | 101 | virtual const char * get_name() 102 | { 103 | return "Dockable Panels"; 104 | } 105 | 106 | virtual GUID get_guid() 107 | { 108 | return guid_preferences; 109 | } 110 | 111 | virtual GUID get_parent_guid() 112 | { 113 | return preferences_page::guid_display; 114 | } 115 | 116 | //! Queries whether this page supports "reset page" feature. 117 | virtual bool reset_query() 118 | { 119 | return false; 120 | } 121 | 122 | virtual void reset() 123 | { 124 | } 125 | 126 | virtual bool get_help_url(pfc::string_base & p_out) 127 | { 128 | p_out.set_string( URL_HELP ); 129 | return true; 130 | } 131 | }; 132 | bool dockable_panel_preferences::m_initialized = false; 133 | 134 | static service_factory_single_t g_pref; 135 | -------------------------------------------------------------------------------- /foo_dock/foo_dock.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_BLANK DIALOGEX 0, 0, 96, 60 56 | STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME 57 | EXSTYLE WS_EX_TOOLWINDOW 58 | CAPTION "foo_dock" 59 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 60 | BEGIN 61 | END 62 | 63 | IDD_RENAME_DIALOG DIALOGEX 0, 0, 186, 47 64 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 65 | EXSTYLE WS_EX_TOOLWINDOW 66 | CAPTION "Custom Title" 67 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 68 | BEGIN 69 | DEFPUSHBUTTON "OK",IDOK,40,26,50,14 70 | PUSHBUTTON "Cancel",IDCANCEL,93,26,50,14 71 | EDITTEXT IDC_NAME,7,7,172,14,ES_AUTOHSCROLL 72 | END 73 | 74 | IDD_PREFERENCES DIALOGEX 0, 0, 285, 259 75 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 76 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 77 | BEGIN 78 | CONTROL "Show docking arrows on title bar",IDC_SHOW_ARROWS, 79 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,120,10 80 | CONTROL "Minimize panels when minimizing main window",IDC_MIN_ON_MAIN_MIN, 81 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,19,160,10 82 | CONTROL "Process Expansion Tagz",IDC_USE_EXPANSION_TAGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,31,93,10 83 | CONTROL "Use Transparency",IDC_USE_TRANSPARENCY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,43,74,10 84 | LTEXT "opacity (active):",IDC_STATIC,33,60,54,8 85 | EDITTEXT IDC_EDIT_OPACITY_ACTIVE,91,58,47,14,ES_AUTOHSCROLL | ES_NUMBER 86 | CONTROL "",IDC_SPIN_OPACITY_ACTIVE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,139,58,10,14 87 | LTEXT "opacity (inactive):",IDC_STATIC,28,77,59,8 88 | EDITTEXT IDC_EDIT_OPACITY_INACTIVE,91,75,47,14,ES_AUTOHSCROLL | ES_NUMBER 89 | CONTROL "",IDC_SPIN_OPACITY_INACTIVE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,139,75,10,14 90 | LTEXT "foo_dockable_panels by Christopher Bowron ",IDC_STATIC,7,244,212,8 91 | EDITTEXT IDC_EDIT_SNAPPING_DISTANCE,71,121,47,14,ES_AUTOHSCROLL | ES_NUMBER 92 | CONTROL "",IDC_SPIN_SNAPPING_DISTANCE,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,119,121,10,14 93 | LTEXT "Snapping Distance:",IDC_STATIC,7,123,62,8 94 | LTEXT "(pixels)",IDC_STATIC,133,124,24,8 95 | END 96 | 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | // 100 | // DESIGNINFO 101 | // 102 | 103 | #ifdef APSTUDIO_INVOKED 104 | GUIDELINES DESIGNINFO 105 | BEGIN 106 | IDD_RENAME_DIALOG, DIALOG 107 | BEGIN 108 | LEFTMARGIN, 7 109 | RIGHTMARGIN, 179 110 | TOPMARGIN, 7 111 | BOTTOMMARGIN, 40 112 | END 113 | 114 | IDD_PREFERENCES, DIALOG 115 | BEGIN 116 | LEFTMARGIN, 7 117 | RIGHTMARGIN, 278 118 | TOPMARGIN, 7 119 | BOTTOMMARGIN, 252 120 | END 121 | END 122 | #endif // APSTUDIO_INVOKED 123 | 124 | #endif // English (U.S.) resources 125 | ///////////////////////////////////////////////////////////////////////////// 126 | 127 | 128 | 129 | #ifndef APSTUDIO_INVOKED 130 | ///////////////////////////////////////////////////////////////////////////// 131 | // 132 | // Generated from the TEXTINCLUDE 3 resource. 133 | // 134 | 135 | 136 | ///////////////////////////////////////////////////////////////////////////// 137 | #endif // not APSTUDIO_INVOKED 138 | 139 | -------------------------------------------------------------------------------- /foo_dock/foo_dock.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 55 | 58 | 61 | 64 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 96 | 104 | 107 | 110 | 113 | 116 | 119 | 128 | 131 | 134 | 137 | 148 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 173 | 174 | 175 | 176 | 177 | 182 | 185 | 186 | 187 | 192 | 195 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 209 | 214 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /foo_dock/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_dock.rc 4 | // 5 | #define IDD_BLANK 101 6 | #define IDD_RENAME_DIALOG 102 7 | #define IDD_PREFERENCES 104 8 | #define IDC_NAME 1001 9 | #define IDC_SHOW_ARROWS 1002 10 | #define IDC_MIN_ON_MAIN_MIN 1003 11 | #define IDC_USE_EXPANSION_TAGZ 1004 12 | #define IDC_USE_TRANSPARENCY 1005 13 | #define IDC_EDIT_OPACITY_ACTIVE 1006 14 | #define IDC_EDIT_OPACITY_INACTIVE 1007 15 | #define IDC_SPIN_OPACITY_ACTIVE 1008 16 | #define IDC_SPIN_OPACITY_INACTIVE 1009 17 | #define IDC_EDIT_SNAPPING_DISTANCE 1010 18 | #define IDC_SPIN_OPACITY_ACTIVE2 1011 19 | #define IDC_SPIN_SNAPPING_DISTANCE 1011 20 | #define IDC_STATIC -1 21 | 22 | // Next default values for new objects 23 | // 24 | #ifdef APSTUDIO_INVOKED 25 | #ifndef APSTUDIO_READONLY_SYMBOLS 26 | #define _APS_NEXT_RESOURCE_VALUE 104 27 | #define _APS_NEXT_COMMAND_VALUE 40001 28 | #define _APS_NEXT_CONTROL_VALUE 1009 29 | #define _APS_NEXT_SYMED_VALUE 101 30 | #endif 31 | #endif 32 | -------------------------------------------------------------------------------- /foo_notitlebar/foo_notitlebar.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 68 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 93 | 102 | 105 | 108 | 111 | 114 | 117 | 126 | 129 | 132 | 135 | 146 | 149 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 171 | 172 | 173 | 174 | 175 | 180 | 183 | 184 | 185 | 190 | 191 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /foo_playlist_tree/bitmap1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwbowron/foobar2000-plugins/6ba30d7b3afc0ee85f5cc2903012c1dfcee132bd/foo_playlist_tree/bitmap1.bmp -------------------------------------------------------------------------------- /foo_playlist_tree/foo_playlist_tree.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_BLANK DIALOGEX 0, 0, 224, 158 56 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 57 | EXSTYLE WS_EX_CONTROLPARENT 58 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 59 | BEGIN 60 | CONTROL "",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_TABSTOP,7,7,210,144 61 | END 62 | 63 | IDD_ICONSELECT DIALOG 0, 0, 235, 166 64 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 65 | CAPTION "Select Icon..." 66 | FONT 8, "MS Sans Serif" 67 | BEGIN 68 | DEFPUSHBUTTON "OK",IDOK,178,7,50,14 69 | PUSHBUTTON "Cancel",IDCANCEL,178,24,50,14 70 | CONTROL "List2",IDC_ICONLIST,"SysListView32",LVS_SINGLESEL | LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP,7,7,163,152 71 | END 72 | 73 | IDD_QUERY DIALOGEX 0, 0, 380, 318 74 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION 75 | EXSTYLE WS_EX_CONTROLPARENT 76 | CAPTION "Query Options" 77 | FONT 8, "MS Sans Serif", 0, 0, 0x1 78 | BEGIN 79 | EDITTEXT IDC_LABEL,2,14,306,13,ES_AUTOHSCROLL 80 | PUSHBUTTON "set...",IDC_SET_NORMAL,319,15,22,9 81 | PUSHBUTTON "reset",IDC_ICON_RESET,319,25,22,9 82 | EDITTEXT IDC_EDIT_SOURCE,2,42,375,13,ES_AUTOHSCROLL 83 | EDITTEXT IDC_QUERY,2,70,375,27,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL 84 | EDITTEXT IDC_FORMAT,2,112,375,129,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL 85 | EDITTEXT IDC_MAX,6,256,40,13,ES_AUTOHSCROLL | ES_NUMBER 86 | CONTROL "tracks",IDC_TRACKS,"Button",BS_AUTORADIOBUTTON,49,255,35,10 87 | CONTROL "minutes",IDC_MINUTES,"Button",BS_AUTORADIOBUTTON,49,265,40,10 88 | CONTROL "megs",IDC_MEGS,"Button",BS_AUTORADIOBUTTON,49,275,33,10 89 | CONTROL "subfolders",IDC_SUBFOLDERS,"Button",BS_AUTORADIOBUTTON,49,285,45,10 90 | EDITTEXT IDC_SORT_CRITERIA,114,255,216,13,ES_AUTOHSCROLL 91 | CONTROL "Reverse",IDC_REVERSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,334,255,43,10 92 | CONTROL "Sort by display name after populating",IDC_SORT_AFTER, 93 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,274,209,10 94 | CONTROL "Automatically Refresh",IDC_CHECK_AUTOREFRESH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,286,84,10 95 | ICON "",IDC_ICON_NORMAL,347,12,20,20,SS_CENTERIMAGE 96 | DEFPUSHBUTTON "OK",IDOK,127,302,50,14 97 | PUSHBUTTON "Cancel",IDCANCEL,179,302,50,14 98 | GROUPBOX "Icon",IDC_STATIC,314,4,55,32 99 | GROUPBOX "Maximum",IDC_STATIC,2,245,97,52 100 | GROUPBOX "Population Order",IDC_STATIC,103,245,274,25 101 | LTEXT "Source:",IDC_STATIC,2,30,26,8 102 | LTEXT "Criteria:",IDC_STATIC,2,58,24,8 103 | LTEXT "Format:",IDC_STATIC,2,100,24,8 104 | LTEXT "Label:",IDC_STATIC,2,3,20,8 105 | END 106 | 107 | IDD_QUICKQUERY DIALOGEX 0, 0, 326, 76 108 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 109 | CAPTION "Quick Query" 110 | FONT 8, "MS Sans Serif", 0, 0, 0x0 111 | BEGIN 112 | COMBOBOX IDC_CB_NOT,2,40,38,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 113 | COMBOBOX IDC_FIELD,46,40,65,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 114 | COMBOBOX IDC_OPERATOR,112,40,65,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 115 | EDITTEXT IDC_VALUE,178,40,89,13,ES_AUTOHSCROLL 116 | CONTROL "Expert Mode",IDC_EXPERT_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,55,56,10 117 | DEFPUSHBUTTON "OK",IDOK,83,58,50,14 118 | PUSHBUTTON "Cancel",IDCANCEL,142,58,50,14 119 | PUSHBUTTON "AND",IDC_AND,263,7,20,13 120 | PUSHBUTTON "OR",IDC_OR,285,7,14,13 121 | LTEXT "",IDC_ACCUM,2,3,253,34 122 | PUSHBUTTON "(",IDC_LEFT_PAREN,301,7,9,13 123 | PUSHBUTTON ")",IDC_RIGHT_PAREN,312,7,9,13 124 | PUSHBUTTON "Insert",IDC_BUTTON_INSERT,274,40,36,13 125 | PUSHBUTTON "Parenthesize",IDC_BUTTON_PARENTHESIZE,263,21,59,14 126 | PUSHBUTTON "Clear",IDC_BUTTON_CLEAR,302,62,20,10 127 | END 128 | 129 | IDD_STATIC_FOLDER_EDIT DIALOGEX 0, 0, 358, 87 130 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 131 | CAPTION "Edit Folder..." 132 | FONT 8, "MS Sans Serif", 0, 0, 0x0 133 | BEGIN 134 | DEFPUSHBUTTON "OK",IDOK,152,59,50,14 135 | PUSHBUTTON "Cancel",IDCANCEL,204,59,50,14 136 | EDITTEXT IDC_EDIT_VALUE,11,13,335,14,ES_AUTOHSCROLL 137 | ICON "",IDC_ICON_NORMAL,35,45,20,20,SS_CENTERIMAGE 138 | PUSHBUTTON "set...",IDC_SET_NORMAL,10,45,22,9 139 | PUSHBUTTON "reset",IDC_ICON_RESET,10,56,22,9 140 | CONTROL "Don't Browse",IDC_CHECK_NOBROWSE,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,68,44,58,10 141 | CONTROL "Don't Save",IDC_CHECK_NOSAVE,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,68,56,51,10 142 | GROUPBOX "Icon",-1,8,35,48,38 143 | GROUPBOX "Label",-1,7,3,344,28 144 | GROUPBOX "Options",-1,59,35,75,38,NOT WS_VISIBLE 145 | END 146 | 147 | IDD_CONFIG DIALOGEX 0, 0, 376, 293 148 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 149 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 150 | BEGIN 151 | PUSHBUTTON "Font",IDC_BTN_FONT,4,11,46,14 152 | PUSHBUTTON "Text Color",IDC_BTN_TEXT_COLOR,4,28,46,14 153 | PUSHBUTTON "Line Color",IDC_BTN_LINE_COLOR,4,45,46,14 154 | PUSHBUTTON "Back Color",IDC_BTN_BACK_COLOR,4,62,46,14 155 | GROUPBOX "Appearance",IDC_STATIC,0,0,55,189 156 | LTEXT "File Format:",IDC_STATIC,62,1,39,8 157 | LTEXT "Default Query Format:",IDC_STATIC,62,54,74,8 158 | EDITTEXT IDC_EDIT_FILE_FORMAT,62,12,242,13,ES_AUTOHSCROLL 159 | EDITTEXT IDC_EDIT_QUERY_FORMAT,62,65,242,13,ES_AUTOHSCROLL 160 | EDITTEXT IDC_EDIT_LIBRARY_PLAYLIST,64,90,242,13,ES_AUTOHSCROLL 161 | COMBOBOX IDC_EDGE_STYLE,4,90,46,61,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 162 | LTEXT "Edge style:",IDC_STATIC,2,79,37,8 163 | GROUPBOX "Bitmaps (Requires Restart to Take Effect)",IDC_STATIC,0,193,308,93 164 | CONTROL "Enable Bitmaps",IDC_ENABLE_BITMAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,203,64,10 165 | PUSHBUTTON "Leaf",IDC_BTN_LEAF,215,201,25,11 166 | PUSHBUTTON "Folder",IDC_BTN_FOLDER,243,201,25,11 167 | PUSHBUTTON "Query",IDC_BTN_QUERY,271,201,25,11 168 | EDITTEXT IDC_EDIT_MORE_BITMAPS,7,251,297,32,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL 169 | LTEXT "Additional Bitmaps: (filenames with complete path, Ctrl+enter for newlines)",IDC_STATIC,8,240,280,10 170 | LTEXT "Folder Format:",IDC_STATIC,62,28,48,8 171 | EDITTEXT IDC_EDIT_FOLDER_FORMAT,62,38,242,13,ES_AUTOHSCROLL 172 | CONTROL "no hscroll",IDC_NOHSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,107,46,10 173 | CONTROL "hide leaves",IDC_HIDELEAVES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,131,48,10 174 | CONTROL "hide root",IDC_HIDEROOT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,119,45,10 175 | CONTROL "hide lines",IDC_HIDELINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,143,45,10 176 | CONTROL "hide +/-",IDC_HIDEBUTTONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,155,42,10 177 | CONTROL "Load Windows Bitmaps",IDC_LOADSYSTEMBITMAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,73,203,89,10 178 | CONTROL "Activate library playlist when sending",IDC_ACTIVATE_LIBRARY_PLAYLIST, 179 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,104,135,10 180 | CONTROL "Rename last library playlist when sending",IDC_REMOVE_LAST_PLAYLIST, 181 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,115,147,10 182 | EDITTEXT IDC_ICON_PATH,7,226,297,13,ES_AUTOHSCROLL 183 | LTEXT "foobar2000 icon path:",IDC_STATIC,9,216,88,8 184 | GROUPBOX "Library Playlist",IDC_STATIC,60,78,252,51 185 | CONTROL "custom selection colors:",IDC_ALLOW_RGB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,69,143,87,10 186 | GROUPBOX "Custom Colors",IDC_STATIC,60,132,251,37 187 | PUSHBUTTON "Background (Focus)",IDC_BTN_SELECTION_FOCUSED,159,138,86,12 188 | PUSHBUTTON "Background (Non-Focus)",IDC_BTN_SELECTION_NONFOCUSED,159,151,86,12 189 | CONTROL "Use Default Queries if no file loaded",IDC_DEFAULT_QUERIES, 190 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,62,177,131,10 191 | PUSHBUTTON "Text (Non-Focus)",IDC_BTN_SELECTION_TEXT_NONFOCUS,247,151,60,12 192 | PUSHBUTTON "Text (Focus)",IDC_BTN_SELECTION_TEXT_FOCUS,247,138,60,12 193 | END 194 | 195 | IDD_TF_CONFIG DIALOGEX 0, 0, 378, 241 196 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 197 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 198 | BEGIN 199 | LTEXT "Track Finder Christopher Bowron - chris@bowron.us\nhttp://wiki.bowron.us/index.php/Foobar2000",IDC_STATIC,7,209,255,25 200 | GROUPBOX "Track Finder Format",IDC_STATIC,7,7,364,101 201 | EDITTEXT IDC_TF_FORMAT,11,17,355,86,ES_MULTILINE | ES_AUTOHSCROLL 202 | GROUPBOX "Selection Actions",IDC_STATIC,7,111,240,91 203 | COMBOBOX IDC_TF_ACTION1,11,122,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 204 | COMBOBOX IDC_TF_ACTION2,11,138,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 205 | COMBOBOX IDC_TF_ACTION3,11,154,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 206 | COMBOBOX IDC_TF_ACTION4,11,170,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 207 | COMBOBOX IDC_TF_ACTION5,11,186,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 208 | GROUPBOX "Maximum Files",IDC_STATIC,249,111,79,29 209 | EDITTEXT IDC_MAX,254,121,70,15,ES_AUTOHSCROLL 210 | END 211 | 212 | IDD_CONFIG_SCHEME DIALOGEX 0, 0, 305, 298 213 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 214 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 215 | BEGIN 216 | EDITTEXT IDC_EDIT_SCHEME_STARTUP,4,18,294,200,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL 217 | LTEXT "Scheme Starup Code:",IDC_STATIC,4,7,70,8 218 | PUSHBUTTON "Evaluate Now",IDC_BUTTON_SCHEME_EVAL_NOW,221,223,77,14 219 | END 220 | 221 | IDD_SEARCH DIALOGEX 0, 0, 190, 17 222 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 223 | EXSTYLE WS_EX_CONTROLPARENT 224 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 225 | BEGIN 226 | EDITTEXT IDC_SEARCH_STRING,1,1,187,14,ES_AUTOHSCROLL 227 | END 228 | 229 | IDD_CONFIG_MOUSE DIALOGEX 0, 0, 351, 298 230 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 231 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 232 | BEGIN 233 | GROUPBOX "Selection Actions",IDC_STATIC,4,7,271,45 234 | COMBOBOX IDC_SELECTION_ACTION_1,15,17,251,67,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 235 | COMBOBOX IDC_SELECTION_ACTION_2,15,33,251,58,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 236 | GROUPBOX "Double Click Action",IDC_STATIC,4,54,271,37 237 | CONTROL "Refresh Queries",IDC_REFRESH_QUERIES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,80,68,10 238 | GROUPBOX "Right Click Actions",IDC_STATIC,4,129,271,55 239 | COMBOBOX IDC_RIGHTCLICK_ACTION,15,140,251,56,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 240 | COMBOBOX IDC_RIGHTCLICK_ACTION_SHIFT,15,164,251,66,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 241 | LTEXT "with shift:",IDC_STATIC,15,156,70,8 242 | COMBOBOX IDC_DOUBLE_CLICK,15,66,251,52,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 243 | GROUPBOX "Middle Click Actions",IDC_STATIC,4,94,271,33 244 | COMBOBOX IDC_MIDDLECLICK,15,106,251,68,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 245 | GROUPBOX "Enter",IDC_STATIC,4,184,271,28 246 | COMBOBOX IDC_ENTER,14,193,251,66,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 247 | GROUPBOX "Space",IDC_STATIC,4,212,271,28 248 | COMBOBOX IDC_SPACE,13,222,251,66,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 249 | CONTROL "Process keyboard shortcuts",IDC_PROCESS_SHORTCUTS, 250 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,277,251,11 251 | EDITTEXT IDC_SELECTION_ACTION_LIMIT,279,35,32,12,ES_AUTOHSCROLL 252 | LTEXT "File Limit:",IDC_STATIC,280,25,30,8 253 | END 254 | 255 | IDD_DIALOG_READ_EVAL_PRINT DIALOGEX 0, 0, 246, 198 256 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU 257 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 258 | BEGIN 259 | EDITTEXT IDC_EDIT1,7,7,232,97,ES_AUTOHSCROLL 260 | EDITTEXT IDC_EDIT2,7,105,232,86,ES_AUTOHSCROLL 261 | END 262 | 263 | IDD_SCHEME_DROPLIST DIALOGEX 0, 0, 186, 73 264 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 265 | CAPTION "Dialog" 266 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 267 | BEGIN 268 | DEFPUSHBUTTON "OK",IDOK,41,52,50,14 269 | PUSHBUTTON "Cancel",IDCANCEL,94,52,50,14 270 | COMBOBOX IDC_LIST,7,36,172,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP 271 | LTEXT "Static",IDC_STATIC_PROMPT,7,7,172,19 272 | END 273 | 274 | IDD_SCHEME_STRING DIALOGEX 0, 0, 186, 71 275 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 276 | CAPTION "Dialog" 277 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 278 | BEGIN 279 | DEFPUSHBUTTON "OK",IDOK,41,50,50,14 280 | PUSHBUTTON "Cancel",IDCANCEL,94,50,50,14 281 | LTEXT "Static",IDC_STATIC_PROMPT,7,7,172,22 282 | EDITTEXT IDC_EDIT_RESPONSE,7,30,172,14,ES_AUTOHSCROLL 283 | END 284 | 285 | 286 | ///////////////////////////////////////////////////////////////////////////// 287 | // 288 | // DESIGNINFO 289 | // 290 | 291 | #ifdef APSTUDIO_INVOKED 292 | GUIDELINES DESIGNINFO 293 | BEGIN 294 | IDD_BLANK, DIALOG 295 | BEGIN 296 | LEFTMARGIN, 7 297 | RIGHTMARGIN, 217 298 | TOPMARGIN, 7 299 | BOTTOMMARGIN, 151 300 | END 301 | 302 | IDD_ICONSELECT, DIALOG 303 | BEGIN 304 | LEFTMARGIN, 7 305 | RIGHTMARGIN, 228 306 | TOPMARGIN, 7 307 | BOTTOMMARGIN, 159 308 | END 309 | 310 | IDD_QUERY, DIALOG 311 | BEGIN 312 | LEFTMARGIN, 2 313 | RIGHTMARGIN, 377 314 | BOTTOMMARGIN, 316 315 | END 316 | 317 | IDD_QUICKQUERY, DIALOG 318 | BEGIN 319 | LEFTMARGIN, 2 320 | RIGHTMARGIN, 322 321 | TOPMARGIN, 3 322 | BOTTOMMARGIN, 72 323 | END 324 | 325 | IDD_STATIC_FOLDER_EDIT, DIALOG 326 | BEGIN 327 | LEFTMARGIN, 7 328 | RIGHTMARGIN, 351 329 | VERTGUIDE, 55 330 | TOPMARGIN, 7 331 | BOTTOMMARGIN, 80 332 | END 333 | 334 | IDD_CONFIG, DIALOG 335 | BEGIN 336 | LEFTMARGIN, 7 337 | RIGHTMARGIN, 338 338 | VERTGUIDE, 50 339 | VERTGUIDE, 60 340 | VERTGUIDE, 62 341 | VERTGUIDE, 206 342 | VERTGUIDE, 211 343 | VERTGUIDE, 304 344 | VERTGUIDE, 338 345 | TOPMARGIN, 7 346 | BOTTOMMARGIN, 286 347 | END 348 | 349 | IDD_TF_CONFIG, DIALOG 350 | BEGIN 351 | LEFTMARGIN, 7 352 | RIGHTMARGIN, 371 353 | TOPMARGIN, 7 354 | BOTTOMMARGIN, 234 355 | END 356 | 357 | IDD_CONFIG_SCHEME, DIALOG 358 | BEGIN 359 | LEFTMARGIN, 4 360 | RIGHTMARGIN, 298 361 | VERTGUIDE, 15 362 | VERTGUIDE, 266 363 | VERTGUIDE, 275 364 | TOPMARGIN, 7 365 | BOTTOMMARGIN, 288 366 | END 367 | 368 | IDD_CONFIG_MOUSE, DIALOG 369 | BEGIN 370 | LEFTMARGIN, 4 371 | RIGHTMARGIN, 344 372 | VERTGUIDE, 15 373 | VERTGUIDE, 266 374 | VERTGUIDE, 275 375 | TOPMARGIN, 7 376 | BOTTOMMARGIN, 288 377 | END 378 | 379 | IDD_DIALOG_READ_EVAL_PRINT, DIALOG 380 | BEGIN 381 | LEFTMARGIN, 7 382 | RIGHTMARGIN, 239 383 | TOPMARGIN, 7 384 | BOTTOMMARGIN, 191 385 | END 386 | 387 | IDD_SCHEME_DROPLIST, DIALOG 388 | BEGIN 389 | LEFTMARGIN, 7 390 | RIGHTMARGIN, 179 391 | TOPMARGIN, 7 392 | BOTTOMMARGIN, 66 393 | END 394 | 395 | IDD_SCHEME_STRING, DIALOG 396 | BEGIN 397 | LEFTMARGIN, 7 398 | RIGHTMARGIN, 179 399 | TOPMARGIN, 7 400 | BOTTOMMARGIN, 64 401 | END 402 | END 403 | #endif // APSTUDIO_INVOKED 404 | 405 | 406 | ///////////////////////////////////////////////////////////////////////////// 407 | // 408 | // Bitmap 409 | // 410 | 411 | IDB_BITMAPS BITMAP "bitmap1.bmp" 412 | #endif // English (U.S.) resources 413 | ///////////////////////////////////////////////////////////////////////////// 414 | 415 | 416 | 417 | #ifndef APSTUDIO_INVOKED 418 | ///////////////////////////////////////////////////////////////////////////// 419 | // 420 | // Generated from the TEXTINCLUDE 3 resource. 421 | // 422 | 423 | 424 | ///////////////////////////////////////////////////////////////////////////// 425 | #endif // not APSTUDIO_INVOKED 426 | 427 | -------------------------------------------------------------------------------- /foo_playlist_tree/foo_playlist_tree.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 56 | 59 | 62 | 65 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 96 | 100 | 101 | 110 | 113 | 116 | 119 | 122 | 125 | 137 | 140 | 143 | 146 | 158 | 161 | 164 | 167 | 170 | 173 | 176 | 179 | 183 | 184 | 185 | 186 | 187 | 188 | 193 | 196 | 197 | 198 | 203 | 206 | 207 | 210 | 211 | 214 | 215 | 218 | 219 | 222 | 223 | 226 | 227 | 230 | 231 | 234 | 235 | 238 | 239 | 242 | 243 | 246 | 247 | 250 | 251 | 254 | 255 | 258 | 259 | 260 | 265 | 268 | 269 | 272 | 273 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | -------------------------------------------------------------------------------- /foo_playlist_tree/playlist_tree.txt: -------------------------------------------------------------------------------- 1 | = Intro = 2 | 3 | Playlist Tree, at its core, begas as a playlist manager that builds 4 | playlists as trees. Most audio players use a list based approach to 5 | playlists, but I wanted to be able to create hierarchies in my 6 | playlists, so that I could have greater control of how I listened to 7 | music. 8 | 9 | Playlist Tree has become one of the most powerful playlist managers 10 | that I have used. That power comes at a price of a fairly steep 11 | learning curve to use it to its full potential. 12 | 13 | PT acts a Columns UI Panel, and this article will assume that you 14 | already known how to make the PT Panel appear in your layout. If you 15 | don't know how to operate Columns UI, please ask someone other than me 16 | ;-). This article also assumes some familiarity with foobar2000 17 | titleformatting. 18 | 19 | = Nodes = 20 | 21 | PT has 3 types of nodes in its trees. First, it supports nodes that 22 | represent a single playable item. These items can be dropped onto the 23 | playlist tree panel from a playlist view or from the Windows 24 | Explorer. Second, it has what I refer to as static folders, which 25 | can contain playable items or other static folders, or the third type 26 | of nodes, the query. Queries are what give PT its power. 27 | 28 | All of these nodes can be moved around by dragging and dropping them in the 29 | panel, and items can be copied rather than moved if you hold down 30 | shift when you begin dragging. 31 | 32 | When you drop folders from windows explorer, it will create folders 33 | for each directory, and subdirectory, and playable nodes for audio files. 34 | 35 | == Queries == 36 | 37 | Queries are PT's automatic playlists. They let you enter the criteria 38 | for which tracks should show up in the results, and how you want the 39 | results to be laid out in the tree. They also let you place limits on 40 | the size of resultant list in the form of number of tracks, duration, 41 | filesize and number of subfolders. 42 | 43 | === Source === 44 | (see: http://wiki.bowron.us/index.php/Playlist_Tree_Tutorial#Source_Directives) 45 | 46 | Source instructs PT which files to use as possible candidates for 47 | the playlist. In most situations @database is probably the desired 48 | source. But other sources exist such as @drop<> for using playlists 49 | and directories as a source, @node<> for using other tree nodes as 50 | source and @playlists and @playlist 51 | 52 | === Criteria === 53 | 54 | Criteria lets you prune files from your source. If you want all the 55 | files in the source to show up in the resultant tree, then leave the 56 | criteria blank. Otherwise, you can use the same syntax as 57 | foo_playlist_gen to remove non-matching tracks. For example, if you 58 | wanted only tracks by the Beatles that you have rated 4 or higher, you 59 | can use "artist HAS beatles AND rating GREATER 3" for your criteria. 60 | 61 | === Format === 62 | 63 | Format specifies how the resultant playlist will be arranged. It use 64 | the foobar2000 titleformatting syntax. Tree layers are split using 65 | the | character. If you wanted all the files to be put into folders 66 | based on their artist, then the album and finally the title, the 67 | format string would look like "%artist%|%album%|%title%". 68 | 69 | === Population Sort Order === 70 | 71 | Population sort order determines the order in which songs go through 72 | the playlist generation process. Its especially useful when you are 73 | using the maximum options. For example, if you wanted a list of 10 74 | random songs, you would set the Population Sort Order to "$rand()" and 75 | the maximum to 10 tracks. 76 | 77 | === Playlist Generation Process === 78 | 79 | Under the hood, the tree in a query basically gets generated like this: 80 | 81 | 1 - make a list of all possible songs based on source 82 | 2 - sort the list based on population sort order. 83 | 3 - prune off items that don't match criteria 84 | 4 - for each item, add it to the tree based on format. 85 | 5 - stop if you reach the end of the list or hit the maximum whatever. 86 | 6 - if Sort by display name is check, sort by display name. 87 | 88 | = Random Things You Should Known When Using PT = 89 | 90 | If you hold shift while draggind and dropping nodes, you can make a 91 | copy rather than move. 92 | 93 | By default, right clicking on a node will give the normal foobar2000 94 | context menu options, holding down shift while right clicking or 95 | middle clicking on a node will give you the playlist tree specific 96 | context menu. (These are configurable) 97 | 98 | PT is very configurable. To get to the preferences select 99 | File->Preferences from main menu, then look under Media 100 | Library->Playlist Tree Panel. 101 | 102 | You can configure what happens when you select, double click, and 103 | middle click on nodes. 104 | 105 | PT adds its main menu options under Library->Playlist Tree. 106 | 107 | In addition to the main Playlist Tree panel, PT also adds a Playlist 108 | Tree Search panel you can use in your Columns UI layout to quickly 109 | search your trees. 110 | 111 | You probably also want my foo_cwb_hooks plugin. 112 | http://wiki.bowron.us/index.php/Foobar2000:Hooks 113 | 114 | I like getting email telling me how much you like my programs. I also 115 | keep track of bugs and feature requests. If you have questions on how 116 | to do something, please use the forums. Other people may benefit 117 | from the information or respond that way. My email is chris@bowron.us 118 | 119 | The playlist tree discussion on the foobar2000 forums is at 120 | http://www.hydrogenaudio.org/forums/index.php?showtopic=29435 121 | 122 | I maintain my own forums at http://bowron.us/smf/index.php 123 | 124 | I make and distribute PT because I enjoy using it myself, and I think 125 | others also enjoy it. But I also have a job, a fiancee, a mortgage 126 | payment, and a life. I wish I could implement every cool feature 127 | people suggest and respond to everyone's post, but I have a limited 128 | amount of time that I can spend on this, so please forgive me if you 129 | don't hear back from me on a bug or a feature request or a question. 130 | 131 | = Scheme = 132 | 133 | As of version 3.0.0, PT contains an embedded version of the Scheme 134 | programming language. This is intended for advanced users. 135 | 136 | The embedded scheme has the following benefits: 137 | 138 | 1 - It is a real programming language with things like conditionals 139 | and loops. 140 | 141 | 2 - Because it is a real programming language, you can do things that 142 | are flat out impossible with a normal playlist tree query. 143 | 144 | 3 - Because it is a real programming language, I can add ways to 145 | script foobar2000 actions. 146 | 147 | 4 - It's easier to use than foobar2000 titleformatting for complex 148 | tasks (when you get the hang of it). 149 | 150 | 5 - It's hardcore. 151 | 152 | See the MORE section for more information and links to examples. 153 | 154 | = MORE = 155 | 156 | More information about playlist tree can be found on the components 157 | homepage at http://wiki.bowron.us/index.php/Playlist_Tree. 158 | 159 | More information about the embedded version of scheme in playlist tree 160 | can be found at http://download.plt-scheme.org/doc/mzscheme/. I also 161 | suggest finding on online scheme tutorial or the book "The Little Schemer". 162 | 163 | Example queries can be found at http://wiki.bowron.us/index.php/Example_Queries. 164 | -------------------------------------------------------------------------------- /foo_playlist_tree/preferences.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../common/menu_stuff.h" 4 | 5 | void setup_context_item_maps_pt( HWND wnd, context_item_map * map, int m ) 6 | { 7 | for ( int n = 0; n < m; n++ ) 8 | { 9 | int id = map[n].id; 10 | HWND hwnd_control = GetDlgItem( wnd, id ); 11 | 12 | SendMessage( hwnd_control, CB_RESETCONTENT, 0,0 ); 13 | 14 | // add empty string option... 15 | uSendDlgItemMessageText( wnd, id, CB_ADDSTRING, 0, "" ); 16 | 17 | pfc::string8_fastalloc tmp; 18 | for ( int z = 0; z < tabsize(mm_map); z ++ ) 19 | { 20 | if ( strcmp( mm_map[z].local_path, "" ) != 0 ) 21 | { 22 | tmp.set_string( "[local] " ); 23 | tmp.add_string( mm_map[z].local_path ); 24 | uSendDlgItemMessageText( wnd, id, CB_ADDSTRING, 0, tmp ); 25 | } 26 | } 27 | 28 | service_enum_t menus; 29 | service_ptr_t item; 30 | 31 | while ( menus.next( item ) ) 32 | { 33 | pfc::string8_fastalloc menuPath; 34 | pfc::string8_fastalloc menuName; 35 | for ( int i = 0; i < item->get_num_items(); i++ ) 36 | { 37 | item->get_item_default_path( i, menuPath ); 38 | item->get_item_name( i, menuName ); 39 | 40 | if ( !menuPath.is_empty() ) 41 | { 42 | menuPath.add_string( "/" ); 43 | } 44 | menuPath.add_string( menuName ); 45 | uSendDlgItemMessageText( wnd, id, CB_ADDSTRING, 0, menuPath ); 46 | } 47 | 48 | uSendDlgItemMessageText( wnd, id, CB_SELECTSTRING, -1, (*map[n].var) ); 49 | } 50 | } 51 | 52 | } 53 | 54 | static const GUID guid_preferences = { 0x85d7363c, 0xf8dd, 0x46c7, { 0xbd, 0x4a, 0xbe, 0xf2, 0x43, 0x3, 0xbf, 0x8a } }; 55 | static const GUID guid_preferences_mouse = { 0x2977da50, 0x9771, 0x46c8, { 0x83, 0x7e, 0x3e, 0xed, 0x7b, 0xc2, 0xc4, 0x13 } }; 56 | static const GUID guid_preferences_scheme = { 0xb4b84026, 0x27d1, 0x42e7, { 0xa7, 0xfd, 0xee, 0xd5, 0x5a, 0xc3, 0x62, 0xe3 } }; 57 | 58 | text_box_map var_map[] = 59 | { 60 | { IDC_EDIT_QUERY_FORMAT, &cfg_query_display }, 61 | { IDC_EDIT_FILE_FORMAT, &cfg_file_format }, 62 | { IDC_EDIT_LIBRARY_PLAYLIST, &cfg_library_playlist }, 63 | { IDC_EDIT_FOLDER_FORMAT, &cfg_folder_display }, 64 | { IDC_EDIT_MORE_BITMAPS, &cfg_bitmaps_more }, 65 | { IDC_ICON_PATH, &cfg_icon_path }, 66 | }; 67 | 68 | context_item_map context_menu_map[] = 69 | { 70 | //{ IDC_SELECTION_ACTION_1, &cfg_selection_action_1 }, 71 | //{ IDC_SELECTION_ACTION_2, &cfg_selection_action_2 }, 72 | { IDC_DOUBLE_CLICK, &cfg_doubleclick }, 73 | { IDC_RIGHTCLICK_ACTION, &cfg_rightclick }, 74 | { IDC_RIGHTCLICK_ACTION_SHIFT, &cfg_rightclick_shift }, 75 | { IDC_MIDDLECLICK, &cfg_middleclick }, 76 | { IDC_ENTER, &cfg_enter }, 77 | { IDC_SPACE, &cfg_space }, 78 | }; 79 | 80 | int_map int_var_map_mouse[] = 81 | { 82 | { IDC_SELECTION_ACTION_LIMIT, &cfg_selection_action_limit }, 83 | }; 84 | 85 | bool_map bool_var_map[] = 86 | { 87 | { IDC_ENABLE_BITMAPS, &cfg_bitmaps_enabled }, 88 | { IDC_HIDELEAVES, &cfg_hideleaves }, 89 | { IDC_HIDEROOT, &cfg_hideroot }, 90 | { IDC_NOHSCROLL, &cfg_nohscroll }, 91 | { IDC_HIDELINES, &cfg_hidelines }, 92 | { IDC_HIDEBUTTONS, &cfg_hidebuttons }, 93 | { IDC_LOADSYSTEMBITMAPS, &cfg_bitmaps_loadsystem }, 94 | { IDC_ACTIVATE_LIBRARY_PLAYLIST, &cfg_activate_library_playlist }, 95 | { IDC_REMOVE_LAST_PLAYLIST, &cfg_remove_last_playlist }, 96 | { IDC_ALLOW_RGB, &cfg_custom_colors }, 97 | { IDC_DEFAULT_QUERIES, &cfg_use_default_queries }, 98 | }; 99 | 100 | bool_map bool_var_map_mouse[] = 101 | { 102 | { IDC_REFRESH_QUERIES, &cfg_repopulate_doubleclick }, 103 | { IDC_PROCESS_SHORTCUTS, &cfg_process_keydown }, 104 | }; 105 | 106 | list_map list_var_map[] = 107 | { 108 | { IDC_EDGE_STYLE, &cfg_edge_style, g_edge_styles } 109 | }; 110 | 111 | color_map color_var_map[] = 112 | { 113 | { IDC_BTN_SELECTION_TEXT_FOCUS, &cfg_selection_text }, 114 | { IDC_BTN_SELECTION_TEXT_NONFOCUS, &cfg_selection_text_nofocus }, 115 | { IDC_BTN_SELECTION_FOCUSED, &cfg_color_selection_focused }, 116 | { IDC_BTN_SELECTION_NONFOCUSED, &cfg_color_selection_nonfocused }, 117 | { IDC_BTN_LINE_COLOR, &cfg_line_color }, 118 | { IDC_BTN_TEXT_COLOR, &cfg_text_color }, 119 | { IDC_BTN_BACK_COLOR, &cfg_back_color }, 120 | }; 121 | 122 | script_map script_var_map[] = 123 | { 124 | { IDC_SELECTION_ACTION_1, &cfg_selection_action_1, &cfg_selection_action1_guid_command, &cfg_selection_action1_guid_subcommand }, 125 | { IDC_SELECTION_ACTION_2, &cfg_selection_action_2, &cfg_selection_action2_guid_command, &cfg_selection_action2_guid_subcommand }, 126 | }; 127 | 128 | text_box_map scheme_edit_map[] = 129 | { 130 | { IDC_EDIT_SCHEME_STARTUP, &cfg_scheme_startup }, 131 | }; 132 | 133 | class playlist_tree_preferences : public preferences_page, public cwb_menu_helpers 134 | { 135 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 136 | { 137 | switch ( msg ) 138 | { 139 | case WM_INITDIALOG: 140 | { 141 | int n, m; 142 | 143 | setup_text_boxes( wnd, var_map, tabsize(var_map) ); 144 | setup_bool_maps( wnd, bool_var_map, tabsize(bool_var_map) ); 145 | 146 | m = tabsize( list_var_map ); 147 | for ( n = 0; n < m; n++ ) 148 | { 149 | SendMessage( GetDlgItem( wnd, list_var_map[n].id), CB_RESETCONTENT, 0,0 ); 150 | for ( int k = 0; ; k++ ) 151 | { 152 | char *label = list_var_map[n].labels[k]; 153 | if ( label == NULL ) 154 | { 155 | break; 156 | } 157 | uSendDlgItemMessageText( wnd, list_var_map[n].id, CB_ADDSTRING, 0, label ); 158 | } 159 | SendMessage( GetDlgItem( wnd, list_var_map[n].id ), CB_SETCURSEL, list_var_map[n].var->get_value(), 0 ); 160 | } 161 | 162 | 163 | } 164 | break; 165 | 166 | case WM_COMMAND: 167 | process_text_boxes( wnd, wp, var_map, tabsize(var_map) ); 168 | 169 | if ( process_bool_map( wnd, wp, bool_var_map, tabsize(bool_var_map) ) ) 170 | { 171 | playlist_tree_panel::g_update_appearance(); 172 | } 173 | else if ( process_color_map( wnd, wp, color_var_map, tabsize( color_var_map ) ) ) 174 | { 175 | playlist_tree_panel::g_update_appearance(); 176 | } 177 | 178 | if ( wp >> 16 == CBN_SELCHANGE ) 179 | { 180 | int the_list = wp & 0xffff; 181 | int n; 182 | int m = tabsize( list_var_map ); 183 | 184 | for ( n = 0; n < m; n++ ) 185 | { 186 | if ( list_var_map[n].id == the_list ) 187 | { 188 | int s = SendDlgItemMessage( wnd, the_list, CB_GETCURSEL, 0, 0 ); 189 | if ( s != CB_ERR ) 190 | { 191 | ( *list_var_map[n].var ) = s; 192 | playlist_tree_panel::g_update_appearance(); 193 | } 194 | break; 195 | } 196 | } 197 | } 198 | 199 | switch ( wp ) 200 | { 201 | case BN_CLICKED<<16|IDC_BTN_LEAF: 202 | { 203 | if ( g_active_trees.get_count() > 0 ) 204 | { 205 | int ic = select_icon( wnd, g_active_trees[0]->m_imagelist ); 206 | 207 | if ( ic >= 0 ) 208 | { 209 | cfg_bitmap_leaf = ic; 210 | } 211 | } 212 | else 213 | { 214 | uMessageBox( wnd, "Playlist Tree must be active to select icons.", "Playlist Tree", MB_OK ); 215 | } 216 | } 217 | break; 218 | 219 | case BN_CLICKED<<16|IDC_BTN_FOLDER: 220 | { 221 | if ( g_active_trees.get_count() > 0 ) 222 | { 223 | int ic = select_icon( wnd, g_active_trees[0]->m_imagelist ); 224 | 225 | if ( ic >= 0 ) 226 | { 227 | cfg_bitmap_folder = ic; 228 | } 229 | } 230 | else 231 | { 232 | uMessageBox( wnd, "Playlist Tree must be active to select icons.", "Playlist Tree", MB_OK ); 233 | } 234 | break; 235 | } 236 | 237 | case BN_CLICKED<<16|IDC_HIDELEAVES: 238 | case BN_CLICKED<<16|IDC_HIDEROOT: 239 | { 240 | for ( int n = 0; n < g_active_trees.get_count(); n++ ) 241 | { 242 | g_active_trees[n]->setup_tree(); 243 | } 244 | } 245 | break; 246 | 247 | case BN_CLICKED<<16|IDC_BTN_QUERY: 248 | { 249 | if ( g_active_trees.get_count() > 0 ) 250 | { 251 | int ic = select_icon( wnd, g_active_trees[0]->m_imagelist ); 252 | 253 | if ( ic >= 0 ) 254 | { 255 | cfg_bitmap_query = ic; 256 | } 257 | } 258 | else 259 | { 260 | uMessageBox( wnd, "Playlist Tree must be active to select icons.", "Playlist Tree", MB_OK ); 261 | } 262 | break; 263 | } 264 | 265 | case BN_CLICKED<<16|IDC_BTN_FONT: 266 | { 267 | LOGFONT temp = cfg_font; 268 | CHOOSEFONT choose; 269 | memset( &choose, 0, sizeof(choose) ); 270 | choose.lStructSize = sizeof(choose); 271 | choose.Flags=CF_SCREENFONTS|CF_FORCEFONTEXIST|CF_INITTOLOGFONTSTRUCT; 272 | choose.nFontType=SCREEN_FONTTYPE; 273 | choose.hwndOwner = wnd; 274 | choose.lpLogFont = &temp; 275 | 276 | if ( ChooseFont( &choose ) ) 277 | { 278 | cfg_font = *choose.lpLogFont; 279 | playlist_tree_panel::g_update_appearance(); 280 | } 281 | } 282 | break; 283 | 284 | } 285 | break; 286 | 287 | } 288 | return false; 289 | } 290 | 291 | virtual HWND create(HWND parent) 292 | { 293 | return uCreateDialog( IDD_CONFIG, parent, dialog_proc ); 294 | } 295 | 296 | virtual const char * get_name() 297 | { 298 | return "Playlist Tree Panel"; 299 | } 300 | 301 | virtual GUID get_guid() 302 | { 303 | return guid_preferences; 304 | } 305 | 306 | virtual GUID get_parent_guid() 307 | { 308 | return preferences_page::guid_media_library; 309 | } 310 | 311 | //! Queries whether this page supports "reset page" feature. 312 | virtual bool reset_query() 313 | { 314 | return false; 315 | } 316 | 317 | virtual void reset() 318 | { 319 | } 320 | 321 | virtual bool get_help_url(pfc::string_base & p_out) 322 | { 323 | p_out.set_string( URL_HELP ); 324 | return true; 325 | } 326 | }; 327 | 328 | static service_factory_single_t g_pref; 329 | 330 | class mouse_preferences : public preferences_page, public cwb_menu_helpers 331 | { 332 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 333 | { 334 | switch ( msg ) 335 | { 336 | case WM_INITDIALOG: 337 | setup_context_item_maps_pt( wnd, context_menu_map, tabsize(context_menu_map) ); 338 | setup_bool_maps( wnd, bool_var_map_mouse, tabsize(bool_var_map_mouse) ); 339 | setup_int_maps( wnd, int_var_map_mouse, tabsize(int_var_map_mouse) ); 340 | setup_script_maps( wnd, script_var_map, tabsize(script_var_map) ); 341 | break; 342 | 343 | case WM_COMMAND: 344 | process_context_item_map( wnd, wp, context_menu_map, tabsize(context_menu_map) ); 345 | process_bool_map( wnd, wp, bool_var_map_mouse, tabsize(bool_var_map_mouse) ); 346 | process_int_maps( wnd, wp, int_var_map_mouse, tabsize(int_var_map_mouse) ); 347 | process_script_map( wnd, wp, script_var_map, tabsize(script_var_map) ); 348 | break; 349 | } 350 | return false; 351 | } 352 | 353 | virtual HWND create(HWND parent) 354 | { 355 | return uCreateDialog( IDD_CONFIG_MOUSE, parent, dialog_proc ); 356 | } 357 | 358 | virtual const char * get_name() 359 | { 360 | return "Mouse & Keyboard"; 361 | } 362 | 363 | virtual GUID get_guid() 364 | { 365 | return guid_preferences_mouse; 366 | } 367 | 368 | virtual GUID get_parent_guid() 369 | { 370 | return guid_preferences; 371 | } 372 | 373 | //! Queries whether this page supports "reset page" feature. 374 | virtual bool reset_query() 375 | { 376 | return false; 377 | } 378 | 379 | virtual void reset() 380 | { 381 | } 382 | 383 | virtual bool get_help_url(pfc::string_base & p_out) 384 | { 385 | p_out.set_string( URL_HELP ); 386 | return true; 387 | } 388 | }; 389 | 390 | static service_factory_single_t g_pref_mouse; 391 | 392 | 393 | class scheme_preferences : public preferences_page, public cwb_menu_helpers 394 | { 395 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 396 | { 397 | switch ( msg ) 398 | { 399 | case WM_INITDIALOG: 400 | setup_text_boxes( wnd, scheme_edit_map, tabsize(scheme_edit_map) ); 401 | break; 402 | 403 | case WM_COMMAND: 404 | process_text_boxes( wnd, wp, scheme_edit_map, tabsize(scheme_edit_map) ); 405 | 406 | switch ( wp ) 407 | { 408 | case BN_CLICKED<<16|IDC_BUTTON_SCHEME_EVAL_NOW: 409 | if ( !g_scheme_installed ) 410 | { 411 | install_scheme_globals(); 412 | } 413 | else 414 | { 415 | scm_eval_startup(); 416 | } 417 | break; 418 | } 419 | break; 420 | 421 | } 422 | return false; 423 | } 424 | 425 | virtual HWND create(HWND parent) 426 | { 427 | return uCreateDialog( IDD_CONFIG_SCHEME, parent, dialog_proc ); 428 | } 429 | 430 | virtual const char * get_name() 431 | { 432 | return "Scheme"; 433 | } 434 | 435 | virtual GUID get_guid() 436 | { 437 | return guid_preferences_scheme; 438 | } 439 | 440 | virtual GUID get_parent_guid() 441 | { 442 | return guid_preferences; 443 | } 444 | 445 | //! Queries whether this page supports "reset page" feature. 446 | virtual bool reset_query() 447 | { 448 | return false; 449 | } 450 | 451 | virtual void reset() 452 | { 453 | } 454 | 455 | virtual bool get_help_url(pfc::string_base & p_out) 456 | { 457 | p_out.set_string( URL_HELP ); 458 | return true; 459 | } 460 | }; 461 | 462 | static service_factory_single_t g_pref_scheme; 463 | -------------------------------------------------------------------------------- /foo_playlist_tree/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwbowron/foobar2000-plugins/6ba30d7b3afc0ee85f5cc2903012c1dfcee132bd/foo_playlist_tree/readme.txt -------------------------------------------------------------------------------- /foo_playlist_tree/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_playlist_tree.rc 4 | // 5 | #define IDD_BLANK 101 6 | #define IDB_BITMAPS 102 7 | #define IDD_CONFIG 103 8 | #define IDD_TF_CONFIG 104 9 | #define IDD_CONFIG_SCHEME 105 10 | #define IDD_SEARCH 106 11 | #define IDD_DIALOG_READ_EVAL_PRINT 107 12 | #define IDD_SCHEME_DROPLIST 108 13 | #define IDD_SCHEME_STRING 109 14 | #define IDD_QUERY 111 15 | #define IDD_QUICKQUERY 113 16 | #define IDD_STATIC_FOLDER_EDIT 115 17 | #define IDD_ICONSELECT 117 18 | #define IDD_CONFIG_MOUSE 118 19 | #define IDC_TREE 1001 20 | #define IDC_SORT_AFTER 1002 21 | #define IDC_BTN_FONT 1004 22 | #define IDC_BTN_TEXT_COLOR 1005 23 | #define IDC_BTN_LINE_COLOR 1006 24 | #define IDC_BTN_BACK_COLOR 1007 25 | #define IDC_BTN_SELECTION_FOCUSED 1008 26 | #define IDC_SELECTION_ACTION_2 1009 27 | #define IDC_BTN_SELECTION_NONFOCUSED 1009 28 | #define IDC_SELECTION_ACTION_1 1010 29 | #define IDC_BTN_SELECTION_TEXT_NONFOCUS 1010 30 | #define IDC_EDIT_FILE_FORMAT 1011 31 | #define IDC_EDIT_QUERY_FORMAT 1012 32 | #define IDC_DOUBLE_CLICK 1013 33 | #define IDC_BTN_SELECTION_TEXT_FOCUS 1013 34 | #define IDC_EDIT_LIBRARY_PLAYLIST 1014 35 | #define IDC_MIDDLECLICK 1014 36 | #define IDC_EDGE_STYLE 1015 37 | #define IDC_ENABLE_BITMAPS 1016 38 | #define IDC_BTN_LEAF 1017 39 | #define IDC_VALUE 1018 40 | #define IDC_BTN_FOLDER 1018 41 | #define IDC_BTN_QUERY 1019 42 | #define IDC_EDIT_MORE_BITMAPS 1020 43 | #define IDC_EDIT_FOLDER_FORMAT 1021 44 | #define IDC_NOHSCROLL 1022 45 | #define IDC_HIDELEAVES 1023 46 | #define IDC_TF_FORMAT 1023 47 | #define IDC_HIDEROOT 1024 48 | #define IDC_TF_ACTION1 1024 49 | #define IDC_HIDELINES 1025 50 | #define IDC_TF_ACTION2 1025 51 | #define IDC_HIDEBUTTONS 1026 52 | #define IDC_TF_ACTION3 1026 53 | #define IDC_TF_ACTION4 1027 54 | #define IDC_REFRESH_QUERIES 1027 55 | #define IDC_ICON_PATH 1027 56 | #define IDC_TF_ACTION5 1028 57 | #define IDC_LOADSYSTEMBITMAPS 1028 58 | #define IDC_RIGHTCLICK_ACTION 1029 59 | #define IDC_ALLOW_RGB 1029 60 | #define IDC_RIGHTCLICK_ACTION_SHIFT 1030 61 | #define IDC_ACTIVATE_LIBRARY_PLAYLIST 1031 62 | #define IDC_ENTER 1031 63 | #define IDC_REMOVE_LAST_PLAYLIST 1032 64 | #define IDC_SEARCH_STRING 1032 65 | #define IDC_SPACE 1032 66 | #define IDC_PROCESS_SHORTCUTS 1034 67 | #define IDC_SELECTION_ACTION_LIMIT 1035 68 | #define IDC_SORT_CRITERIA 1036 69 | #define IDC_DEFAULT_QUERIES 1036 70 | #define IDC_EDIT_SCHEME_STARTUP 1038 71 | #define IDC_BUTTON_SCHEME_EVAL_NOW 1039 72 | #define IDC_EDIT1 1040 73 | #define IDC_EDIT2 1041 74 | #define IDC_COMBO1 1042 75 | #define IDC_LIST 1042 76 | #define IDC_STATIC_PROMPT 1043 77 | #define IDC_EDIT_RESPONSE 1044 78 | #define IDC_LABEL 1062 79 | #define IDC_QUERY 1063 80 | #define IDC_FORMAT 1064 81 | #define IDC_EDIT_SOURCE 1065 82 | #define IDC_MAX 1067 83 | #define IDC_REVERSE 1071 84 | #define IDC_TRACKS 1073 85 | #define IDC_MINUTES 1074 86 | #define IDC_MEGS 1075 87 | #define IDC_SUBFOLDERS 1080 88 | #define IDC_FIELD 1102 89 | #define IDC_OPERATOR 1103 90 | #define IDC_EDIT_VALUE 1110 91 | #define IDC_AND 1116 92 | #define IDC_OR 1117 93 | #define IDC_ACCUM 1118 94 | #define IDC_CB_NOT 1119 95 | #define IDC_ICONLIST 1121 96 | #define IDC_ICON_NORMAL 1125 97 | #define IDC_SET_NORMAL 1127 98 | #define IDC_ICON_RESET 1129 99 | #define IDC_CHECK_NOBROWSE 1130 100 | #define IDC_CHECK_NOSAVE 1131 101 | #define IDC_CHECK_AUTOREFRESH 1132 102 | #define IDC_LEFT_PAREN 1145 103 | #define IDC_RIGHT_PAREN 1146 104 | #define IDC_EXPERT_MODE 1147 105 | #define IDC_BUTTON_INSERT 1149 106 | #define IDC_BUTTON_PARENTHESIZE 1150 107 | #define IDC_BUTTON_CLEAR 1151 108 | 109 | // Next default values for new objects 110 | // 111 | #ifdef APSTUDIO_INVOKED 112 | #ifndef APSTUDIO_READONLY_SYMBOLS 113 | #define _APS_NEXT_RESOURCE_VALUE 110 114 | #define _APS_NEXT_COMMAND_VALUE 40001 115 | #define _APS_NEXT_CONTROL_VALUE 1045 116 | #define _APS_NEXT_SYMED_VALUE 101 117 | #endif 118 | #endif 119 | -------------------------------------------------------------------------------- /foo_playlist_tree/sexp_reader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | node * read_sexp( FILE * ); 4 | 5 | int is_whitespace( char ch ) 6 | { 7 | if ( ch == ' ' ) return 1; 8 | if ( ch == '\t') return 1; 9 | if ( ch == '\r') return 1; 10 | if ( ch == '\n') return 1; 11 | if ( ch == '\0') return 1; 12 | return 0; 13 | } 14 | 15 | int get_next_token( FILE * f, pfc::string8 & result ) 16 | { 17 | static char internal_buffer[1024]; 18 | static int buffer_runner = -1; 19 | 20 | if ( ( buffer_runner < 0 ) || ( buffer_runner >= strlen( internal_buffer) ) ) 21 | { 22 | if ( feof( f ) ) return 0; 23 | 24 | memset( internal_buffer, 0, sizeof(internal_buffer) ); 25 | fgets( internal_buffer, sizeof(internal_buffer), f ); 26 | buffer_runner = 0; 27 | } 28 | 29 | // zoom thru whitespace 30 | while ( is_whitespace( internal_buffer[buffer_runner] ) ) 31 | { 32 | buffer_runner++; 33 | 34 | if ( buffer_runner >= strlen( internal_buffer ) ) 35 | { 36 | if ( feof( f ) ) return 0; 37 | 38 | memset( internal_buffer, 0, sizeof(internal_buffer) ); 39 | fgets( internal_buffer, sizeof(internal_buffer), f ); 40 | buffer_runner = 0; 41 | } 42 | } 43 | 44 | // assume we are not looking at whitespace 45 | if ( internal_buffer[buffer_runner] == '(' ) 46 | { 47 | buffer_runner++; 48 | result.set_string( "(" ); 49 | } 50 | else if ( internal_buffer[buffer_runner] == ')' ) 51 | { 52 | buffer_runner++; 53 | result.set_string( ")" ); 54 | } 55 | else if ( internal_buffer[buffer_runner] == '\"' ) 56 | { 57 | // READING STRING 58 | result.reset(); 59 | 60 | buffer_runner++; 61 | 62 | 63 | //while ( internal_buffer[buffer_runner] != '\"' ) 64 | for (;;) 65 | { 66 | char ch = internal_buffer[buffer_runner]; 67 | 68 | if ( ch == '\"' ) 69 | { 70 | if ( internal_buffer[buffer_runner+1] == '\"') 71 | { 72 | buffer_runner++; 73 | } 74 | else 75 | { 76 | break; 77 | } 78 | } 79 | 80 | result.add_byte( ch ); 81 | buffer_runner++; 82 | 83 | if ( buffer_runner >= strlen( internal_buffer ) ) 84 | { 85 | if ( feof ( f ) ) return 0; 86 | 87 | memset( internal_buffer, 0, sizeof(internal_buffer) ); 88 | fgets( internal_buffer, sizeof(internal_buffer), f ); 89 | buffer_runner = 0; 90 | } 91 | } 92 | 93 | // uMessageBox( NULL, result, "Token", MB_OK ); 94 | 95 | buffer_runner++; 96 | } 97 | else 98 | { 99 | // READING SYMBOL 100 | int start = buffer_runner; 101 | 102 | while ( 1 ) 103 | { 104 | if ( is_whitespace( internal_buffer[buffer_runner] ) ) 105 | break; 106 | 107 | if ( internal_buffer[buffer_runner] == ')' ) 108 | break; 109 | 110 | buffer_runner++; 111 | 112 | } 113 | 114 | result.set_string( &internal_buffer[ start ], buffer_runner - start ); 115 | 116 | if ( strcmp( result, "nil" ) == 0 ) 117 | { 118 | result.reset(); 119 | } 120 | } 121 | 122 | #if 0 123 | FILE * ftrace = fopen( "c:\\temp\\playlist_tree.log", "a" ); 124 | fprintf( ftrace, "position: %d, token: %s\n", ftell(ftrace), (const char *)result ); 125 | fclose( ftrace); 126 | #endif 127 | // console::info( string_printf( "Token: '%s'", (const char *) result ) ); 128 | return 1; 129 | } 130 | 131 | int read_sexp_children( FILE *f, node *parent ) 132 | { 133 | pfc::string8 token; 134 | 135 | get_next_token( f, token ); 136 | 137 | if ( strcmp( token, "(" ) != 0 ) 138 | { 139 | console::warning( pfc::string_printf( "Error reading playlist file near character %d - token %s - expected (", ftell( f ), (const char *)token)); 140 | return -1; 141 | } 142 | 143 | int count = 0; 144 | node *n; 145 | 146 | while ( n = read_sexp( f ) ) 147 | { 148 | parent->add_child( n ); 149 | count++; 150 | } 151 | 152 | return count; 153 | } 154 | 155 | enum { SEXP_TYPE_UNKNOWN, SEXP_TYPE_LEAF, SEXP_TYPE_FOLDER, SEXP_TYPE_QUERY }; 156 | 157 | node * read_sexp( FILE *f ) 158 | { 159 | pfc::string8 token; 160 | 161 | get_next_token( f, token ); 162 | 163 | if ( strcmp( token, ")" ) == 0 ) 164 | { 165 | return NULL; 166 | } 167 | 168 | if ( strcmp( token, "(" ) != 0 ) 169 | { 170 | console::warning( 171 | pfc::string_printf( "Error reading playlist tree file near character %d - token '%s' - expected (", 172 | ftell( f ), (const char *) token )); 173 | return NULL; 174 | } 175 | 176 | get_next_token( f, token ); 177 | 178 | int type = SEXP_TYPE_UNKNOWN; 179 | 180 | if ( strcmp( token, "LEAF" ) == 0 ) type = SEXP_TYPE_LEAF; 181 | else if ( strcmp( token, "FOLDER" ) == 0 ) type = SEXP_TYPE_FOLDER; 182 | else if ( strcmp( token, "QUERY" ) == 0 ) type = SEXP_TYPE_QUERY; 183 | 184 | if ( !type ) 185 | { 186 | console::warning( 187 | pfc::string_printf( "Error reading playlist tree file near character %d - token %s", 188 | ftell( f ), (const char *)token )); 189 | return NULL; 190 | } 191 | 192 | pfc::string8 name; 193 | get_next_token( f, name ); 194 | node * result; 195 | 196 | // leaf 197 | if ( type == SEXP_TYPE_LEAF ) 198 | { 199 | pfc::string8 path; 200 | int subsong = 0; 201 | 202 | get_next_token( f, path ); 203 | 204 | while ( get_next_token( f, token ) ) 205 | { 206 | if ( strcmp( token, ")" ) == 0) 207 | { 208 | break; 209 | } 210 | if ( strcmp( token, ":SUBSONG" ) == 0 ) 211 | { 212 | get_next_token( f, token ); 213 | subsong = atoi( token ); 214 | } 215 | else 216 | { 217 | console::warning( pfc::string_printf( "Unknown Token: '%s', near character %d", 218 | (const char *) token, 219 | ftell( f ))); 220 | } 221 | } 222 | 223 | static_api_ptr_t db; 224 | 225 | metadb_handle_ptr h; 226 | db->handle_create( h, make_playable_location( path, subsong ) ); 227 | result = new leaf_node( name, h ); 228 | 229 | //h->handle_release(); 230 | } 231 | else if ( type == SEXP_TYPE_FOLDER ) 232 | { 233 | get_next_token( f, token ); 234 | 235 | result = new folder_node( name, atoi( token ) ); 236 | 237 | while ( get_next_token( f, token ) ) 238 | { 239 | if ( strcmp( token, ")" ) == 0 ) break; 240 | 241 | if ( strcmp( token, ":CONTENTS" ) == 0 ) 242 | { 243 | read_sexp_children( f, result ); 244 | } 245 | } 246 | } 247 | else if ( type == SEXP_TYPE_QUERY ) 248 | { 249 | query_node *result = new query_node( name ); 250 | 251 | get_next_token( f, token ); 252 | 253 | result->m_expanded = atoi( token ); 254 | 255 | get_next_token( f, result->m_source ); 256 | get_next_token( f, result->m_query_criteria ); 257 | get_next_token( f, result->m_query_format ); 258 | get_next_token( f, result->m_query_handle_sort_criteria ); 259 | //get_next_token( f, result->m_sort_criteria ); 260 | get_next_token( f, token ); 261 | 262 | result->m_sort_after_populate = ( strcmp( token, "0" ) != 0 ); 263 | 264 | while ( get_next_token( f, token ) ) 265 | { 266 | if ( strcmp( token, ")" ) == 0 ) 267 | { 268 | break; 269 | } 270 | else if ( strcmp( token, ":MAX-TRACKS" ) == 0 ) 271 | { 272 | get_next_token( f, token ); 273 | result->m_query_limit = atoi( token ); 274 | result->m_limit_criteria = MAX_CRIT_TRACKS; 275 | } 276 | else if ( strcmp( token, ":MAX-LENGTH" ) == 0 ) 277 | { 278 | get_next_token( f, token ); 279 | result->m_query_limit = atoi( token ); 280 | result->m_limit_criteria = MAX_CRIT_LENGTH; 281 | } 282 | else if ( strcmp( token, ":MAX-SIZE" ) == 0 ) 283 | { 284 | get_next_token( f, token ); 285 | result->m_query_limit = atoi( token ); 286 | result->m_limit_criteria = MAX_CRIT_SIZE; 287 | } 288 | else if ( strcmp( token, ":MAX-FOLDERS" ) == 0 ) 289 | { 290 | get_next_token( f, token ); 291 | result->m_query_limit = atoi( token ); 292 | result->m_limit_criteria = MAX_CRIT_SUBFOLDER; 293 | } 294 | else if ( strcmp( token, ":REVERSE" ) == 0 ) 295 | { 296 | get_next_token( f, token ); 297 | 298 | if ( (strcmp( token, "t" ) == 0 ) || (strcmp( token, "1" ) == 0 ) ) 299 | { 300 | result->m_reverse_populate_query = 1; 301 | } 302 | else 303 | { 304 | result->m_reverse_populate_query = 0; 305 | } 306 | } 307 | else if ( strcmp( token, ":CONTENTS" ) == 0 ) 308 | { 309 | read_sexp_children( f, result ); 310 | } 311 | else if ( strcmp( token, ":GUID" ) == 0 ) 312 | { 313 | get_next_token( f, token ); 314 | GUID guid_temp = pfc::GUID_from_text( token ); 315 | 316 | // console::printf( "GUID = %s", token.get_ptr() ); 317 | 318 | if ( guid_temp != pfc::guid_null ) 319 | { 320 | result->m_guid = guid_temp; 321 | } 322 | /* 323 | else 324 | { 325 | console::printf( "Ignoring NULL GUID" ); 326 | } 327 | */ 328 | } 329 | else 330 | { 331 | console::warning( 332 | pfc::string_printf( "unexpected token %s, near character %d", 333 | (const char *)token, ftell( f ) ) ); 334 | } 335 | } 336 | 337 | return result; 338 | } 339 | else 340 | { 341 | console::warning( 342 | pfc::string_printf( "Unexpected Token Near character %d", 343 | ftell( f ) ) ); 344 | } 345 | 346 | return result; 347 | } 348 | 349 | 350 | static node * read_sexp_file( const char * path ) 351 | { 352 | FILE * f = fopen( path, "r" ); 353 | 354 | if ( !f ) 355 | { 356 | console::warning( pfc::string_printf( "opening %s failed", path ) ); 357 | return NULL; 358 | } 359 | 360 | return read_sexp( f ); 361 | } 362 | 363 | static node * do_load_helper( const char * file ) 364 | { 365 | FILE *playlist; 366 | 367 | pfc::stringcvt::string_wide_from_utf8 wide_file( file ); 368 | 369 | playlist = _wfopen( wide_file, _T("r") ); 370 | 371 | if ( playlist == NULL ) 372 | { 373 | console::warning( pfc::string_printf( "Opening File Failed" ) ); 374 | return NULL; 375 | } 376 | 377 | node * n = read_sexp( playlist ); 378 | 379 | return n; 380 | } 381 | 382 | node * load( pfc::string8 * out_name ) 383 | { 384 | /* 385 | TCHAR fileName[MAX_PATH]; 386 | 387 | TCHAR *filters = 388 | _T("Playlist Tree SEXP (*.") _T(PLAYLIST_TREE_EXTENSION) _T(")\0") 389 | _T("*.") _T(PLAYLIST_TREE_EXTENSION) _T("\0") 390 | _T("All files (*.*)\0") 391 | _T("*.*\0") 392 | _T("\0"); 393 | 394 | OPENFILENAME blip; 395 | memset((void*)&blip, 0, sizeof(blip)); 396 | memset(fileName, 0, sizeof(fileName)); 397 | blip.lpstrFilter = filters; 398 | blip.lStructSize = sizeof(OPENFILENAME); 399 | blip.lpstrFile = fileName; 400 | blip.nMaxFile = sizeof(fileName)/ sizeof(*fileName); 401 | blip.lpstrTitle = _T("Open..."); 402 | 403 | blip.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 404 | */ 405 | 406 | pfc::string8 filename; 407 | if ( get_save_name( filename, false, true ) ) 408 | { 409 | node * n = do_load_helper( filename ); 410 | 411 | if ( out_name ) 412 | { 413 | out_name->set_string( filename ); 414 | } 415 | 416 | return n; 417 | } 418 | return NULL; 419 | } 420 | 421 | -------------------------------------------------------------------------------- /foo_playlist_tree/trackfinder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static const GUID guid_tf_context = { 0x10c60205, 0x8404, 0x4c63, { 0x89, 0xbd, 0x76, 0x1b, 0xba, 0x97, 0x11, 0xb8 } }; 4 | 5 | 6 | #if 1 7 | class simple_node; 8 | int simple_node_compare( const simple_node * a, const simple_node * b ); 9 | 10 | class simple_node 11 | { 12 | public: 13 | metadb_handle_ptr m_handle; 14 | pfc::ptr_list_t m_children; 15 | pfc::string8 m_label; 16 | int m_id; 17 | 18 | simple_node( const char * label ) 19 | { 20 | m_label.set_string( label ); 21 | } 22 | 23 | simple_node ( const char * label, metadb_handle_ptr p ) 24 | { 25 | m_label.set_string( label ); 26 | m_handle = p; 27 | } 28 | 29 | ~simple_node() 30 | { 31 | m_children.delete_all(); 32 | } 33 | 34 | simple_node * find_by_id( int id ) 35 | { 36 | if ( m_id == id ) return this; 37 | 38 | for ( int n = 0; n < m_children.get_count(); n++ ) 39 | { 40 | simple_node * sn = m_children[n]->find_by_id( id ); 41 | if ( sn ) return sn; 42 | } 43 | return false; 44 | } 45 | 46 | virtual bool get_entries( pfc::list_base_t & list ) 47 | { 48 | if ( m_handle.is_valid() ) 49 | { 50 | list.add_item( m_handle ); 51 | } 52 | 53 | for ( int n = 0; n < m_children.get_count(); n++ ) 54 | { 55 | m_children[n]->get_entries( list ); 56 | } 57 | return true; 58 | } 59 | 60 | virtual void sort( bool recurse ) 61 | { 62 | m_children.sort_t( &simple_node_compare ); 63 | 64 | if ( recurse ) 65 | { 66 | for ( int n = 0; n < m_children.get_count(); n++ ) 67 | { 68 | m_children[n]->sort( true ); 69 | } 70 | } 71 | } 72 | 73 | virtual simple_node * add_child_conditional( const char * str ) 74 | { 75 | for ( unsigned i = 0; i < m_children.get_count(); i++) 76 | { 77 | if ( stricmp_utf8_ex( m_children[i]->m_label, ~0, str, ~0 ) == 0 ) 78 | { 79 | return m_children[i]; 80 | } 81 | } 82 | 83 | simple_node * fn = new simple_node( str ); 84 | m_children.add_item( fn ); 85 | return fn; 86 | } 87 | 88 | simple_node * add_delimited_child( const char *strings, metadb_handle_ptr handle ) 89 | { 90 | const char *car = strings; 91 | const char *cdr = strings + strlen( strings ) + 1; 92 | 93 | if ( !*cdr ) 94 | { 95 | simple_node * sn = new simple_node( car, handle ); 96 | m_children.add_item( sn ); 97 | return sn; 98 | } 99 | else 100 | { 101 | simple_node *n = add_child_conditional( car ); 102 | 103 | if ( !n ) 104 | { 105 | return NULL; 106 | } 107 | 108 | return n->add_delimited_child( cdr, handle ); 109 | } 110 | } 111 | 112 | virtual void add_to_hmenu( HMENU menu, int & baseID, pfc::ptr_list_t options ) 113 | { 114 | if ( m_children.get_count() == 0 ) 115 | { 116 | add_actions_to_hmenu( menu, baseID, options ); 117 | } 118 | 119 | if ( m_children.get_count() > 1 ) 120 | { 121 | uAppendMenu( menu, MF_POPUP, (UINT_PTR) CreatePopupMenu(), "All" ); 122 | uAppendMenu( menu, MF_SEPARATOR, 0, 0 ); 123 | } 124 | 125 | for ( int n = 0; n < m_children.get_count(); n++ ) 126 | { 127 | HMENU child = CreatePopupMenu(); 128 | m_children[n]->m_id = (int)child; 129 | uAppendMenu( menu, MF_POPUP, (UINT_PTR)child, m_children[n]->m_label ); 130 | } 131 | } 132 | 133 | }; 134 | 135 | int simple_node_compare( const simple_node * a, const simple_node * b ) 136 | { 137 | return stricmp_utf8_ex( a->m_label, ~0, b->m_label, ~0 ); 138 | } 139 | 140 | #endif 141 | 142 | //folder_node * generate_trackfinder_tree( const pfc::list_base_const_t & list ) 143 | simple_node * generate_trackfinder_tree( const pfc::list_base_const_t & list ) 144 | { 145 | int i, j, max_j; 146 | 147 | pfc::ptr_list_t track_formats; 148 | 149 | string_split( cfg_tf_format, "\r\n", track_formats ); 150 | 151 | //folder_node *qt_tree = new folder_node( "Track Tree" ); 152 | simple_node *qt_tree = new simple_node( "Track Tree" ); 153 | 154 | pfc::string8 handle_info; 155 | 156 | max_j = track_formats.get_count(); 157 | 158 | for (i = 0; i < list.get_count(); i++) 159 | { 160 | for ( j = 0; j < max_j; j++) 161 | { 162 | list[i]->format_title( NULL, handle_info, 163 | (const char *)track_formats[j]->get_ptr(), NULL ); 164 | 165 | query_ready_string delimited( handle_info ); 166 | 167 | //node * temp = qt_tree->add_delimited_child( delimited, list[i] ); 168 | simple_node * temp = qt_tree->add_delimited_child( delimited, list[i] ); 169 | } 170 | } 171 | 172 | qt_tree->sort( true ); 173 | track_formats.delete_all(); 174 | 175 | return qt_tree; 176 | } 177 | 178 | int process_trackfinder_selection( node *tree, int ID, pfc::ptr_list_t * actions ) 179 | { 180 | if ( actions->get_count() == 1 ) 181 | { 182 | if ( tree->m_id == ID ) 183 | { 184 | run_context_command( actions->get_item(0)->get_ptr(), NULL, tree ); 185 | return true; 186 | } 187 | } 188 | else 189 | { 190 | int n = ID - tree->m_id; 191 | 192 | if ( ( n >= 0 ) && ( n < actions->get_count() ) ) 193 | { 194 | run_context_command( actions->get_item(n)->get_ptr(), NULL, tree ); 195 | return true; 196 | } 197 | } 198 | 199 | if ( !tree->is_leaf() ) 200 | { 201 | folder_node * fn = (folder_node*) tree; 202 | for ( int i = 0; i < fn->get_num_children(); i++ ) 203 | { 204 | if ( process_trackfinder_selection( fn->m_children[i], ID, actions ) ) 205 | { 206 | return true; 207 | } 208 | } 209 | } 210 | return false; 211 | } 212 | 213 | pfc::ptr_list_t * g_actions; 214 | int g_runningID = 1; 215 | pfc::string8 g_last_tf_command; 216 | //node * g_last_tf_node; 217 | simple_node * g_last_tf_node; 218 | 219 | static BOOL CALLBACK tfProc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 220 | { 221 | //static node * menuNode = NULL; 222 | static simple_node * menuNode = NULL; 223 | 224 | switch ( msg ) 225 | { 226 | case WM_INITDIALOG: 227 | //menuNode = (node *) lp; 228 | menuNode = (simple_node *) lp; 229 | ShowWindow( wnd, SW_HIDE ); 230 | break; 231 | 232 | case WM_MENUSELECT: 233 | { 234 | //console::printf( "WM_SELECT" ); 235 | 236 | int item = LOWORD(wp); 237 | int flags = HIWORD(wp); 238 | if ( flags & MF_POPUP ) 239 | { 240 | //pfc::string8 label; 241 | //uGetMenuString( (HMENU)lp, item, label, MF_BYPOSITION ); 242 | //console::printf( "MF_POPUP: %s, item = %d, flags = 0x%x", 243 | // (const char *) label, item, flags ); 244 | 245 | //node * nd = menuNode->find_by_id( lp ); 246 | simple_node * nd = menuNode->find_by_id( lp ); 247 | 248 | if ( nd ) 249 | { 250 | /* 251 | if ( nd->is_leaf() ) 252 | { 253 | } 254 | else 255 | */ 256 | { 257 | HMENU sub = GetSubMenu( (HMENU)lp, item ); 258 | int z = GetMenuItemCount( sub ); 259 | //int zz; 260 | 261 | /* 262 | //console::printf( "SubItemCount = %d", z ); 263 | for ( zz = 0; zz < z; zz++ ) 264 | { 265 | DeleteMenu( sub, 0, MF_BYPOSITION ); 266 | //console::printf( "Deleting Submenu" ); 267 | } 268 | */ 269 | 270 | //folder_node * fn = (folder_node*) nd; 271 | simple_node * fn = (simple_node*) nd; 272 | 273 | if ( fn->m_children.get_count() > 1 ) 274 | { 275 | item -= 2; 276 | } 277 | 278 | if ( item >= 0 ) 279 | { 280 | if ( z == 0 ) 281 | { 282 | fn->m_children[item]->add_to_hmenu( sub, g_runningID, *g_actions ); 283 | } 284 | } 285 | else if ( item == -2 ) 286 | { 287 | g_last_tf_node = fn; 288 | 289 | if ( z == 0 ) 290 | { 291 | add_actions_to_hmenu( sub, g_runningID, *g_actions ); 292 | } 293 | //console::printf( "you selected all" ); 294 | } 295 | } 296 | //console::printf( "node: %s", (const char *)nd->m_label ); 297 | } 298 | else 299 | { 300 | //console::printf( "node not found: %d", lp ); 301 | } 302 | // uAppendMenu( GetSubMenu( (HMENU)lp, item ), MF_STRING, 1000, "w00t" ); 303 | } 304 | else 305 | { 306 | //node * nd = menuNode->find_by_id( lp ); 307 | simple_node * nd = menuNode->find_by_id( lp ); 308 | if ( nd ) 309 | { 310 | g_last_tf_node = nd; 311 | //console::printf( "node = %s", (const char *)nd->m_label ); 312 | } 313 | pfc::string8 label; 314 | uGetMenuString( (HMENU)lp, item, label, MF_BYCOMMAND ); 315 | //console::printf( "not popup: %s", (const char *)label ); 316 | 317 | g_last_tf_command.set_string( label ); 318 | } 319 | } 320 | return 0; 321 | } 322 | return 0; 323 | } 324 | 325 | void track_finder( const pfc::list_base_const_t & p_data ) 326 | { 327 | if ( (cfg_trackfinder_max > 0) && ( p_data.get_count() > cfg_trackfinder_max ) ) 328 | { 329 | int zoop = MessageBox( core_api::get_main_window(), 330 | _T("The selection contains more files that the current maximum defined in the preferences. ") 331 | _T("Running Track Finder on such large sets may result in significant delay and possible ") 332 | _T("crash due to windows resource issues. It is recommended that you select a smaller ") 333 | _T("set of files for track finder. Do you REALLY want to continue?"), 334 | _T("Track Finder maximum exceeded"), MB_OKCANCEL ); 335 | 336 | if ( zoop != IDOK ) 337 | { 338 | return; 339 | } 340 | } 341 | 342 | //folder_node * n = generate_trackfinder_tree( p_data ); 343 | simple_node * n = generate_trackfinder_tree( p_data ); 344 | 345 | pfc::ptr_list_t actions; 346 | 347 | if ( !cfg_tf_action1.is_empty() ) 348 | { 349 | actions.add_item( new pfc::string8( cfg_tf_action1 ) ); 350 | } 351 | if ( !cfg_tf_action2.is_empty() ) 352 | { 353 | actions.add_item( new pfc::string8( cfg_tf_action2 ) ); 354 | } 355 | if ( !cfg_tf_action3.is_empty() ) 356 | { 357 | actions.add_item( new pfc::string8( cfg_tf_action3 ) ); 358 | } 359 | if ( !cfg_tf_action4.is_empty() ) 360 | { 361 | actions.add_item( new pfc::string8( cfg_tf_action4 ) ); 362 | } 363 | if ( !cfg_tf_action5.is_empty() ) 364 | { 365 | actions.add_item( new pfc::string8( cfg_tf_action5 ) ); 366 | } 367 | 368 | POINT pt; 369 | GetCursorPos( &pt ); 370 | 371 | #if 1 372 | g_actions = &actions; 373 | g_runningID = 1; 374 | 375 | HMENU m2 = CreatePopupMenu(); 376 | int ID2 = 1; 377 | n->m_id = (int)m2; 378 | n->add_to_hmenu( m2, ID2, actions ); 379 | // console::printf( "ID2 = %d", ID2 ); 380 | HWND trackFinderWnd = uCreateDialog( IDD_BLANK, core_api::get_main_window(), tfProc, (LPARAM)n ); 381 | HWND parent2 = trackFinderWnd; 382 | 383 | int cmd2 = TrackPopupMenuEx( m2, TPM_RIGHTBUTTON | TPM_RETURNCMD, 384 | pt.x, pt.y, parent2, 0 ); 385 | 386 | DestroyWindow( trackFinderWnd ); 387 | 388 | // console::printf( "Selection = %d", cmd2 ); 389 | // console::printf( "action: %s", (const char *) g_last_tf_command ); 390 | 391 | if ( cmd2 && g_last_tf_node ) 392 | { 393 | // console::printf( "node: %s", (const char *) g_last_tf_node->m_label ); 394 | metadb_handle_list handles; 395 | g_last_tf_node->get_entries( handles ); 396 | 397 | //run_context_command( g_last_tf_command, NULL, g_last_tf_node ); 398 | run_context_command( g_last_tf_command, &handles, NULL ); 399 | 400 | 401 | } 402 | 403 | DestroyMenu( m2 ); 404 | 405 | #else 406 | int ID = 1; 407 | HMENU m = generate_node_menu_complex( n, ID, true, &actions ); 408 | console::printf( "trackfinder items: %d", ID - 1 ); 409 | 410 | 411 | HWND parent; 412 | 413 | parent = core_api::get_main_window(); 414 | 415 | int cmd = TrackPopupMenuEx( m, TPM_RIGHTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD, 416 | pt.x, pt.y, parent, 0 ); 417 | 418 | if ( cmd ) 419 | { 420 | process_trackfinder_selection( n, cmd, &actions ); 421 | } 422 | else 423 | { 424 | DWORD dw = GetLastError(); 425 | if ( dw != 0 ) 426 | { 427 | LPVOID lpMsgBuf; 428 | FormatMessage( 429 | FORMAT_MESSAGE_ALLOCATE_BUFFER | 430 | FORMAT_MESSAGE_FROM_SYSTEM, 431 | NULL, 432 | dw, 433 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 434 | (LPTSTR) &lpMsgBuf, 435 | 0, NULL ); 436 | 437 | pfc::stringcvt::string_utf8_from_wide msg( (TCHAR*)lpMsgBuf ); 438 | 439 | pfc::string_printf warnmsg( "Track Finder failed: %s", msg.get_ptr() ); 440 | console::warning( warnmsg ); 441 | LocalFree( lpMsgBuf ); 442 | } 443 | } 444 | 445 | DestroyMenu( m ); 446 | #endif 447 | 448 | delete n; 449 | actions.delete_all(); 450 | } 451 | 452 | class tf_context : public contextmenu_item_simple 453 | { 454 | unsigned get_num_items() 455 | { 456 | return 1; 457 | } 458 | 459 | GUID get_item_guid( unsigned int n ) 460 | { 461 | return guid_tf_context; 462 | } 463 | 464 | void get_item_name( unsigned n, pfc::string_base & out ) 465 | { 466 | out.set_string( "Track Finder..." ); 467 | } 468 | 469 | void get_item_default_path( unsigned n, pfc::string_base & out ) 470 | { 471 | out.set_string( "" ); 472 | } 473 | 474 | bool get_item_description( unsigned n, pfc::string_base & out ) 475 | { 476 | out.set_string( "Generate a quick file selector from a set of files" ); 477 | return true; 478 | } 479 | 480 | virtual void context_command(unsigned p_index,const pfc::list_base_const_t & p_data,const GUID& p_caller) 481 | { 482 | track_finder( p_data ); 483 | } 484 | }; 485 | 486 | static service_factory_single_t g_tf_context; -------------------------------------------------------------------------------- /foo_playlist_tree/tree_drop_source.h: -------------------------------------------------------------------------------- 1 | class tree_drop_source : public IDropSource 2 | { 3 | public: 4 | long refcount; 5 | node * m_node; 6 | playlist_tree_panel * m_panel; 7 | 8 | tree_drop_source( playlist_tree_panel * panel, node * n ) : refcount(1) 9 | { 10 | m_panel = panel; 11 | m_node = n; 12 | } 13 | 14 | virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID iid, void ** ppvObject ) 15 | { 16 | if (ppvObject==0) 17 | { 18 | return E_INVALIDARG; 19 | } 20 | else if (iid == IID_IUnknown) 21 | { 22 | AddRef(); 23 | *ppvObject = (IUnknown*)this; 24 | return S_OK; 25 | } 26 | else if (iid == IID_IDropSource) 27 | { 28 | AddRef(); 29 | *ppvObject = (IDropSource*)this; 30 | return S_OK; 31 | } 32 | else 33 | { 34 | return E_NOINTERFACE; 35 | } 36 | } 37 | 38 | virtual ULONG STDMETHODCALLTYPE AddRef() 39 | { 40 | return InterlockedIncrement(&refcount); 41 | } 42 | 43 | virtual ULONG STDMETHODCALLTYPE Release() 44 | { 45 | return InterlockedDecrement(&refcount); 46 | } 47 | 48 | virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( BOOL fEscapePressed, DWORD grfKeyState ); 49 | 50 | virtual HRESULT STDMETHODCALLTYPE GiveFeedback( DWORD dwEffect ); 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /foo_playlist_tree/tree_drop_target.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class tree_drop_target : public IDropTarget 4 | { 5 | private: 6 | int refCount; 7 | 8 | public: 9 | 10 | playlist_tree_panel * m_panel; 11 | node * m_target; 12 | 13 | 14 | tree_drop_target( playlist_tree_panel * p ) 15 | { 16 | m_panel = p; 17 | refCount = 0; 18 | } 19 | 20 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,void ** ppvObject) 21 | { 22 | if (ppvObject==0) 23 | { 24 | return E_INVALIDARG; 25 | } 26 | else if (iid == IID_IUnknown) 27 | { 28 | AddRef(); 29 | *ppvObject = (IUnknown*)this; 30 | return S_OK; 31 | } 32 | else if (iid == IID_IDropTarget) 33 | { 34 | AddRef(); 35 | *ppvObject = (IDropTarget*)this; 36 | return S_OK; 37 | } 38 | return E_NOINTERFACE; 39 | } 40 | 41 | ULONG STDMETHODCALLTYPE AddRef() 42 | { 43 | refCount++; 44 | return refCount; 45 | } 46 | 47 | ULONG STDMETHODCALLTYPE Release() 48 | { 49 | refCount--; 50 | return refCount; 51 | } 52 | 53 | HRESULT STDMETHODCALLTYPE DragEnter( IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect); 54 | 55 | HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect); 56 | 57 | HRESULT STDMETHODCALLTYPE DragLeave( void ); 58 | 59 | HRESULT STDMETHODCALLTYPE Drop( IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect); 60 | }; 61 | -------------------------------------------------------------------------------- /foo_playlist_tree/tree_search.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | static const GUID guid_tree_searcher = { 0x9fdc37c6, 0x22af, 0x4461, { 0x92, 0xb7, 0x27, 0xac, 0x4c, 0xde, 0xfd, 0xf } }; 4 | 5 | #define WM_SETCOLOR (WM_APP+1) 6 | 7 | #define MY_TEXT_COLOR (cfg_text_color) 8 | #define COLOR_MISSING (RGB(255,0,0)) 9 | 10 | static WNDPROC EditProc; 11 | 12 | class tree_searcher : public ui_extension::window 13 | { 14 | static LRESULT CALLBACK EditBoxHook( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 15 | { 16 | switch ( msg ) 17 | { 18 | case WM_CHAR: 19 | switch ( wp ) 20 | { 21 | case VK_RETURN: 22 | { 23 | pfc::string8 string; 24 | uGetWindowText( wnd, string ); 25 | 26 | if ( g_last_active_tree ) 27 | { 28 | if ( g_last_active_tree->search( string ) ) 29 | { 30 | PostMessage( GetParent(wnd), WM_SETCOLOR, MY_TEXT_COLOR, 0 ); 31 | } 32 | else 33 | { 34 | PostMessage( GetParent(wnd), WM_SETCOLOR, COLOR_MISSING, 0 ); 35 | } 36 | } 37 | } 38 | break; 39 | 40 | case VK_ESCAPE: 41 | g_last_active_tree->search( NULL ); 42 | uSetWindowText( wnd, "" ); 43 | PostMessage( GetParent(wnd), WM_SETCOLOR, MY_TEXT_COLOR, 0 ); 44 | break; 45 | 46 | default: 47 | PostMessage( GetParent(wnd), WM_SETCOLOR, MY_TEXT_COLOR, 0 ); 48 | break; 49 | } 50 | 51 | break; 52 | } 53 | return uCallWindowProc( EditProc, wnd, msg, wp, lp ); 54 | } 55 | 56 | static BOOL CALLBACK dialog_proc( HWND wnd, UINT msg, WPARAM wp, LPARAM lp ) 57 | { 58 | static HBRUSH brush = NULL; 59 | static int edit_color = MY_TEXT_COLOR; 60 | 61 | switch ( msg ) 62 | { 63 | case WM_DESTROY: 64 | if ( brush ) 65 | { 66 | DeleteObject( brush ); 67 | } 68 | return false; 69 | 70 | case WM_SETCOLOR: 71 | edit_color = wp; 72 | InvalidateRect( wnd, NULL, TRUE ); 73 | break; 74 | 75 | case WM_CTLCOLOREDIT: 76 | { 77 | SetTextColor((HDC)wp, edit_color ); 78 | SetBkColor( (HDC)wp, cfg_back_color ); 79 | 80 | if ( brush ) 81 | { 82 | DeleteObject( brush ); 83 | } 84 | 85 | brush = CreateSolidBrush( cfg_back_color ); 86 | SelectObject( (HDC) wp, brush ); 87 | return (BOOL)brush; 88 | } 89 | break; 90 | 91 | case WM_INITDIALOG: 92 | { 93 | EditProc = uHookWindowProc( GetDlgItem( wnd, IDC_SEARCH_STRING ), EditBoxHook ); 94 | } 95 | break; 96 | 97 | case WM_GETMINMAXINFO: 98 | { 99 | LPMINMAXINFO info = (LPMINMAXINFO) lp; 100 | info->ptMinTrackSize.y = 22; 101 | return 0; 102 | } 103 | 104 | case WM_SIZE: 105 | { 106 | int height = 20; 107 | int offset = 1; 108 | 109 | RECT r; 110 | GetWindowRect( wnd, &r ); 111 | SetWindowPos( GetDlgItem( wnd, IDC_SEARCH_STRING ), 0, 112 | offset, offset, r.right-r.left - 2 * offset, height, 113 | SWP_NOZORDER ); 114 | } 115 | break; 116 | 117 | } 118 | return FALSE; 119 | } 120 | 121 | public: 122 | HWND m_wnd; 123 | 124 | ui_extension::window_host_ptr m_host; 125 | 126 | tree_searcher() 127 | { 128 | m_wnd = NULL; 129 | } 130 | 131 | unsigned get_type() const 132 | { 133 | return ui_extension::type_toolbar; 134 | } 135 | 136 | void destroy_window() 137 | { 138 | dialog_proc( m_wnd, WM_DESTROY, 0, 0 ); 139 | m_wnd = NULL; 140 | } 141 | 142 | void get_category( pfc::string_base & out ) const 143 | { 144 | out.set_string( "Toolbars" ); 145 | } 146 | 147 | virtual bool get_description( pfc::string_base & out ) const 148 | { 149 | out.set_string( "Playlist Tree Search Tool" ); 150 | return true; 151 | } 152 | 153 | virtual bool get_short_name( pfc::string_base & out ) const 154 | { 155 | out.set_string( "Playlist Tree Search" ); 156 | return true; 157 | } 158 | 159 | virtual void get_name( pfc::string_base & out ) const 160 | { 161 | out.set_string( "Playlist Tree Search" ); 162 | } 163 | 164 | const GUID & get_extension_guid() const 165 | { 166 | return guid_tree_searcher; 167 | } 168 | 169 | void get_size_limits( ui_extension::size_limit_t & p_out ) const 170 | { 171 | p_out.min_height = 20; 172 | p_out.min_width = 30; 173 | } 174 | 175 | virtual HWND get_wnd() const 176 | { 177 | return m_wnd; 178 | } 179 | 180 | virtual bool is_available( const ui_extension::window_host_ptr & p_host) const 181 | { 182 | return ( m_wnd == NULL ); 183 | } 184 | 185 | virtual HWND create_or_transfer_window( HWND wnd_parent, const ui_extension::window_host_ptr & p_host, const ui_helpers::window_position_t & p_position ) 186 | { 187 | if ( m_wnd ) 188 | { 189 | ShowWindow( m_wnd, SW_HIDE ); 190 | SetParent( get_wnd(), wnd_parent ); 191 | SetWindowPos( get_wnd(), NULL, p_position.x, p_position.y, p_position.cx, p_position.cy, SWP_NOZORDER ); 192 | m_host->relinquish_ownership( get_wnd() ); 193 | return m_wnd; 194 | } 195 | else 196 | { 197 | m_host = p_host; 198 | m_wnd = uCreateDialog( IDD_SEARCH, wnd_parent, dialog_proc, (LPARAM)this ); 199 | 200 | 201 | switch ( cfg_edge_style ) 202 | { 203 | case EE_NONE: 204 | SetWindowLong( GetDlgItem( m_wnd, IDC_SEARCH_STRING ), GWL_EXSTYLE, MY_EDGE_NONE ); 205 | break; 206 | case EE_GREY: 207 | SetWindowLong( GetDlgItem( m_wnd, IDC_SEARCH_STRING ), GWL_EXSTYLE, MY_EDGE_GREY ); 208 | break; 209 | case EE_SUNKEN: 210 | SetWindowLong( GetDlgItem( m_wnd, IDC_SEARCH_STRING ), GWL_EXSTYLE, MY_EDGE_SUNKEN ); 211 | break; 212 | } 213 | 214 | return m_wnd; 215 | } 216 | } 217 | 218 | const bool get_is_single_instance() const 219 | { 220 | return true; 221 | } 222 | }; 223 | 224 | //static ui_extension::window_factory_single g_tree_searcher(); 225 | static service_factory_single_t g_tree_searcher; -------------------------------------------------------------------------------- /foo_sendtodevice/foo_sendtodevice.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // Englisch (USA) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_PREFERENCES DIALOGEX 0, 0, 320, 284 56 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 57 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 58 | BEGIN 59 | GROUPBOX "Device Paths",IDC_STATIC,7,3,306,111 60 | EDITTEXT IDC_EDIT_DEVICES,13,24,294,86,ES_MULTILINE | ES_AUTOHSCROLL 61 | LTEXT "Enter possible device paths seperated by newlines (ctrl-enter)",IDC_STATIC,17,13,200,8 62 | LTEXT "foo_sendtodevice\nby Christopher Bowron \n( cover art copying by Hanno Stock )",IDC_STATIC,7,256,206,28 63 | CONTROL "Tag original files with SENT_TO_DEVICE timestamp",IDC_CHECK_TAG_FILES, 64 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,119,262,10 65 | CONTROL "Process destination files with:",IDC_CHECK_RUN_SCRIPT, 66 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,133,111,10 67 | COMBOBOX IDC_COMBO_SCRIPT,20,146,279,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 68 | EDITTEXT IDC_LAME,11,226,288,13,ES_AUTOHSCROLL 69 | LTEXT "Lame command line (for mp3 conversion)",IDC_STATIC,11,214,131,8 70 | CONTROL "Prompt for conversion to mp3",IDC_CHECK_PROMPT_MP3, 71 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,201,264,10 72 | CONTROL "Copy Cover Art",IDC_COPY_COVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,166,306,10 73 | EDITTEXT IDC_COVER_FILENAME,68,178,231,13,ES_AUTOHSCROLL 74 | LTEXT "Cover Filename:",IDC_STATIC,11,180,55,8 75 | END 76 | 77 | IDD_USER_SELECTION DIALOGEX 0, 0, 299, 49 78 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 79 | EXSTYLE WS_EX_TOOLWINDOW 80 | CAPTION "Send To Device" 81 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 82 | BEGIN 83 | DEFPUSHBUTTON "OK",IDOK,97,30,50,14 84 | PUSHBUTTON "Cancel",IDCANCEL,151,30,50,14 85 | CONTROL "Export playlist?",IDC_EXPORT_PLAYLIST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,29,65,10 86 | COMBOBOX IDC_SELECTIONS,16,12,268,17,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP 87 | GROUPBOX "Destination:",IDC_STATIC,7,3,285,25 88 | END 89 | 90 | 91 | ///////////////////////////////////////////////////////////////////////////// 92 | // 93 | // DESIGNINFO 94 | // 95 | 96 | #ifdef APSTUDIO_INVOKED 97 | GUIDELINES DESIGNINFO 98 | BEGIN 99 | IDD_PREFERENCES, DIALOG 100 | BEGIN 101 | LEFTMARGIN, 7 102 | RIGHTMARGIN, 313 103 | VERTGUIDE, 11 104 | VERTGUIDE, 299 105 | TOPMARGIN, 7 106 | BOTTOMMARGIN, 277 107 | END 108 | 109 | IDD_USER_SELECTION, DIALOG 110 | BEGIN 111 | LEFTMARGIN, 7 112 | RIGHTMARGIN, 292 113 | TOPMARGIN, 7 114 | BOTTOMMARGIN, 44 115 | END 116 | END 117 | #endif // APSTUDIO_INVOKED 118 | 119 | #endif // Englisch (USA) resources 120 | ///////////////////////////////////////////////////////////////////////////// 121 | 122 | 123 | 124 | #ifndef APSTUDIO_INVOKED 125 | ///////////////////////////////////////////////////////////////////////////// 126 | // 127 | // Generated from the TEXTINCLUDE 3 resource. 128 | // 129 | 130 | 131 | ///////////////////////////////////////////////////////////////////////////// 132 | #endif // not APSTUDIO_INVOKED 133 | 134 | -------------------------------------------------------------------------------- /foo_sendtodevice/foo_sendtodevice.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 55 | 58 | 61 | 64 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 99 | 100 | 109 | 112 | 115 | 118 | 121 | 124 | 133 | 136 | 139 | 142 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 175 | 179 | 180 | 181 | 182 | 186 | 190 | 194 | 198 | 199 | 200 | 205 | 208 | 209 | 212 | 213 | 214 | 219 | 222 | 223 | 224 | 229 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /foo_sendtodevice/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_sendtodevice.rc 4 | // 5 | #define IDD_PREFERENCES 9 6 | #define IDD_USER_SELECTION 102 7 | #define IDC_EDIT_DEVICES 1001 8 | #define IDC_EXPORT_PLAYLIST 1002 9 | #define IDC_SELECTIONS 1003 10 | #define IDC_CHECK_TAG_FILES 1004 11 | #define IDC_CHECK_RUN_SCRIPT 1005 12 | #define IDC_COMBO_SCRIPT 1006 13 | #define IDC_CHECK1 1008 14 | #define IDC_CHECK_PROMPT_MP3 1008 15 | #define IDC_COPY_COVERART 1009 16 | #define IDC_COPY_COVER 1009 17 | #define IDC_COVER_FILENAME 1010 18 | #define IDC_LAME 1027 19 | 20 | // Next default values for new objects 21 | // 22 | #ifdef APSTUDIO_INVOKED 23 | #ifndef APSTUDIO_READONLY_SYMBOLS 24 | #define _APS_NEXT_RESOURCE_VALUE 104 25 | #define _APS_NEXT_COMMAND_VALUE 40001 26 | #define _APS_NEXT_CONTROL_VALUE 1011 27 | #define _APS_NEXT_SYMED_VALUE 101 28 | #endif 29 | #endif 30 | -------------------------------------------------------------------------------- /foo_tcp_interface/foo_tcp_interface.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_ART_LIST DIALOGEX 0, 0, 246, 225 56 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 57 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 58 | BEGIN 59 | CONTROL "",IDC_LIST_IMAGES,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,232,211 60 | END 61 | 62 | IDD_OPTIONS DIALOGEX 0, 0, 250, 209 63 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 64 | CAPTION "Options" 65 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 66 | BEGIN 67 | DEFPUSHBUTTON "OK",IDOK,73,188,50,14 68 | PUSHBUTTON "Cancel",IDCANCEL,126,188,50,14 69 | EDITTEXT IDC_EDIT_ART_FORMAT,7,24,236,14,ES_AUTOHSCROLL 70 | EDITTEXT IDC_EDIT_LABEL_FORMAT,7,53,236,14,ES_AUTOHSCROLL 71 | EDITTEXT IDC_EDIT_THUMBNAIL_WIDTH,38,88,40,14,ES_AUTOHSCROLL 72 | EDITTEXT IDC_EDIT_THUMBNAIL_HEIGHT,38,104,40,14,ES_AUTOHSCROLL 73 | PUSHBUTTON "Text",IDC_BUTTON_TEXT,171,86,50,14 74 | PUSHBUTTON "Background",IDC_BUTTON_BACKGROUND,171,104,50,14 75 | LTEXT "Image Labels:",IDC_STATIC,11,41,186,8 76 | LTEXT "Album Art Location:",IDC_STATIC,11,15,186,8 77 | GROUPBOX "Formatting",IDC_STATIC,7,7,236,68 78 | GROUPBOX "Thumbnail",IDC_STATIC,7,78,78,44 79 | LTEXT "Width:",IDC_STATIC,11,91,22,8 80 | LTEXT "Height:",IDC_STATIC,12,106,24,8 81 | GROUPBOX "Colors",IDC_STATIC,88,78,155,44 82 | PUSHBUTTON "Button1",IDC_BUTTON_FILL_TEXT,118,86,50,14 83 | PUSHBUTTON "Button1",IDC_BUTTON_FILL_BACK,118,104,50,14 84 | GROUPBOX "Actions",IDC_STATIC,7,126,236,47 85 | COMBOBOX IDC_COMBO_SELECTION_ACTION,59,137,184,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 86 | COMBOBOX IDC_COMBO_DOUBLE_CLICK_ACTION,59,154,184,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 87 | LTEXT "Selection:",IDC_STATIC,22,139,32,8 88 | LTEXT "Double Click:",IDC_STATIC,12,155,42,8 89 | END 90 | 91 | IDD_STARTUP_PREFERENCES DIALOGEX 0, 0, 308, 222 92 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 93 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 94 | BEGIN 95 | CONTROL "",IDC_LIST_ACTIONS,"SysListView32",LVS_LIST | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,11,21,222,190 96 | PUSHBUTTON "Add",IDC_BUTTON_ADD,237,20,50,14 97 | PUSHBUTTON "Remove",IDC_BUTTON_REMOVE,237,37,50,14 98 | GROUPBOX "Startup Actions",IDC_STATIC,7,7,301,215 99 | END 100 | 101 | IDD_ADD_ACTION DIALOGEX 0, 0, 186, 49 102 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 103 | CAPTION "Add Action..." 104 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 105 | BEGIN 106 | DEFPUSHBUTTON "OK",IDOK,41,28,50,14 107 | PUSHBUTTON "Cancel",IDCANCEL,94,28,50,14 108 | COMBOBOX IDC_COMBO_ACTIONS,7,7,172,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 109 | END 110 | 111 | 112 | ///////////////////////////////////////////////////////////////////////////// 113 | // 114 | // DESIGNINFO 115 | // 116 | 117 | #ifdef APSTUDIO_INVOKED 118 | GUIDELINES DESIGNINFO 119 | BEGIN 120 | IDD_ART_LIST, DIALOG 121 | BEGIN 122 | LEFTMARGIN, 7 123 | RIGHTMARGIN, 239 124 | TOPMARGIN, 7 125 | BOTTOMMARGIN, 218 126 | END 127 | 128 | IDD_OPTIONS, DIALOG 129 | BEGIN 130 | LEFTMARGIN, 7 131 | RIGHTMARGIN, 243 132 | TOPMARGIN, 7 133 | BOTTOMMARGIN, 202 134 | END 135 | 136 | IDD_STARTUP_PREFERENCES, DIALOG 137 | BEGIN 138 | LEFTMARGIN, 7 139 | RIGHTMARGIN, 301 140 | TOPMARGIN, 7 141 | BOTTOMMARGIN, 215 142 | END 143 | 144 | IDD_ADD_ACTION, DIALOG 145 | BEGIN 146 | LEFTMARGIN, 7 147 | RIGHTMARGIN, 179 148 | TOPMARGIN, 7 149 | BOTTOMMARGIN, 42 150 | END 151 | END 152 | #endif // APSTUDIO_INVOKED 153 | 154 | #endif // English (U.S.) resources 155 | ///////////////////////////////////////////////////////////////////////////// 156 | 157 | 158 | 159 | #ifndef APSTUDIO_INVOKED 160 | ///////////////////////////////////////////////////////////////////////////// 161 | // 162 | // Generated from the TEXTINCLUDE 3 resource. 163 | // 164 | 165 | 166 | ///////////////////////////////////////////////////////////////////////////// 167 | #endif // not APSTUDIO_INVOKED 168 | 169 | -------------------------------------------------------------------------------- /foo_tcp_interface/foo_tcp_interface.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 25 | 28 | 31 | 34 | 37 | 40 | 52 | 55 | 58 | 61 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 93 | 98 | 99 | 108 | 111 | 114 | 117 | 120 | 123 | 132 | 135 | 138 | 141 | 152 | 155 | 158 | 161 | 164 | 167 | 170 | 173 | 178 | 179 | 180 | 181 | 182 | 183 | 188 | 191 | 192 | 193 | 198 | 201 | 202 | 203 | 208 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /foo_tcp_interface/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_cwbowron.rc 4 | // 5 | #define IDD_ART_LIST 101 6 | #define IDD_OPTIONS 102 7 | #define IDD_STARTUP_PREFERENCES 103 8 | #define IDD_ADD_ACTION 104 9 | #define IDC_LIST_IMAGES 1001 10 | #define IDC_EDIT_ART_FORMAT 1002 11 | #define IDC_EDIT_LABEL_FORMAT 1003 12 | #define IDC_EDIT_THUMBNAIL_WIDTH 1004 13 | #define IDC_EDIT_THUMBNAIL_HEIGHT 1005 14 | #define IDC_BUTTON_BACKGROUND 1006 15 | #define IDC_BUTTON_TEXT 1007 16 | #define IDC_BUTTON_FILL_TEXT 1010 17 | #define IDC_BUTTON_FILL_BACK 1011 18 | #define IDC_COMBO_SELECTION_ACTION 1012 19 | #define IDC_COMBO_DOUBLE_CLICK_ACTION 1013 20 | #define IDC_LIST_ACTIONS 1015 21 | #define IDC_BUTTON_ADD 1016 22 | #define IDC_BUTTON_REMOVE 1017 23 | #define IDC_COMBO1 1017 24 | #define IDC_COMBO_ACTIONS 1017 25 | 26 | // Next default values for new objects 27 | // 28 | #ifdef APSTUDIO_INVOKED 29 | #ifndef APSTUDIO_READONLY_SYMBOLS 30 | #define _APS_NEXT_RESOURCE_VALUE 105 31 | #define _APS_NEXT_COMMAND_VALUE 40001 32 | #define _APS_NEXT_CONTROL_VALUE 1018 33 | #define _APS_NEXT_SYMED_VALUE 101 34 | #endif 35 | #endif 36 | -------------------------------------------------------------------------------- /foo_trackfinder/foo_trackfinder.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Dialog 53 | // 54 | 55 | IDD_BLANK DIALOGEX 0, 0, 186, 166 56 | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 57 | CAPTION "Dialog" 58 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 59 | BEGIN 60 | END 61 | 62 | IDD_TF_CONFIG DIALOGEX 0, 0, 378, 241 63 | STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU 64 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 65 | BEGIN 66 | LTEXT "Track Finder Christopher Bowron - chris@bowron.us\nhttp://wiki.bowron.us/index.php/Foobar2000",IDC_STATIC,7,209,255,25 67 | GROUPBOX "Track Finder Format",IDC_STATIC,7,7,364,101 68 | EDITTEXT IDC_TF_FORMAT,11,17,355,86,ES_MULTILINE | ES_AUTOHSCROLL 69 | GROUPBOX "Selection Actions",IDC_STATIC,7,111,240,91 70 | COMBOBOX IDC_TF_ACTION1,11,122,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 71 | COMBOBOX IDC_TF_ACTION2,11,138,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 72 | COMBOBOX IDC_TF_ACTION3,11,154,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 73 | COMBOBOX IDC_TF_ACTION4,11,170,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 74 | COMBOBOX IDC_TF_ACTION5,11,186,232,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP 75 | GROUPBOX "Maximum Files",IDC_STATIC,249,111,79,29 76 | EDITTEXT IDC_MAX,254,121,70,15,ES_AUTOHSCROLL 77 | END 78 | 79 | 80 | ///////////////////////////////////////////////////////////////////////////// 81 | // 82 | // DESIGNINFO 83 | // 84 | 85 | #ifdef APSTUDIO_INVOKED 86 | GUIDELINES DESIGNINFO 87 | BEGIN 88 | IDD_BLANK, DIALOG 89 | BEGIN 90 | LEFTMARGIN, 7 91 | RIGHTMARGIN, 179 92 | TOPMARGIN, 7 93 | BOTTOMMARGIN, 159 94 | END 95 | 96 | IDD_TF_CONFIG, DIALOG 97 | BEGIN 98 | LEFTMARGIN, 7 99 | RIGHTMARGIN, 371 100 | TOPMARGIN, 7 101 | BOTTOMMARGIN, 234 102 | END 103 | END 104 | #endif // APSTUDIO_INVOKED 105 | 106 | #endif // English (U.S.) resources 107 | ///////////////////////////////////////////////////////////////////////////// 108 | 109 | 110 | 111 | #ifndef APSTUDIO_INVOKED 112 | ///////////////////////////////////////////////////////////////////////////// 113 | // 114 | // Generated from the TEXTINCLUDE 3 resource. 115 | // 116 | 117 | 118 | ///////////////////////////////////////////////////////////////////////////// 119 | #endif // not APSTUDIO_INVOKED 120 | 121 | -------------------------------------------------------------------------------- /foo_trackfinder/foo_trackfinder.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 28 | 31 | 34 | 37 | 40 | 43 | 55 | 58 | 61 | 64 | 71 | 74 | 77 | 80 | 83 | 86 | 89 | 92 | 95 | 96 | 105 | 108 | 111 | 114 | 117 | 120 | 131 | 134 | 137 | 140 | 151 | 154 | 157 | 160 | 163 | 166 | 169 | 172 | 175 | 176 | 177 | 178 | 179 | 180 | 185 | 188 | 189 | 190 | 195 | 198 | 199 | 200 | 205 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /foo_trackfinder/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by foo_trackfinder.rc 4 | // 5 | #define IDD_BLANK 101 6 | #define IDD_TF_CONFIG 104 7 | #define IDC_TF_FORMAT 1023 8 | #define IDC_TF_ACTION1 1024 9 | #define IDC_TF_ACTION2 1025 10 | #define IDC_TF_ACTION3 1026 11 | #define IDC_TF_ACTION4 1027 12 | #define IDC_TF_ACTION5 1028 13 | #define IDC_MAX 1067 14 | 15 | // Next default values for new objects 16 | // 17 | #ifdef APSTUDIO_INVOKED 18 | #ifndef APSTUDIO_READONLY_SYMBOLS 19 | #define _APS_NEXT_RESOURCE_VALUE 102 20 | #define _APS_NEXT_COMMAND_VALUE 40001 21 | #define _APS_NEXT_CONTROL_VALUE 1001 22 | #define _APS_NEXT_SYMED_VALUE 101 23 | #endif 24 | #endif 25 | -------------------------------------------------------------------------------- /lib/libmzgc360_000.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwbowron/foobar2000-plugins/6ba30d7b3afc0ee85f5cc2903012c1dfcee132bd/lib/libmzgc360_000.lib -------------------------------------------------------------------------------- /lib/libmzsch360_000.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cwbowron/foobar2000-plugins/6ba30d7b3afc0ee85f5cc2903012c1dfcee132bd/lib/libmzsch360_000.lib --------------------------------------------------------------------------------