foobar2000 SDK  2015-01-14
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 {
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 {
403 }
404 
406 {
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);
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  {
573  }
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;
725  }
726 }
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
virtual void recycler_restore(t_size which)=0
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
virtual bool playlist_lock_is_present(t_size p_playlist)=0
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
metadb_handle_list m_handles
Definition: playlist.h:840
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
virtual bool playlist_is_redo_available(t_size p_playlist)=0
Returns whether a redo restore point is available for specified playlist.
virtual void playlist_set_selection(t_size p_playlist, const bit_array &p_affected, const bit_array &p_status)=0
Selects/deselects items on specified playlist.
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
virtual bool playlist_rename(t_size p_index, const char *p_name, t_size p_name_length)=0
Renames specified playlist.
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
virtual bool remove_playlists(const bit_array &p_mask)=0
Removes playlists according to specified mask. See also: bit_array.
t_size activeplaylist_set_focus_by_handle(metadb_handle_ptr p_item)
Definition: playlist.cpp:848
bit_array_table_t< bool > bit_array_table
virtual t_size create_playlist(const char *p_name, t_size p_name_length, t_size p_index)=0
Creates a new playlist.
bool activeplaylist_is_undo_available()
Definition: playlist.cpp:638
virtual t_size playlist_insert_items(t_size p_playlist, t_size p_base, const pfc::list_base_const_t< metadb_handle_ptr > &data, const bit_array &p_selection)=0
Inserts new items into specified playlist, at specified position.
virtual bool playlist_reorder_items(t_size p_playlist, const t_size *p_order, t_size p_count)=0
Reorders items in specified playlist according to specified permutation.
virtual void set_active_playlist(t_size p_index)=0
Sets active playlist (infinite to set no active playlist).
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
virtual t_size get_active_playlist()=0
Retrieves index of active playlist; infinite if no playlist is active.
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
virtual bool playlist_is_undo_available(t_size p_playlist)=0
Returns whether an undo restore point is available for specified playlist.
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
virtual bool playlist_execute_default_action(t_size p_playlist, t_size p_item)=0
Executes default doubleclick/enter action for specified item on specified playlist (starts playing th...
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
virtual interface IDataObject * create_dataobject(const pfc::list_base_const_t< metadb_handle_ptr > &p_data)=0
Creates an IDataObject from specified metadb_handle list. The caller is responsible for releasing the...
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
virtual void set_playing_playlist(t_size p_index)=0
Sets playlist from which items to be played are taken from.
virtual void playlist_ensure_visible(t_size p_playlist, t_size p_item)=0
Tells playlist renderers to make sure that specified item is visible.
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:614
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
virtual void playlist_item_format_title(t_size p_playlist, t_size p_item, titleformat_hook *p_hook, pfc::string_base &p_out, const service_ptr_t< titleformat_object > &p_script, titleformat_text_filter *p_filter, playback_control::t_display_level p_playback_info_level)=0
Renders information about specified playlist item, using specified titleformatting script parameters...
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.
virtual void playlist_enum_items(t_size p_playlist, enum_items_callback &p_callback, const bit_array &p_mask)=0
Enumerates contents of specified playlist.
bool activeplaylist_add_items(const pfc::list_base_const_t< metadb_handle_ptr > &data, const bit_array &p_selection)
Definition: playlist.cpp:343
virtual void playlist_undo_backup(t_size p_playlist)=0
Creates an undo restore point for specified playlist.
bool activeplaylist_reorder_items(const t_size *order, t_size count)
Definition: playlist.cpp:169
virtual void playlist_set_focus_item(t_size p_playlist, t_size p_item)=0
Sets index of focus item on specified playlist; use infinite to set no focus item.
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
virtual bool get_playing_item_location(t_size *p_playlist, t_size *p_index)=0
Retrieves playlist position of currently playing item.
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
virtual bool playlist_remove_items(t_size p_playlist, const bit_array &mask)=0
Removes specified items from specified playlist. Returns true on success or false on failure (playlis...
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
virtual t_size playlist_get_item_count(t_size p_playlist)=0
Retrieves number of items on specified playlist.
virtual bool process_locations(const pfc::list_base_const_t< const char * > &p_urls, pfc::list_base_t< metadb_handle_ptr > &p_out, bool p_filter, const char *p_restrict_mask_override, const char *p_exclude_mask_override, HWND p_parentwnd)=0
Converts one or more paths to a list of metadb_handles; displays a progress dialog. Note that this function creates modal dialog and does not return until the operation has completed.
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
virtual bool playlist_replace_item(t_size p_playlist, t_size p_item, const metadb_handle_ptr &p_new_item)=0
Replaces specified item on specified playlist. Returns true on success or false on failure (playlist ...
virtual bool playlist_get_name(t_size p_playlist, pfc::string_base &p_out)=0
Retrieves name of specified playlist. Should never fail unless the parameters are invalid...
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
virtual bool playlist_redo_restore(t_size p_playlist)=0
Reverts specified playlist to next redo restore point and generates an undo restore point...
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
virtual t_size get_playlist_count()=0
Retrieves number of playlists.
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)
virtual bool playlist_undo_restore(t_size p_playlist)=0
Reverts specified playlist to last undo restore point and generates a redo restore point...
virtual t_uint32 playlist_lock_get_filter_mask(t_size p_playlist)=0
Helper template used to easily access core services. Usage: static_api_ptr_t 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
pfc::string_list_impl m_paths
Definition: playlist.h:839
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
virtual void on_completion(unsigned p_code)=0
Called when an async operation has been completed. Note that on_completion is always called from main...
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
virtual t_size playlist_get_focus_item(t_size p_playlist)=0
Retrieves index of focus item on specified playlist; returns infinite when no item has focus...
virtual bool playlist_sort_by_format(t_size p_playlist, const char *p_pattern, bool p_sel_only)=0
Sorts specified playlist - entire playlist or selection only - by specified title formatting pattern...
virtual t_uint32 recycler_get_id(t_size which)=0
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