foobar2000 SDK  2015-01-14
menu_helpers.cpp
Go to the documentation of this file.
1 #include "foobar2000.h"
2 
3 
6  if (!menu_item_resolver::g_resolve_context_command(p_guid, ptr, index)) return false;
7  bool rv = ptr->get_item_description(index, out);
8  if (!rv) out.reset();
9  return rv;
10 }
11 
12 static bool run_context_command_internal(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller) {
13  if (data.get_count() == 0) return false;
15  if (!menu_item_resolver::g_resolve_context_command(p_command, ptr, index)) return false;
16 
17  {
18  TRACK_CALL_TEXT("menu_helpers::run_command(), by GUID");
19  ptr->item_execute_simple(index, p_subcommand, data, caller);
20  }
21 
22  return true;
23 }
24 
25 bool menu_helpers::run_command_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data)
26 {
27  return run_context_command_internal(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
28 }
29 
30 bool menu_helpers::run_command_context_ex(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller)
31 {
32  return run_context_command_internal(p_command,p_subcommand,data,caller);
33 }
34 
36 {
38  return menu_item_resolver::g_resolve_context_command(p_guid, ptr, index);
39 }
40 
41 static bool g_is_checked(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data,const GUID & caller)
42 {
44  if (!menu_item_resolver::g_resolve_context_command(p_command, ptr, index)) return false;
45 
46  unsigned displayflags = 0;
47  pfc::string_formatter dummystring;
48  if (!ptr->item_get_display_data(dummystring,displayflags,index,p_subcommand,data,caller)) return false;
49  return (displayflags & contextmenu_item_node::FLAG_CHECKED) != 0;
50 
51 }
52 
53 bool menu_helpers::is_command_checked_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data)
54 {
55  return g_is_checked(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
56 }
57 
58 bool menu_helpers::is_command_checked_context_playlist(const GUID & p_command,const GUID & p_subcommand)
59 {
60  metadb_handle_list temp;
62  api->activeplaylist_get_selected_items(temp);
63  return g_is_checked(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
64 }
65 
66 
67 
68 
69 
70 
71 
72 bool menu_helpers::run_command_context_playlist(const GUID & p_command,const GUID & p_subcommand)
73 {
74  metadb_handle_list temp;
76  api->activeplaylist_get_selected_items(temp);
77  return run_command_context_ex(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
78 }
79 
80 bool menu_helpers::run_command_context_now_playing(const GUID & p_command,const GUID & p_subcommand)
81 {
82  metadb_handle_ptr item;
83  if (!static_api_ptr_t<playback_control>()->get_now_playing(item)) return false;//not playing
85 }
86 
87 
88 bool menu_helpers::guid_from_name(const char * p_name,unsigned p_name_len,GUID & p_out)
89 {
92  pfc::string8_fastalloc nametemp;
93  while(e.next(ptr))
94  {
95  unsigned n, m = ptr->get_num_items();
96  for(n=0;n<m;n++)
97  {
98  ptr->get_item_name(n,nametemp);
99  if (!strcmp_ex(nametemp,~0,p_name,p_name_len))
100  {
101  p_out = ptr->get_item_guid(n);
102  return true;
103  }
104  }
105  }
106  return false;
107 }
108 
109 bool menu_helpers::name_from_guid(const GUID & p_guid,pfc::string_base & p_out) {
111  if (!menu_item_resolver::g_resolve_context_command(p_guid, ptr, index)) return false;
112  ptr->get_item_name(index, p_out);
113  return true;
114 }
115 
116 
117 static unsigned calc_total_action_count()
118 {
121  unsigned ret = 0;
122  while(e.next(ptr))
123  ret += ptr->get_num_items();
124  return ret;
125 }
126 
127 
128 const char * menu_helpers::guid_to_name_table::search(const GUID & p_guid)
129 {
130  if (!m_inited)
131  {
132  m_data.set_size(calc_total_action_count());
133  t_size dataptr = 0;
134  pfc::string8_fastalloc nametemp;
135 
138  while(e.next(ptr))
139  {
140  unsigned n, m = ptr->get_num_items();
141  for(n=0;n<m;n++)
142  {
143  assert(dataptr < m_data.get_size());
144 
145  ptr->get_item_name(n,nametemp);
146  m_data[dataptr].m_name = _strdup(nametemp);
147  m_data[dataptr].m_guid = ptr->get_item_guid(n);
148  dataptr++;
149  }
150  }
151  assert(dataptr == m_data.get_size());
152 
154  m_inited = true;
155  }
156  t_size index;
157  if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,p_guid,index))
158  return m_data[index].m_name;
159  else
160  return 0;
161 }
162 
164 {
165  return pfc::guid_compare(entry1.m_guid,entry2);
166 }
167 
169 {
170  return pfc::guid_compare(entry1.m_guid,entry2.m_guid);
171 }
172 
174 {
175  m_inited = false;
176 }
177 
179 {
180  t_size n, m = m_data.get_size();
181  for(n=0;n<m;n++) free(m_data[n].m_name);
182 
183 }
184 
185 
187 {
188  return stricmp_utf8_ex(entry1.m_name,~0,entry2.m_name,entry2.m_name_len);
189 }
190 
192 {
193  return stricmp_utf8(entry1.m_name,entry2.m_name);
194 }
195 
196 bool menu_helpers::name_to_guid_table::search(const char * p_name,unsigned p_name_len,GUID & p_out)
197 {
198  if (!m_inited)
199  {
200  m_data.set_size(calc_total_action_count());
201  t_size dataptr = 0;
202  pfc::string8_fastalloc nametemp;
203 
206  while(e.next(ptr))
207  {
208  unsigned n, m = ptr->get_num_items();
209  for(n=0;n<m;n++)
210  {
211  assert(dataptr < m_data.get_size());
212 
213  ptr->get_item_name(n,nametemp);
214  m_data[dataptr].m_name = _strdup(nametemp);
215  m_data[dataptr].m_guid = ptr->get_item_guid(n);
216  dataptr++;
217  }
218  }
219  assert(dataptr == m_data.get_size());
220 
221  pfc::sort_t(m_data,entry_compare,m_data.get_size());
222  m_inited = true;
223  }
224  t_size index;
225  search_entry temp = {p_name,p_name_len};
226  if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,temp,index))
227  {
228  p_out = m_data[index].m_guid;
229  return true;
230  }
231  else
232  return false;
233 }
234 
236 {
237  m_inited = false;
238 }
239 
241 {
242  t_size n, m = m_data.get_size();
243  for(n=0;n<m;n++) free(m_data[n].m_name);
244 
245 }
246 
247 bool menu_helpers::find_command_by_name(const char * p_name,service_ptr_t<contextmenu_item> & p_item,unsigned & p_index)
248 {
249  pfc::string8_fastalloc path,name;
252  if (e.first(ptr)) do {
253 // if (ptr->get_type()==type)
254  {
255  unsigned action,num_actions = ptr->get_num_items();
256  for(action=0;action<num_actions;action++)
257  {
258  ptr->get_item_default_path(action,path); ptr->get_item_name(action,name);
259  if (!path.is_empty()) path += "/";
260  path += name;
261  if (!stricmp_utf8(p_name,path))
262  {
263  p_item = ptr;
264  p_index = action;
265  return true;
266  }
267  }
268  }
269  } while(e.next(ptr));
270  return false;
271 
272 }
273 
274 bool menu_helpers::find_command_by_name(const char * p_name,GUID & p_command)
275 {
277  unsigned index;
278  bool ret = find_command_by_name(p_name,item,index);
279  if (ret) p_command = item->get_item_guid(index);
280  return ret;
281 }
282 
283 
284 bool standard_commands::run_main(const GUID & p_guid) {
285  t_uint32 index;
286  mainmenu_commands::ptr ptr;
287  if (!menu_item_resolver::g_resolve_main_command(p_guid, ptr, index)) return false;
288  ptr->execute(index,service_ptr_t<service_base>());
289  return true;
290 }
291 
292 bool menu_item_resolver::g_resolve_context_command(const GUID & id, contextmenu_item::ptr & out, t_uint32 & out_index) {
293  return static_api_ptr_t<menu_item_resolver>()->resolve_context_command(id, out, out_index);
294 }
295 bool menu_item_resolver::g_resolve_main_command(const GUID & id, mainmenu_commands::ptr & out, t_uint32 & out_index) {
296  return static_api_ptr_t<menu_item_resolver>()->resolve_main_command(id, out, out_index);
297 }
Definition: menu_helpers.h:55
bool context_get_description(const GUID &p_guid, pfc::string_base &out)
Definition: menu_helpers.cpp:4
bool name_from_guid(const GUID &p_guid, pfc::string_base &p_out)
int SHARED_EXPORT stricmp_utf8_ex(const char *p1, t_size len1, const char *p2, t_size len2)
bool run_command_context_playlist(const GUID &p_command, const GUID &p_subcommand)
static const GUID caller_now_playing
Definition: contextmenu.h:138
Definition: pfc.h:53
static bool run_main(const GUID &guid)
bool first(service_ptr_t< t_query > &p_out)
Definition: service.h:581
bool search(const char *p_name, unsigned p_name_len, GUID &p_out)
static int entry_compare_search(const entry &entry1, const search_entry &entry2)
bool run_command_context_now_playing(const GUID &p_command, const GUID &p_subcommand)
bool run_command_context(const GUID &p_command, const GUID &p_subcommand, const pfc::list_base_const_t< metadb_handle_ptr > &data)
int SHARED_EXPORT stricmp_utf8(const char *p1, const char *p2)
static bool g_resolve_main_command(const GUID &id, service_ptr_t< class mainmenu_commands > &out, t_uint32 &out_index)
static int entry_compare(const entry &entry1, const entry &entry2)
bool find_command_by_name(const char *p_name, service_ptr_t< contextmenu_item > &p_item, unsigned &p_index)
int guid_compare(const GUID &g1, const GUID &g2)
Definition: guid.h:18
const char * search(const GUID &p_guid)
int strcmp_ex(const char *p1, t_size n1, const char *p2, t_size n2)
size_t t_size
Definition: int_types.h:48
string8_fastalloc string_formatter
Definition: string_base.h:614
bool guid_from_name(const char *p_name, unsigned p_name_len, GUID &p_out)
virtual t_size get_count() const =0
bool is_command_checked_context_playlist(const GUID &p_command, const GUID &p_subcommand)
bool is_command_checked_context(const GUID &p_command, const GUID &p_subcommand, const pfc::list_base_const_t< metadb_handle_ptr > &data)
static const GUID caller_undefined
Definition: contextmenu.h:139
static const GUID caller_playlist
Deprecated - use caller_active_playlist_selection instead.
Definition: contextmenu.h:136
static bool g_resolve_context_command(const GUID &id, service_ptr_t< class contextmenu_item > &out, t_uint32 &out_index)
static void sort_t(t_container &p_data, t_compare p_compare, t_size p_count)
Definition: sort.h:162
pfc::array_t< entry > m_data
Definition: menu_helpers.h:35
Autopointer class to be used with all services. Manages reference counter calls behind-the-scenes.
Definition: service.h:55
bool test_command_context(const GUID &p_guid)
static int entry_compare(const entry &entry1, const entry &entry2)
Helper template used to easily access core services. Usage: static_api_ptr_t api; api->doso...
Definition: service.h:533
bool next(service_ptr_t< t_query > &p_out)
Definition: service.h:587
string8_t< pfc::alloc_fast_aggressive > string8_fastalloc
Definition: string_base.h:435
bool run_command_context_ex(const GUID &p_command, const GUID &p_subcommand, const pfc::list_base_const_t< metadb_handle_ptr > &data, const GUID &caller)
bool bsearch_t(t_size p_count, const t_container &p_container, t_compare p_compare, const t_param &p_param, t_size &p_index)
Definition: bsearch.h:48
uint32_t t_uint32
Definition: int_types.h:5
static int entry_compare_search(const entry &entry1, const GUID &entry2)