foobar2000 SDK  2015-08-03
playlist.cpp
Go to the documentation of this file.
1 #include "foobar2000.h"
2 
3 namespace {
4  class enum_items_callback_retrieve_item : public playlist_manager::enum_items_callback
5  {
6  metadb_handle_ptr m_item;
7  public:
8  enum_items_callback_retrieve_item() : m_item(0) {}
9  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
10  {
11  assert(m_item.is_empty());
12  m_item = p_location;
13  return false;
14  }
15  inline const metadb_handle_ptr & get_item() {return m_item;}
16  };
17 
18  class enum_items_callback_retrieve_selection : public playlist_manager::enum_items_callback
19  {
20  bool m_state;
21  public:
22  enum_items_callback_retrieve_selection() : m_state(false) {}
23  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
24  {
25  m_state = b_selected;
26  return false;
27  }
28  inline bool get_state() {return m_state;}
29  };
30 
31  class enum_items_callback_retrieve_selection_mask : public playlist_manager::enum_items_callback
32  {
33  bit_array_var & m_out;
34  public:
35  enum_items_callback_retrieve_selection_mask(bit_array_var & p_out) : m_out(p_out) {}
36  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
37  {
38  m_out.set(p_index,b_selected);
39  return true;
40  }
41  };
42 
43  class enum_items_callback_retrieve_all_items : public playlist_manager::enum_items_callback
44  {
46  public:
47  enum_items_callback_retrieve_all_items(pfc::list_base_t<metadb_handle_ptr> & p_out) : m_out(p_out) {m_out.remove_all();}
48  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
49  {
50  m_out.add_item(p_location);
51  return true;
52  }
53  };
54 
55  class enum_items_callback_retrieve_selected_items : public playlist_manager::enum_items_callback
56  {
58  public:
59  enum_items_callback_retrieve_selected_items(pfc::list_base_t<metadb_handle_ptr> & p_out) : m_out(p_out) {m_out.remove_all();}
60  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
61  {
62  if (b_selected) m_out.add_item(p_location);
63  return true;
64  }
65  };
66 
67  class enum_items_callback_count_selection : public playlist_manager::enum_items_callback
68  {
69  t_size m_counter,m_max;
70  public:
71  enum_items_callback_count_selection(t_size p_max) : m_max(p_max), m_counter(0) {}
72  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
73  {
74  if (b_selected)
75  {
76  if (++m_counter >= m_max) return false;
77  }
78  return true;
79  }
80 
81  inline t_size get_count() {return m_counter;}
82  };
83 
84 }
85 
87 {
88  playlist_get_items(p_playlist,out,bit_array_true());
89 }
90 
92 {
93  playlist_enum_items(p_playlist,enum_items_callback_retrieve_selected_items(out),bit_array_true());
94 }
95 
97 {
98  playlist_enum_items(p_playlist,enum_items_callback_retrieve_selection_mask(out),bit_array_true());
99 }
100 
102 {
103  enum_items_callback_retrieve_selection callback;
104  playlist_enum_items(p_playlist,callback,bit_array_one(p_item));
105  return callback.get_state();
106 }
107 
109  metadb_handle_ptr temp;
110  if (!playlist_get_item_handle(temp, playlist, item)) throw pfc::exception_invalid_params();
111  PFC_ASSERT( temp.is_valid() );
112  return temp;
113 
114 }
116 {
117  enum_items_callback_retrieve_item callback;
118  playlist_enum_items(p_playlist,callback,bit_array_one(p_item));
119  p_out = callback.get_item();
120  return p_out.is_valid();
121 }
122 
123 void playlist_manager::g_make_selection_move_permutation(t_size * p_output,t_size p_count,const bit_array & p_selection,int p_delta) {
124  pfc::create_move_items_permutation(p_output,p_count,p_selection,p_delta);
125 }
126 
127 bool playlist_manager::playlist_move_selection(t_size p_playlist,int p_delta) {
128  if (p_delta==0) return true;
129 
130  t_size count = playlist_get_item_count(p_playlist);
131 
132  pfc::array_t<t_size> order; order.set_size(count);
133  pfc::array_t<bool> selection; selection.set_size(count);
134 
135  playlist_get_selection_mask(p_playlist,bit_array_var_table(selection.get_ptr(),selection.get_size()));
136  g_make_selection_move_permutation(order.get_ptr(),count,bit_array_table(selection.get_ptr(),selection.get_size()),p_delta);
137  return playlist_reorder_items(p_playlist,order.get_ptr(),count);
138 }
139 
140 //retrieving status
142 {
143  t_size playlist = get_active_playlist();
144  if (playlist == pfc_infinite) return 0;
145  else return playlist_get_item_count(playlist);
146 }
147 
149 {
150  t_size playlist = get_active_playlist();
151  if (playlist != pfc_infinite) playlist_enum_items(playlist,p_callback,p_mask);
152 }
153 
155 {
156  t_size playlist = get_active_playlist();
157  if (playlist == pfc_infinite) return pfc_infinite;
158  else return playlist_get_focus_item(playlist);
159 }
160 
162 {
163  t_size playlist = get_active_playlist();
164  if (playlist == pfc_infinite) return false;
165  else return playlist_get_name(playlist,p_out);
166 }
167 
168 //modifying playlist
170 {
171  t_size playlist = get_active_playlist();
172  if (playlist != pfc_infinite) return playlist_reorder_items(playlist,order,count);
173  else return false;
174 }
175 
177 {
178  t_size playlist = get_active_playlist();
179  if (playlist != pfc_infinite) playlist_set_selection(playlist,affected,status);
180 }
181 
183 {
184  t_size playlist = get_active_playlist();
185  if (playlist != pfc_infinite) return playlist_remove_items(playlist,mask);
186  else return false;
187 }
188 
190 {
191  t_size playlist = get_active_playlist();
192  if (playlist != pfc_infinite) return playlist_replace_item(playlist,p_item,p_new_item);
193  else return false;
194 }
195 
197 {
198  t_size playlist = get_active_playlist();
199  if (playlist != pfc_infinite) playlist_set_focus_item(playlist,p_item);
200 }
201 
203 {
204  t_size playlist = get_active_playlist();
205  if (playlist != pfc_infinite) return playlist_insert_items(playlist,p_base,data,p_selection);
206  else return pfc_infinite;
207 }
208 
210 {
211  t_size playlist = get_active_playlist();
212  if (playlist != pfc_infinite) playlist_ensure_visible(playlist,p_item);
213 }
214 
215 bool playlist_manager::activeplaylist_rename(const char * p_name,t_size p_name_len)
216 {
217  t_size playlist = get_active_playlist();
218  if (playlist != pfc_infinite) return playlist_rename(playlist,p_name,p_name_len);
219  else return false;
220 }
221 
223 {
224  t_size playlist = get_active_playlist();
225  if (playlist != pfc_infinite) return playlist_is_item_selected(playlist,p_item);
226  else return false;
227 }
228 
230  metadb_handle_ptr temp;
231  if (!activeplaylist_get_item_handle(temp, p_item)) throw pfc::exception_invalid_params();
232  PFC_ASSERT( temp.is_valid() );
233  return temp;
234 }
236 {
237  t_size playlist = get_active_playlist();
238  if (playlist != pfc_infinite) return playlist_get_item_handle(p_out,playlist,p_item);
239  else return false;
240 }
241 
243 {
244  t_size playlist = get_active_playlist();
245  if (playlist != pfc_infinite) playlist_move_selection(playlist,p_delta);
246 }
247 
249 {
250  t_size playlist = get_active_playlist();
251  if (playlist != pfc_infinite) playlist_get_selection_mask(playlist,out);
252 }
253 
255 {
256  t_size playlist = get_active_playlist();
257  if (playlist != pfc_infinite) playlist_get_all_items(playlist,out);
258 }
259 
261 {
262  t_size playlist = get_active_playlist();
263  if (playlist != pfc_infinite) playlist_get_selected_items(playlist,out);
264 }
265 
267 {
268  return remove_playlists(bit_array_one(idx));
269 }
270 
271 bool playlist_incoming_item_filter::process_location(const char * url,pfc::list_base_t<metadb_handle_ptr> & out,bool filter,const char * p_mask,const char * p_exclude,HWND p_parentwnd)
272 {
273  return process_locations(pfc::list_single_ref_t<const char*>(url),out,filter,p_mask,p_exclude,p_parentwnd);
274 }
275 
277 {
278  playlist_remove_items(p_playlist,bit_array_true());
279 }
280 
282 {
283  t_size playlist = get_active_playlist();
284  if (playlist != pfc_infinite) playlist_clear(playlist);
285 }
286 
288  metadb_handle_list old;
289  playlist_get_all_items(playlist, old);
290  if (old.get_size() == 0) {
291  if (content.get_size() == 0) return false;
292  if (bUndoBackup) playlist_undo_backup(playlist);
293  playlist_add_items(playlist, content, bit_array_false());
294  return true;
295  }
296  pfc::avltree_t<metadb_handle::nnptr> itemsOld, itemsNew;
297 
298  for(t_size walk = 0; walk < old.get_size(); ++walk) itemsOld += old[walk];
299  for(t_size walk = 0; walk < content.get_size(); ++walk) itemsNew += content[walk];
300  bit_array_bittable removeMask(old.get_size());
301  bit_array_bittable filterMask(content.get_size());
302  bool gotNew = false, filterNew = false, gotRemove = false;
303  for(t_size walk = 0; walk < content.get_size(); ++walk) {
304  const bool state = !itemsOld.have_item(content[walk]);
305  if (state) gotNew = true;
306  else filterNew = true;
307  filterMask.set(walk, state);
308  }
309  for(t_size walk = 0; walk < old.get_size(); ++walk) {
310  const bool state = !itemsNew.have_item(old[walk]);
311  if (state) gotRemove = true;
312  removeMask.set(walk, state);
313  }
314  if (!gotNew && !gotRemove) return false;
315  if (bUndoBackup) playlist_undo_backup(playlist);
316  if (gotRemove) {
317  playlist_remove_items(playlist, removeMask);
318  }
319  if (gotNew) {
320  if (filterNew) {
321  metadb_handle_list temp(content);
322  temp.filter_mask(filterMask);
323  playlist_add_items(playlist, temp, bit_array_false());
324  } else {
325  playlist_add_items(playlist, content, bit_array_false());
326  }
327  }
328 
329  {
330  playlist_get_all_items(playlist, old);
331  pfc::array_t<t_size> order;
333  playlist_reorder_items(playlist, order.get_ptr(), order.get_size());
334  }
335  }
336  return true;
337 }
339 {
340  return playlist_insert_items(playlist,pfc_infinite,data,p_selection) != pfc_infinite;
341 }
342 
344 {
345  t_size playlist = get_active_playlist();
346  if (playlist != pfc_infinite) return playlist_add_items(playlist,data,p_selection);
347  else return false;
348 }
349 
351 {
352  metadb_handle_list temp;
354  if (!api->filter_items(p_data,temp))
355  return false;
356  return playlist_insert_items(p_playlist,p_base,temp,bit_array_val(p_select)) != pfc_infinite;
357 }
358 
360 {
361  t_size playlist = get_active_playlist();
362  if (playlist != pfc_infinite) return playlist_insert_items_filter(playlist,p_base,p_data,p_select);
363  else return false;
364 }
365 
366 bool playlist_manager::playlist_insert_locations(t_size p_playlist,t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
367 {
368  metadb_handle_list temp;
370  if (!api->process_locations(p_urls,temp,true,0,0,p_parentwnd)) return false;
371  return playlist_insert_items(p_playlist,p_base,temp,bit_array_val(p_select)) != pfc_infinite;
372 }
373 
374 bool playlist_manager::activeplaylist_insert_locations(t_size p_base,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
375 {
376  t_size playlist = get_active_playlist();
377  if (playlist != pfc_infinite) return playlist_insert_locations(playlist,p_base,p_urls,p_select,p_parentwnd);
378  else return false;
379 }
380 
382 {
383  return playlist_insert_items_filter(p_playlist,pfc_infinite,p_data,p_select);
384 }
385 
387 {
388  return activeplaylist_insert_items_filter(pfc_infinite,p_data,p_select);
389 }
390 
391 bool playlist_manager::playlist_add_locations(t_size p_playlist,const pfc::list_base_const_t<const char*> & p_urls,bool p_select,HWND p_parentwnd)
392 {
393  return playlist_insert_locations(p_playlist,pfc_infinite,p_urls,p_select,p_parentwnd);
394 }
396 {
397  return activeplaylist_insert_locations(pfc_infinite,p_urls,p_select,p_parentwnd);
398 }
399 
401 {
402  set_playing_playlist(get_active_playlist());
403 }
404 
406 {
407  playlist_set_selection(p_playlist,bit_array_true(),bit_array_false());
408 }
409 
411 {
412  t_size playlist = get_active_playlist();
413  if (playlist != pfc_infinite) playlist_clear_selection(playlist);
414 }
415 
417 {
418  t_size playlist = get_active_playlist();
419  if (playlist != pfc_infinite) playlist_undo_backup(playlist);
420 }
421 
423 {
424  t_size playlist = get_active_playlist();
425  if (playlist != pfc_infinite) return playlist_undo_restore(playlist);
426  else return false;
427 }
428 
430 {
431  t_size playlist = get_active_playlist();
432  if (playlist != pfc_infinite) return playlist_redo_restore(playlist);
433  else return false;
434 }
435 
437 {
438  bit_array_bittable table(playlist_get_item_count(p_playlist));
439  playlist_get_selection_mask(p_playlist,table);
440  if (p_crop) playlist_remove_items(p_playlist,bit_array_not(table));
441  else playlist_remove_items(p_playlist,table);
442 }
443 
445 {
446  t_size playlist = get_active_playlist();
447  if (playlist != pfc_infinite) playlist_remove_selection(playlist,p_crop);
448 }
449 
451 {
452  t_size playlist = get_active_playlist();
453  if (playlist == pfc_infinite) out = "NJET";
454  else playlist_item_format_title(playlist,p_item,p_hook,out,p_script,p_filter,p_playback_info_level);
455 }
456 
458 {
459  playlist_set_selection(p_playlist,bit_array_one(p_item),bit_array_val(p_state));
460 }
461 
463 {
464  t_size playlist = get_active_playlist();
465  if (playlist != pfc_infinite) playlist_set_selection_single(playlist,p_item,p_state);
466 }
467 
469 {
470  enum_items_callback_count_selection callback(p_max);
471  playlist_enum_items(p_playlist,callback,bit_array_true());
472  return callback.get_count();
473 }
474 
476 {
477  t_size playlist = get_active_playlist();
478  if (playlist != pfc_infinite) return playlist_get_selection_count(playlist,p_max);
479  else return 0;
480 }
481 
483 {
484  t_size index = playlist_get_focus_item(p_playlist);
485  if (index == pfc_infinite) return false;
486  return playlist_get_item_handle(p_out,p_playlist,index);
487 }
488 
490 {
491  t_size playlist = get_active_playlist();
492  if (playlist != pfc_infinite) return playlist_get_focus_item_handle(p_out,playlist);
493  else return false;
494 }
495 
496 t_size playlist_manager::find_playlist(const char * p_name,t_size p_name_length)
497 {
498  t_size n, m = get_playlist_count();
500  for(n=0;n<m;n++) {
501  if (!playlist_get_name(n,temp)) break;
502  if (stricmp_utf8_ex(temp,temp.length(),p_name,p_name_length) == 0) return n;
503  }
504  return pfc_infinite;
505 }
506 
508  t_size n, m = get_playlist_count();
510  for(n=0;n<m;n++) {
511  if (!playlist_lock_is_present(n) && playlist_get_name(n,temp)) {
512  if (stricmp_utf8_ex(temp,~0,p_name,p_name_length) == 0) return n;
513  }
514  }
515  return create_playlist(p_name,p_name_length,pfc_infinite);
516 }
517 t_size playlist_manager::find_or_create_playlist(const char * p_name,t_size p_name_length)
518 {
519  t_size index = find_playlist(p_name,p_name_length);
520  if (index != pfc_infinite) return index;
521  return create_playlist(p_name,p_name_length,pfc_infinite);
522 }
523 
525  static const char new_playlist_text[] = "New Playlist";
526  if (find_playlist(new_playlist_text,pfc_infinite) == pfc_infinite) return create_playlist(new_playlist_text,pfc_infinite,p_index);
527  for(t_size walk = 2; ; walk++) {
528  pfc::string_fixed_t<64> namebuffer;
529  namebuffer << new_playlist_text << " (" << walk << ")";
530  if (find_playlist(namebuffer,pfc_infinite) == pfc_infinite) return create_playlist(namebuffer,pfc_infinite,p_index);
531  }
532 }
533 
534 bool playlist_manager::activeplaylist_sort_by_format(const char * spec,bool p_sel_only)
535 {
536  t_size playlist = get_active_playlist();
537  if (playlist != pfc_infinite) return playlist_sort_by_format(playlist,spec,p_sel_only);
538  else return false;
539 }
540 
542 {
543  t_size playlist,item;
544  if (!get_playing_item_location(&playlist,&item)) return false;
545  set_active_playlist(playlist);
546  playlist_set_focus_item(playlist,item);
547  playlist_set_selection(playlist,bit_array_true(),bit_array_one(item));
548  playlist_ensure_visible(playlist,item);
549  return true;
550 }
551 
553 {
554  playlist_enum_items(p_playlist,enum_items_callback_retrieve_all_items(out),p_mask);
555 }
556 
558 {
559  t_size playlist = get_active_playlist();
560  if (playlist != pfc_infinite) playlist_get_items(playlist,out,p_mask);
561  else out.remove_all();
562 }
563 
565 {
566  t_size playlist = get_active_playlist();
567  if (playlist == pfc_infinite)
568  {
569  t_size max = get_playlist_count();
570  if (max == 0)
571  {
572  create_playlist_autoname();
573  }
574  set_active_playlist(0);
575  }
576 }
577 
578 namespace {
579  class enum_items_callback_remove_list : public playlist_manager::enum_items_callback
580  {
581  const metadb_handle_list & m_data;
582  bit_array_var & m_table;
583  t_size m_found;
584  public:
585  enum_items_callback_remove_list(const metadb_handle_list & p_data,bit_array_var & p_table) : m_data(p_data), m_table(p_table), m_found(0) {}
586  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected)
587  {
588  bool found = m_data.bsearch_by_pointer(p_location) != pfc_infinite;
589  m_table.set(p_index,found);
590  if (found) m_found++;
591  return true;
592  }
593 
594  inline t_size get_found() const {return m_found;}
595  };
596 }
597 
599 {
600  t_size playlist_num, playlist_max = get_playlist_count();
601  if (playlist_max != pfc_infinite)
602  {
603  metadb_handle_list temp;
604  temp.add_items(p_data);
605  temp.sort_by_pointer();
606  for(playlist_num = 0; playlist_num < playlist_max; playlist_num++ )
607  {
608  t_size playlist_item_count = playlist_get_item_count(playlist_num);
609  if (playlist_item_count == pfc_infinite) break;
610  bit_array_bittable table(playlist_item_count);
611  enum_items_callback_remove_list callback(temp,table);
612  playlist_enum_items(playlist_num,callback,bit_array_true());
613  if (callback.get_found()>0)
614  playlist_remove_items(playlist_num,table);
615  }
616  }
617 }
618 
620 {
621  t_size n, m = get_playlist_count();
622  if (m == pfc_infinite) return false;
623  enum_items_callback_retrieve_all_items callback(out);
624  for(n=0;n<m;n++)
625  {
626  playlist_enum_items(n,callback,bit_array_true());
627  }
628  return true;
629 }
630 
632 {
633  t_size playlist = get_active_playlist();
634  if (playlist == pfc_infinite) return ~0;
635  else return playlist_lock_get_filter_mask(playlist);
636 }
637 
639 {
640  t_size playlist = get_active_playlist();
641  if (playlist == pfc_infinite) return false;
642  else return playlist_is_undo_available(playlist);
643 }
644 
646 {
647  t_size playlist = get_active_playlist();
648  if (playlist == pfc_infinite) return false;
649  else return playlist_is_redo_available(playlist);
650 }
651 
653 {
654  bool need_switch = get_active_playlist() == idx;
655  if (remove_playlist(idx))
656  {
657  if (need_switch)
658  {
659  t_size total = get_playlist_count();
660  if (total > 0)
661  {
662  if (idx >= total) idx = total-1;
663  set_active_playlist(idx);
664  }
665  }
666  return true;
667  }
668  else return false;
669 }
670 
671 
672 
674 {
675  return m_handle == p_item.m_handle && m_playlist == p_item.m_playlist && m_item == p_item.m_item;
676 }
677 
679 {
680  return m_handle != p_item.m_handle || m_playlist != p_item.m_playlist || m_item != p_item.m_item;
681 }
682 
683 
684 
686  t_size idx = get_active_playlist();
687  if (idx == pfc_infinite) return false;
688  else return playlist_execute_default_action(idx,p_item);
689 }
690 
691 namespace {
692  class completion_notify_dfd : public completion_notify {
693  public:
694  completion_notify_dfd(const pfc::list_base_const_t<metadb_handle_ptr> & p_data,service_ptr_t<process_locations_notify> p_notify) : m_data(p_data), m_notify(p_notify) {}
695  void on_completion(unsigned p_code) {
696  switch(p_code) {
698  m_notify->on_aborted();
699  break;
700  default:
701  m_notify->on_completion(m_data);
702  break;
703  }
704  }
705  private:
706  metadb_handle_list m_data;
708  };
709 };
710 
712  if (m_is_paths) {
713  static_api_ptr_t<playlist_incoming_item_filter_v2>()->process_locations_async(
714  m_paths,
715  p_op_flags,
716  NULL,
717  NULL,
718  p_parentwnd,
719  p_notify);
720  } else {
721  t_uint32 flags = 0;
724  static_api_ptr_t<metadb_io_v2>()->load_info_async(m_handles,metadb_io::load_info_default,p_parentwnd,flags,new service_impl_t<completion_notify_dfd>(m_handles,p_notify));
725  }
726 }
728  to_handles_async_ex(p_filter ? 0 : playlist_incoming_item_filter_v2::op_flag_no_filter,p_parentwnd,p_notify);
729 }
730 
731 bool dropped_files_data_impl::to_handles(pfc::list_base_t<metadb_handle_ptr> & p_out,bool p_filter,HWND p_parentwnd) {
732  if (m_is_paths) {
733  return static_api_ptr_t<playlist_incoming_item_filter>()->process_locations(m_paths,p_out,p_filter,NULL,NULL,p_parentwnd);
734  } else {
735  if (static_api_ptr_t<metadb_io>()->load_info_multi(m_handles,metadb_io::load_info_default,p_parentwnd,true) == metadb_io::load_info_aborted) return false;
736  p_out = m_handles;
737  return true;
738  }
739 }
740 
742  const t_size total = get_playlist_count();
743  if (total > 0) {
744  t_size active = get_active_playlist();
745 
746  //clip p_delta to -(total-1)...(total-1) range
747  if (p_delta < 0) {
748  p_delta = - ( (-p_delta) % (t_ssize)total );
749  } else {
750  p_delta = p_delta % total;
751  }
752  if (p_delta != 0) {
753  if (active == pfc_infinite) {
754  //special case when no playlist is active
755  if (p_delta > 0) {
756  active = (t_size)(p_delta - 1);
757  } else {
758  active = (total + p_delta);//p_delta is negative
759  }
760  } else {
761  active = (t_size) (active + total + p_delta) % total;
762  }
763  set_active_playlist(active % total);
764  }
765  }
766 }
767 namespace {
768  class enum_items_callback_get_selected_count : public playlist_manager::enum_items_callback {
769  public:
770  enum_items_callback_get_selected_count() : m_found() {}
771  t_size get_count() const {return m_found;}
772  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected) {
773  if (b_selected) m_found++;
774  return true;
775  }
776  private:
777  t_size m_found;
778  };
779 }
781  enum_items_callback_get_selected_count callback;
782  playlist_enum_items(p_playlist,callback,p_mask);
783  return callback.get_count();
784 }
785 
786 namespace {
787  class enum_items_callback_find_item : public playlist_manager::enum_items_callback {
788  public:
789  enum_items_callback_find_item(metadb_handle_ptr p_lookingFor) : m_result(pfc_infinite), m_lookingFor(p_lookingFor) {}
790  t_size result() const {return m_result;}
791  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected) {
792  if (p_location == m_lookingFor) {
793  m_result = p_index;
794  return false;
795  } else {
796  return true;
797  }
798  }
799  private:
800  metadb_handle_ptr m_lookingFor;
801  t_size m_result;
802  };
803  class enum_items_callback_find_item_selected : public playlist_manager::enum_items_callback {
804  public:
805  enum_items_callback_find_item_selected(metadb_handle_ptr p_lookingFor) : m_result(pfc_infinite), m_lookingFor(p_lookingFor) {}
806  t_size result() const {return m_result;}
807  bool on_item(t_size p_index,const metadb_handle_ptr & p_location,bool b_selected) {
808  if (b_selected && p_location == m_lookingFor) {
809  m_result = p_index;
810  return false;
811  } else {
812  return true;
813  }
814  }
815  private:
816  metadb_handle_ptr m_lookingFor;
817  t_size m_result;
818  };
819 }
820 
822  enum_items_callback_find_item callback(p_item);
823  playlist_enum_items(p_playlist,callback,bit_array_true());
824  t_size result = callback.result();
825  if (result == pfc_infinite) return false;
826  p_result = result;
827  return true;
828 }
830  enum_items_callback_find_item_selected callback(p_item);
831  playlist_enum_items(p_playlist,callback,bit_array_true());
832  t_size result = callback.result();
833  if (result == pfc_infinite) return false;
834  p_result = result;
835  return true;
836 }
838  t_size index;
839  if (!playlist_find_item(p_playlist,p_item,index)) index = pfc_infinite;
840  playlist_set_focus_item(p_playlist,index);
841  return index;
842 }
844  t_size playlist = get_active_playlist();
845  if (playlist == pfc_infinite) return false;
846  return playlist_find_item(playlist,p_item,p_result);
847 }
849  t_size playlist = get_active_playlist();
850  if (playlist == pfc_infinite) return pfc_infinite;
851  return playlist_set_focus_by_handle(playlist,p_item);
852 }
853 
855  pfc::com_ptr_t<interface IDataObject> temp; temp.attach( create_dataobject(data) ); PFC_ASSERT( temp.is_valid() ); return temp;
856 }
857 
859  t_size which = recycler_find_by_id(id);
860  if (which != ~0) recycler_restore(which);
861 }
862 
864  const t_size total = recycler_get_count();
865  for(t_size walk = 0; walk < total; ++walk) {
866  if (id == recycler_get_id(walk)) return walk;
867  }
868  return ~0;
869 }
t_size playlist_get_selected_count(t_size p_playlist, bit_array const &p_mask)
Definition: playlist.cpp:780
t_size activeplaylist_get_item_count()
Definition: playlist.cpp:141
void to_handles_async_ex(t_uint32 p_op_flags, HWND p_parentwnd, service_ptr_t< process_locations_notify > p_notify)
Definition: playlist.cpp:711
Generic service for receiving notifications about async operation completion. Used by various other s...
metadb_handle_ptr m_handle
Definition: playlist.h:63
t_size recycler_find_by_id(t_uint32 id)
Definition: playlist.cpp:863
const t_item * get_ptr() const
Definition: array.h:213
void activeplaylist_item_format_title(t_size p_item, titleformat_hook *p_hook, pfc::string_base &out, const service_ptr_t< titleformat_object > &p_script, titleformat_text_filter *p_filter, play_control::t_display_level p_playback_info_level)
Definition: playlist.cpp:450
Template implementing reference-counting features of service_base. Intended for dynamic instantiation...
Definition: service_impl.h:4
bool activeplaylist_redo_restore()
Definition: playlist.cpp:429
int SHARED_EXPORT stricmp_utf8_ex(const char *p1, t_size len1, const char *p2, t_size len2)
bool playlist_add_locations(t_size p_playlist, const pfc::list_base_const_t< const char * > &p_urls, bool p_select, HWND p_parentwnd)
Definition: playlist.cpp:391
bool highlight_playing_item()
Helper; highlights currently playing item; returns true on success or false on failure (not playing o...
Definition: playlist.cpp:541
t_size add_item(const T &item)
Definition: list.h:210
void activeplaylist_set_selection_single(t_size p_item, bool p_state)
Definition: playlist.cpp:462
void reset_playing_playlist()
Definition: playlist.cpp:400
bool playlist_insert_items_filter(t_size p_playlist, t_size p_base, const pfc::list_base_const_t< metadb_handle_ptr > &p_data, bool p_select)
Definition: playlist.cpp:350
bool is_empty() const
Definition: service.h:120
t_size get_size() const
Definition: list.h:366
Generic variable bit_array implementation. Needs to be initialized with requested array size before ...
void playlist_clear(t_size p_playlist)
Clears contents of specified playlist (removes all items from it).
Definition: playlist.cpp:276
void playlist_get_selected_items(t_size p_playlist, pfc::list_base_t< metadb_handle_ptr > &out)
Definition: playlist.cpp:91
bool playlist_insert_locations(t_size p_playlist, t_size p_base, const pfc::list_base_const_t< const char * > &p_urls, bool p_select, HWND p_parentwnd)
Definition: playlist.cpp:366
bool operator!=(const t_playback_queue_item &p_item) const
Definition: playlist.cpp:678
void playlist_get_items(t_size p_playlist, pfc::list_base_t< metadb_handle_ptr > &out, const bit_array &p_mask)
Definition: playlist.cpp:552
void add_items(const t_in &in)
Definition: list.h:424
bool activeplaylist_get_item_handle(metadb_handle_ptr &item, t_size p_item)
Definition: playlist.cpp:235
bool operator==(const t_playback_queue_item &p_item) const
Definition: playlist.cpp:673
bool playlist_is_item_selected(t_size p_playlist, t_size p_item)
Helper; returns whether specified item on specified playlist is selected or not.
Definition: playlist.cpp:101
Bit array interface class, constant version (you can only retrieve values). Range of valid indexes d...
Definition: bit_array.h:6
t_size playlist_get_selection_count(t_size p_playlist, t_size p_max)
Definition: playlist.cpp:468
bool playlist_get_focus_item_handle(metadb_handle_ptr &p_item, t_size p_playlist)
Definition: playlist.cpp:482
t_size activeplaylist_set_focus_by_handle(metadb_handle_ptr p_item)
Definition: playlist.cpp:848
bit_array_table_t< bool > bit_array_table
bool activeplaylist_is_undo_available()
Definition: playlist.cpp:638
t_uint32 activeplaylist_lock_get_filter_mask()
Definition: playlist.cpp:631
Set this flag to delay the progress dialog becoming visible, so it does not appear at all during shor...
Definition: metadb.h:122
t_size find_playlist(const char *p_name, t_size p_name_length=~0)
Definition: playlist.cpp:496
void filter_mask(const bit_array &mask)
Definition: list.h:433
bit_array_var_table_t< bool > bit_array_var_table
void activeplaylist_get_all_items(pfc::list_base_t< metadb_handle_ptr > &out)
Definition: playlist.cpp:254
Set this flag to make the progress dialog not steal focus on creation.
Definition: playlist.h:789
bool playlist_get_item_handle(metadb_handle_ptr &p_out, t_size p_playlist, t_size p_item)
Helper; retrieves metadb_handle of the specified playlist item. Returns true on success, false on failure (invalid parameters).
Definition: playlist.cpp:115
void activeplaylist_enum_items(enum_items_callback &p_callback, const bit_array &p_mask)
Definition: playlist.cpp:148
Set this to disable presorting (according to user settings) and duplicate removal in output list...
Definition: playlist.h:787
bool activeplaylist_undo_restore()
Definition: playlist.cpp:422
Negation of another array. Valid index range is the same as valid index range of the parameter array...
bool have_item(const t_param &p_item) const
Same as contains().
Definition: avltree.h:433
void playlist_get_selection_mask(t_size p_playlist, bit_array_var &out)
Retrieves selection map of specific playlist, using bit_array_var interface.
Definition: playlist.cpp:96
bool is_valid() const
Definition: service.h:119
bool playlist_update_content(t_size playlist, metadb_handle_list_cref content, bool bUndoBackup)
Changes contents of the specified playlist to the specified items, trying to reuse existing playlist ...
Definition: playlist.cpp:287
bool activeplaylist_find_item(metadb_handle_ptr p_item, t_size &p_result)
Definition: playlist.cpp:843
bool activeplaylist_remove_items(const bit_array &mask)
Definition: playlist.cpp:182
void playlist_activate_delta(int p_delta)
Definition: playlist.cpp:741
bool get_all_items(pfc::list_base_t< metadb_handle_ptr > &out)
Definition: playlist.cpp:619
t_size create_playlist_autoname(t_size p_index=~0)
Definition: playlist.cpp:524
Set this flag to delay the progress dialog becoming visible, so it does not appear at all during shor...
Definition: playlist.h:791
t_size find_or_create_playlist_unlocked(const char *p_name, t_size p_name_length=~0)
Definition: playlist.cpp:507
t_size playlist_set_focus_by_handle(t_size p_playlist, metadb_handle_ptr p_item)
Definition: playlist.cpp:837
virtual void set(t_size n, bool val)=0
static void g_make_selection_move_permutation(t_size *p_output, t_size p_count, const bit_array &p_selection, int p_delta)
Definition: playlist.cpp:123
t_size activeplaylist_insert_items(t_size p_base, const pfc::list_base_const_t< metadb_handle_ptr > &data, const bit_array &p_selection)
Definition: playlist.cpp:202
void activeplaylist_get_items(pfc::list_base_t< metadb_handle_ptr > &out, const bit_array &p_mask)
Definition: playlist.cpp:557
bool activeplaylist_is_item_selected(t_size p_item)
Definition: playlist.cpp:222
t_size get_size() const
Definition: list.h:14
Set this flag to make the progress dialog not steal focus on creation.
Definition: metadb.h:120
size_t t_size
Definition: int_types.h:48
string8_fastalloc string_formatter
Definition: string_base.h:615
void set_size(t_size p_size)
Definition: array.h:104
bool remove_playlist(t_size p_playlist)
Helper; removes single playlist of specified index.
Definition: playlist.cpp:266
bool activeplaylist_insert_items_filter(t_size p_base, const pfc::list_base_const_t< metadb_handle_ptr > &p_data, bool p_select)
Definition: playlist.cpp:359
bool activeplaylist_get_focus_item_handle(metadb_handle_ptr &item)
Definition: playlist.cpp:489
bool playlist_find_item(t_size p_playlist, metadb_handle_ptr p_item, t_size &p_result)
Definition: playlist.cpp:821
void activeplaylist_get_selection_mask(bit_array_var &out)
Definition: playlist.cpp:248
bool activeplaylist_rename(const char *p_name, t_size p_name_len)
Definition: playlist.cpp:215
void to_handles_async(bool p_filter, HWND p_parentwnd, service_ptr_t< process_locations_notify > p_notify)
Definition: playlist.cpp:727
void activeplaylist_ensure_visible(t_size p_item)
Definition: playlist.cpp:209
bool activeplaylist_replace_item(t_size p_item, const metadb_handle_ptr &p_new_item)
Definition: playlist.cpp:189
void playlist_get_all_items(t_size p_playlist, pfc::list_base_t< metadb_handle_ptr > &out)
Definition: playlist.cpp:86
void create_move_items_permutation(t_size *p_output, t_size p_count, const class bit_array &p_selection, int p_delta)
Creates a permutation that moves selected items in a list box by the specified delta-offset.
bool activeplaylist_add_items(const pfc::list_base_const_t< metadb_handle_ptr > &data, const bit_array &p_selection)
Definition: playlist.cpp:343
bool activeplaylist_reorder_items(const t_size *order, t_size count)
Definition: playlist.cpp:169
Bit array interface class, variable version (you can both set and retrieve values). As with the constant version, valid index range depends on the context.
Definition: bit_array.h:40
bool playlist_find_item_selected(t_size p_playlist, metadb_handle_ptr p_item, t_size &p_result)
Definition: playlist.cpp:829
bool activeplaylist_get_name(pfc::string_base &p_out)
Definition: playlist.cpp:161
bool playlist_add_items_filter(t_size p_playlist, const pfc::list_base_const_t< metadb_handle_ptr > &p_data, bool p_select)
Definition: playlist.cpp:381
t_size activeplaylist_get_selection_count(t_size p_max)
Definition: playlist.cpp:475
t_display_level
Type used to indicate level of dynamic playback-related info displayed. Safe to use with <> opereator...
bool activeplaylist_sort_by_format(const char *spec, bool p_sel_only)
Definition: playlist.cpp:534
bool activeplaylist_add_items_filter(const pfc::list_base_const_t< metadb_handle_ptr > &p_data, bool p_select)
Definition: playlist.cpp:386
bool activeplaylist_insert_locations(t_size p_base, const pfc::list_base_const_t< const char * > &p_urls, bool p_select, HWND p_parentwnd)
Definition: playlist.cpp:374
bool playlist_move_selection(t_size p_playlist, int p_delta)
Moves selected items up/down in the playlist by specified offset.
Definition: playlist.cpp:127
Callback interface for playlist enumeration methods.
Definition: playlist.h:79
void activeplaylist_move_selection(int p_delta)
Definition: playlist.cpp:242
bool to_handles(pfc::list_base_t< metadb_handle_ptr > &p_out, bool p_filter, HWND p_parentwnd)
Definition: playlist.cpp:731
pfc::sized_int_t< sizeof(size_t) >::t_signed t_ssize
Definition: int_types.h:49
t_size activeplaylist_get_focus_item()
Definition: playlist.cpp:154
void activeplaylist_clear_selection()
Definition: playlist.cpp:410
void remove_all()
Definition: list.h:213
void activeplaylist_clear()
Definition: playlist.cpp:281
void playlist_clear_selection(t_size p_playlist)
Definition: playlist.cpp:405
bool activeplaylist_is_redo_available()
Definition: playlist.cpp:645
t_size bsearch_by_pointer(const metadb_handle_ptr &val) const
void activeplaylist_set_selection(const bit_array &affected, const bit_array &status)
Definition: playlist.cpp:176
bool activeplaylist_add_locations(const pfc::list_base_const_t< const char * > &p_urls, bool p_select, HWND p_parentwnd)
Definition: playlist.cpp:395
void attach(T *p_ptr)
Definition: com_ptr_t.h:31
void playlist_remove_selection(t_size p_playlist, bool p_crop=false)
Definition: playlist.cpp:436
virtual bool on_item(t_size p_index, const metadb_handle_ptr &p_location, bool b_selected)=0
bool remove_playlist_switch(t_size p_playlist)
Helper; removes single playlist of specified index, and switches to another playlist when possible...
Definition: playlist.cpp:652
bool activeplaylist_execute_default_action(t_size p_item)
Definition: playlist.cpp:685
void activeplaylist_get_selected_items(pfc::list_base_t< metadb_handle_ptr > &out)
Definition: playlist.cpp:260
pfc::com_ptr_t< interface IDataObject > create_dataobject_ex(metadb_handle_list_cref data)
Helper - returns a pfc::com_ptr_t<> rather than a raw pointer.
Definition: playlist.cpp:854
void activeplaylist_set_focus_item(t_size p_item)
Definition: playlist.cpp:196
bool is_valid() const
Definition: com_ptr_t.h:61
void playlist_set_selection_single(t_size p_playlist, t_size p_item, bool p_state)
Definition: playlist.cpp:457
void activeplaylist_undo_backup()
Definition: playlist.cpp:416
static bool guess_reorder_pattern(pfc::array_t< t_size > &out, const t_list1 &from, const t_list2 &to)
Helper template used to easily access core services. Usage: static_api_ptr_t<myclass> api; api->doso...
Definition: service.h:533
t_size find_or_create_playlist(const char *p_name, t_size p_name_length=~0)
Definition: playlist.cpp:517
void active_playlist_fix()
Definition: playlist.cpp:564
t_size get_size() const
Definition: array.h:130
void recycler_restore_by_id(t_uint32 id)
Definition: playlist.cpp:858
void activeplaylist_remove_selection(bool p_crop=false)
Definition: playlist.cpp:444
void remove_items_from_all_playlists(const pfc::list_base_const_t< metadb_handle_ptr > &p_data)
Definition: playlist.cpp:598
uint32_t t_uint32
Definition: int_types.h:5
bool process_location(const char *url, pfc::list_base_t< metadb_handle_ptr > &out, bool filter, const char *p_mask, const char *p_exclude, HWND p_parentwnd)
Helper - calls process_locations() with a single URL. See process_locations() for more info...
Definition: playlist.cpp:271
bool playlist_add_items(t_size playlist, const pfc::list_base_const_t< metadb_handle_ptr > &data, const bit_array &p_selection)
Definition: playlist.cpp:338