18 #include "m_property.h"
19 #include "asxparser.h"
21 #include "libmpcodecs/img_format.h"
22 #include "libmpcodecs/mp_image.h"
25 #include "menu_list.h"
26 #include "input/input.h"
27 #include "osdep/keycodes.h"
46 static struct menu_priv_s cfg_dflt
= {
54 static m_option_t cfg_fields
[] = {
55 MENU_LIST_PRIV_FIELDS
,
56 { "title", M_ST_OFF(menu_list_priv_t
,title
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
57 { "na", M_ST_OFF(struct menu_priv_s
,na
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
58 { "hide-na", M_ST_OFF(struct menu_priv_s
,hide_na
), CONF_TYPE_FLAG
, CONF_RANGE
, 0, 1, NULL
},
59 { NULL
, NULL
, NULL
, 0,0,0,NULL
}
62 #define mpriv (menu->priv)
64 #define OPT_NAME "name"
65 #define OPT_VCODEC "vcodec"
66 #define OPT_VBITRATE "vbitrate"
67 #define OPT_RESOLUTION "resolution"
68 #define OPT_ACODEC "acodec"
69 #define OPT_ABITRATE "abitrate"
70 #define OPT_SAMPLES "asamples"
71 #define OPT_INFO_TITLE "title"
72 #define OPT_INFO_ARTIST "artist"
73 #define OPT_INFO_ALBUM "album"
74 #define OPT_INFO_YEAR "year"
75 #define OPT_INFO_COMMENT "comment"
76 #define OPT_INFO_TRACK "track"
77 #define OPT_INFO_GENRE "genre"
79 m_option_t
* mp_property_find(const char* name
);
81 static void entry_set_text(menu_t
* menu
, list_entry_t
* e
) {
82 char* val
= m_property_print(e
->opt
);
83 int l
,edit
= (mpriv
->edit
&& e
== mpriv
->p
.current
);
89 val
= strdup(mpriv
->na
);
90 } else if(mpriv
->hide_na
)
92 l
= strlen(e
->name
) + 2 + strlen(val
) + (edit
? 4 : 0) + 1;
93 if(e
->p
.txt
) free(e
->p
.txt
);
95 sprintf(e
->p
.txt
,"%s: %s%s%s",e
->name
,edit
? "> " : "",val
,edit
? " <" : "");
99 static void update_entries(menu_t
* menu
) {
101 for(e
= mpriv
->p
.menu
; e
; e
= e
->p
.next
)
102 if(e
->opt
) entry_set_text(menu
,e
);
105 static int parse_args(menu_t
* menu
,char* args
) {
106 char *element
,*body
, **attribs
, *name
, *meta
, *val
;
107 list_entry_t
* m
= NULL
;
110 ASX_Parser_t
* parser
= asx_parser_new();
114 r
= asx_get_element(parser
,&args
,&element
,&body
,&attribs
);
116 mp_msg(MSGT_OSD_MENU
,MSGL_ERR
,MSGTR_LIBMENU_SyntaxErrorAtLine
,parser
->line
);
117 asx_parser_free(parser
);
120 asx_parser_free(parser
);
122 mp_msg(MSGT_OSD_MENU
,MSGL_WARN
,MSGTR_LIBMENU_NoEntryFoundInTheMenuDefinition
);
123 m
= calloc(1,sizeof(struct list_entry_s
));
124 m
->p
.txt
= strdup("Back");
125 menu_list_add_entry(menu
,m
);
128 if(!strcmp(element
,"menu")) {
129 name
= asx_get_attrib("menu",attribs
);
131 mp_msg(MSGT_OSD_MENU
,MSGL_WARN
,MSGTR_LIBMENU_SubmenuDefinitionNeedAMenuAttribut
);
134 m
= calloc(1,sizeof(struct list_entry_s
));
136 name
= NULL
; // we want to keep it
137 m
->p
.txt
= asx_get_attrib("name",attribs
);
138 if(!m
->p
.txt
) m
->p
.txt
= strdup(m
->menu
);
139 menu_list_add_entry(menu
,m
);
143 meta
= asx_get_attrib("meta",attribs
);
146 if (!strcmp (meta
, OPT_NAME
))
147 val
= get_metadata (META_NAME
);
148 else if (!strcmp (meta
, OPT_VCODEC
))
149 val
= get_metadata (META_VIDEO_CODEC
);
150 else if (!strcmp(meta
, OPT_VBITRATE
))
151 val
= get_metadata (META_VIDEO_BITRATE
);
152 else if(!strcmp(meta
, OPT_RESOLUTION
))
153 val
= get_metadata (META_VIDEO_RESOLUTION
);
154 else if (!strcmp(meta
, OPT_ACODEC
))
155 val
= get_metadata (META_AUDIO_CODEC
);
156 else if(!strcmp(meta
, OPT_ABITRATE
))
157 val
= get_metadata (META_AUDIO_BITRATE
);
158 else if(!strcmp(meta
, OPT_SAMPLES
))
159 val
= get_metadata (META_AUDIO_SAMPLES
);
160 else if (!strcmp (meta
, OPT_INFO_TITLE
))
161 val
= get_metadata (META_INFO_TITLE
);
162 else if (!strcmp (meta
, OPT_INFO_ARTIST
))
163 val
= get_metadata (META_INFO_ARTIST
);
164 else if (!strcmp (meta
, OPT_INFO_ALBUM
))
165 val
= get_metadata (META_INFO_ALBUM
);
166 else if (!strcmp (meta
, OPT_INFO_YEAR
))
167 val
= get_metadata (META_INFO_YEAR
);
168 else if (!strcmp (meta
, OPT_INFO_COMMENT
))
169 val
= get_metadata (META_INFO_COMMENT
);
170 else if (!strcmp (meta
, OPT_INFO_TRACK
))
171 val
= get_metadata (META_INFO_TRACK
);
172 else if (!strcmp (meta
, OPT_INFO_GENRE
))
173 val
= get_metadata (META_INFO_GENRE
);
175 char *item
= asx_get_attrib("name",attribs
);
179 item
= strdup (meta
);
180 l
= strlen(item
) + 2 + strlen(val
) + 1;
181 m
= calloc(1,sizeof(struct list_entry_s
));
182 m
->p
.txt
= malloc(l
);
183 sprintf(m
->p
.txt
,"%s: %s",item
,val
);
186 menu_list_add_entry(menu
,m
);
193 asx_free_attribs(attribs
);
197 name
= asx_get_attrib("property",attribs
);
198 opt
= name
? mp_property_find(name
) : NULL
;
200 mp_msg(MSGT_OSD_MENU
,MSGL_WARN
,MSGTR_LIBMENU_PrefMenuEntryDefinitionsNeed
,parser
->line
);
203 m
= calloc(1,sizeof(struct list_entry_s
));
205 m
->name
= asx_get_attrib("name",attribs
);
206 if(!m
->name
) m
->name
= strdup(opt
->name
);
207 entry_set_text(menu
,m
);
208 menu_list_add_entry(menu
,m
);
214 asx_free_attribs(attribs
);
218 static void read_key(menu_t
* menu
,int c
) {
219 menu_list_read_key(menu
,c
,0);
222 static void read_cmd(menu_t
* menu
,int cmd
) {
223 list_entry_t
* e
= mpriv
->p
.current
;
228 if(!mpriv
->edit
) break;
230 if(m_property_do(e
->opt
,M_PROPERTY_STEP_UP
,NULL
) > 0)
231 update_entries(menu
);
234 if(!mpriv
->edit
) break;
236 if(m_property_do(e
->opt
,M_PROPERTY_STEP_DOWN
,NULL
) > 0)
237 update_entries(menu
);
241 // check that the property is writable
242 if(m_property_do(e
->opt
,M_PROPERTY_SET
,NULL
) < 0) return;
243 // shortcut for flags
244 if(e
->opt
->type
== CONF_TYPE_FLAG
) {
245 if(m_property_do(e
->opt
,M_PROPERTY_STEP_UP
,NULL
) > 0)
246 update_entries(menu
);
250 mpriv
->edit
= !mpriv
->edit
;
252 update_entries(menu
);
253 // switch the pointer
255 mpriv
->ptr
= mpriv
->p
.ptr
;
258 mpriv
->p
.ptr
= mpriv
->ptr
;
260 case MENU_CMD_CANCEL
:
261 if(!mpriv
->edit
) break;
263 update_entries(menu
);
264 mpriv
->p
.ptr
= mpriv
->ptr
;
272 char* txt
= malloc(10 + strlen(e
->menu
) + 1);
273 sprintf(txt
,"set_menu %s",e
->menu
);
274 c
= mp_input_parse_cmd(txt
);
275 if(c
) mp_input_queue_cmd(c
);
288 menu_list_read_cmd(menu
,cmd
);
291 static void free_entry(list_entry_t
* entry
) {
293 if(entry
->name
) free(entry
->name
);
294 if(entry
->menu
) free(entry
->menu
);
298 static void closeMenu(menu_t
* menu
) {
299 menu_list_uninit(menu
,free_entry
);
302 static int openMenu(menu_t
* menu
, char* args
) {
304 menu
->draw
= menu_list_draw
;
305 menu
->read_cmd
= read_cmd
;
306 menu
->read_key
= read_key
;
307 menu
->close
= closeMenu
;
311 mp_msg(MSGT_OSD_MENU
,MSGL_ERR
,MSGTR_LIBMENU_PrefMenuNeedsAnArgument
);
315 menu_list_init(menu
);
316 return parse_args(menu
,args
);
319 const menu_info_t menu_info_pref
= {
326 sizeof(struct menu_priv_s
),