annotate foosdk/sdk/foobar2000/SDK/menu_helpers.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "foobar2000-sdk-pch.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "menu_helpers.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "metadb.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "playlist.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 bool menu_helpers::context_get_description(const GUID& p_guid,pfc::string_base & out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 service_ptr_t<contextmenu_item> ptr; t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 if (!menu_item_resolver::g_resolve_context_command(p_guid, ptr, index)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 bool rv = ptr->get_item_description(index, out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 if (!rv) out.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 return rv;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 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) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 if (data.get_count() == 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 service_ptr_t<contextmenu_item> ptr; t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 if (!menu_item_resolver::g_resolve_context_command(p_command, ptr, index)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 TRACK_CALL_TEXT("menu_helpers::run_command(), by GUID");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 ptr->item_execute_simple(index, p_subcommand, data, caller);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 bool menu_helpers::run_command_context(const GUID & p_command,const GUID & p_subcommand,const pfc::list_base_const_t<metadb_handle_ptr> & data)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 return run_context_command_internal(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 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)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 return run_context_command_internal(p_command,p_subcommand,data,caller);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 bool menu_helpers::test_command_context(const GUID & p_guid)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 service_ptr_t<contextmenu_item> ptr; t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 return menu_item_resolver::g_resolve_context_command(p_guid, ptr, index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 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)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 service_ptr_t<contextmenu_item> ptr; t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 if (!menu_item_resolver::g_resolve_context_command(p_command, ptr, index)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 unsigned displayflags = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 pfc::string_formatter dummystring;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 if (!ptr->item_get_display_data(dummystring,displayflags,index,p_subcommand,data,caller)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 return (displayflags & contextmenu_item_node::FLAG_CHECKED) != 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 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)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 return g_is_checked(p_command,p_subcommand,data,contextmenu_item::caller_undefined);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 bool menu_helpers::is_command_checked_context_playlist(const GUID & p_command,const GUID & p_subcommand)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 metadb_handle_list temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 playlist_manager::get()->activeplaylist_get_selected_items(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 return g_is_checked(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 bool menu_helpers::run_command_context_playlist(const GUID & p_command,const GUID & p_subcommand)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 metadb_handle_list temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 playlist_manager::get()->activeplaylist_get_selected_items(temp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 return run_command_context_ex(p_command,p_subcommand,temp,contextmenu_item::caller_playlist);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 bool menu_helpers::run_command_context_now_playing(const GUID & p_command,const GUID & p_subcommand)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 metadb_handle_ptr item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 if (!playback_control::get()->get_now_playing(item)) return false;//not playing
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 return run_command_context_ex(p_command,p_subcommand,pfc::list_single_ref_t<metadb_handle_ptr>(item),contextmenu_item::caller_now_playing);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 bool menu_helpers::guid_from_name(const char * p_name,unsigned p_name_len,GUID & p_out)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 pfc::string8_fastalloc nametemp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 for( auto ptr : contextmenu_item::enumerate() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 unsigned n, m = ptr->get_num_items();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 ptr->get_item_name(n,nametemp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 if (!strcmp_ex(nametemp,SIZE_MAX,p_name,p_name_len))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 p_out = ptr->get_item_guid(n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 bool menu_helpers::name_from_guid(const GUID & p_guid,pfc::string_base & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 service_ptr_t<contextmenu_item> ptr; t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 if (!menu_item_resolver::g_resolve_context_command(p_guid, ptr, index)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 ptr->get_item_name(index, p_out);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 static unsigned calc_total_action_count()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 unsigned ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 for( auto ptr : contextmenu_item::enumerate()) ret += ptr->get_num_items();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 const char * menu_helpers::guid_to_name_table::search(const GUID & p_guid)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 if (!m_inited)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 m_data.set_size(calc_total_action_count());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 t_size dataptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 pfc::string8_fastalloc nametemp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 for( auto ptr : contextmenu_item::enumerate())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 unsigned n, m = ptr->get_num_items();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 assert(dataptr < m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 ptr->get_item_name(n,nametemp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 m_data[dataptr].m_name = pfc::strDup(nametemp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 m_data[dataptr].m_guid = ptr->get_item_guid(n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 dataptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 assert(dataptr == m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 pfc::sort_t(m_data,entry_compare,m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 m_inited = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 t_size index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,p_guid,index))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 return m_data[index].m_name;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 int menu_helpers::guid_to_name_table::entry_compare_search(const entry & entry1,const GUID & entry2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 return pfc::guid_compare(entry1.m_guid,entry2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 int menu_helpers::guid_to_name_table::entry_compare(const entry & entry1,const entry & entry2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 return pfc::guid_compare(entry1.m_guid,entry2.m_guid);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 menu_helpers::guid_to_name_table::guid_to_name_table()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 m_inited = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 menu_helpers::guid_to_name_table::~guid_to_name_table()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 t_size n, m = m_data.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 for(n=0;n<m;n++) free(m_data[n].m_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 int menu_helpers::name_to_guid_table::entry_compare_search(const entry & entry1,const search_entry & entry2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 return stricmp_utf8_ex(entry1.m_name,SIZE_MAX,entry2.m_name,entry2.m_name_len);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 int menu_helpers::name_to_guid_table::entry_compare(const entry & entry1,const entry & entry2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 return stricmp_utf8(entry1.m_name,entry2.m_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 bool menu_helpers::name_to_guid_table::search(const char * p_name,unsigned p_name_len,GUID & p_out)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 if (!m_inited)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 m_data.set_size(calc_total_action_count());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 t_size dataptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 pfc::string8_fastalloc nametemp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 for( auto ptr : contextmenu_item::enumerate() )
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 unsigned n, m = ptr->get_num_items();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 for(n=0;n<m;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 assert(dataptr < m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 ptr->get_item_name(n,nametemp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 m_data[dataptr].m_name = pfc::strDup(nametemp);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 m_data[dataptr].m_guid = ptr->get_item_guid(n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 dataptr++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 assert(dataptr == m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 pfc::sort_t(m_data,entry_compare,m_data.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 m_inited = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 t_size index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 search_entry temp = {p_name,p_name_len};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 if (pfc::bsearch_t(m_data.get_size(),m_data,entry_compare_search,temp,index))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 p_out = m_data[index].m_guid;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 menu_helpers::name_to_guid_table::name_to_guid_table()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 m_inited = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 menu_helpers::name_to_guid_table::~name_to_guid_table()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 t_size n, m = m_data.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 for(n=0;n<m;n++) free(m_data[n].m_name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 bool menu_helpers::find_command_by_name(const char * p_name,service_ptr_t<contextmenu_item> & p_item,unsigned & p_index)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 pfc::string8_fastalloc path,name;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 for (auto ptr : contextmenu_item::enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 // if (ptr->get_type()==type)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 unsigned action, num_actions = ptr->get_num_items();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 for (action = 0; action < num_actions; action++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 ptr->get_item_default_path(action, path); ptr->get_item_name(action, name);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 if (!path.is_empty()) path += "/";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 path += name;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 if (!stricmp_utf8(p_name, path))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 p_item = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 p_index = action;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 bool menu_helpers::find_command_by_name(const char * p_name,GUID & p_command)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 service_ptr_t<contextmenu_item> item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 unsigned index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 bool ret = find_command_by_name(p_name,item,index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 if (ret) p_command = item->get_item_guid(index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 bool standard_commands::run_main(const GUID & p_guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 t_uint32 index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 mainmenu_commands::ptr ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 if (!menu_item_resolver::g_resolve_main_command(p_guid, ptr, index)) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 ptr->execute(index,service_ptr_t<service_base>());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 bool menu_item_resolver::g_resolve_context_command(const GUID & id, contextmenu_item::ptr & out, t_uint32 & out_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 return menu_item_resolver::get()->resolve_context_command(id, out, out_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 bool menu_item_resolver::g_resolve_main_command(const GUID & id, mainmenu_commands::ptr & out, t_uint32 & out_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 return menu_item_resolver::get()->resolve_main_command(id, out, out_index);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 static bool char_is_separator(char x)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 for( auto s : {' ', ',', '/', '-'}) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 if (x==s) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 static bool capitalize_exception( const char * ptr, size_t len ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 for( auto e : {"for", "to", "from", "with", "by", "in", "at", "and", "or", "on", "a", "of", "as" }) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 if ( len == strlen(e) && memcmp(ptr, e, len) == 0 ) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 #if FB2K_MENU_CAPS == FB2K_MENU_CAPS_TITLE
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 static pfc::string8 capitalizeThis( const char * arg ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 pfc::string8 work; work.prealloc( 256 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 auto base = arg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 while(*base) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 auto ptr = base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 while(*ptr && ! char_is_separator(*ptr) ) ++ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 if ( ptr > base ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 if ( !capitalize_exception( base, ptr-base ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 unsigned c = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 auto d = pfc::utf8_decode_char(base, c, ptr-base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 if ( d > 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 c = uCharUpper( c );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 work.add_char( c );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 base += d;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 work.add_string_nc(base, ptr - base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 while(*ptr && char_is_separator(*ptr)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 work.add_byte(*ptr++);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 base = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 return work;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 #endif // #if FB2K_MENU_CAPS == FB2K_MENU_CAPS_TITLE
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 void fb2k::capitalizeMenuLabel( pfc::string_base & inOut ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 #if FB2K_MENU_CAPS == FB2K_MENU_CAPS_TITLE
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 inOut = capitalizeThis( inOut );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 (void) inOut;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 }