1 /* ncmpc (Ncurses MPD Client)
2 * (c) 2004-2010 The Music Player Daemon Project
3 * Project homepage: http://musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "screen_keydef.h"
21 #include "screen_interface.h"
22 #include "screen_message.h"
23 #include "screen_find.h"
27 #include "screen_utils.h"
34 #define STATIC_ITEMS 0
35 #define STATIC_SUB_ITEMS 1
38 #define LIST_ITEM_APPLY() ((unsigned)command_list_length)
39 #define LIST_ITEM_SAVE() (LIST_ITEM_APPLY()+1)
40 #define LIST_LENGTH() (LIST_ITEM_SAVE()+1)
42 #define LIST_ITEM_SAVE_LABEL _("===> Apply & Save key bindings ")
43 #define LIST_ITEM_APPLY_LABEL _("===> Apply key bindings ")
46 static struct list_window
*lw
;
47 static unsigned command_list_length
= 0;
48 static command_definition_t
*cmds
= NULL
;
50 static int subcmd
= -1;
51 static unsigned subcmd_length
= 0;
52 static unsigned subcmd_addpos
= 0;
55 keybindings_changed(void)
57 command_definition_t
*orginal_cmds
= get_command_definitions();
58 size_t size
= command_list_length
* sizeof(command_definition_t
);
60 return memcmp(orginal_cmds
, cmds
, size
);
66 if (keybindings_changed()) {
67 command_definition_t
*orginal_cmds
= get_command_definitions();
68 size_t size
= command_list_length
* sizeof(command_definition_t
);
70 memcpy(orginal_cmds
, cmds
, size
);
71 screen_status_printf(_("You have new key bindings"));
73 screen_status_printf(_("Keybindings unchanged."));
82 if (check_user_conf_dir()) {
83 screen_status_printf(_("Error: Unable to create directory ~/.ncmpc - %s"),
89 filename
= get_user_key_binding_filename();
91 if ((f
= fopen(filename
,"w")) == NULL
) {
92 screen_status_printf(_("Error: %s - %s"), filename
, strerror(errno
));
98 if (write_key_bindings(f
, KEYDEF_WRITE_HEADER
))
99 screen_status_printf(_("Error: %s - %s"), filename
, strerror(errno
));
101 screen_status_printf(_("Wrote %s"), filename
);
108 check_subcmd_length(void)
111 while (subcmd_length
< MAX_COMMAND_KEYS
&&
112 cmds
[subcmd
].keys
[subcmd_length
] > 0)
115 if (subcmd_length
< MAX_COMMAND_KEYS
) {
116 subcmd_addpos
= subcmd_length
;
120 subcmd_length
+= STATIC_SUB_ITEMS
;
121 list_window_set_length(lw
, subcmd_length
);
135 delete_key(int cmd_index
, int key_index
)
139 screen_status_printf(_("Deleted"));
140 while (i
< MAX_COMMAND_KEYS
&& cmds
[cmd_index
].keys
[i
])
141 cmds
[cmd_index
].keys
[key_index
++] = cmds
[cmd_index
].keys
[i
++];
142 cmds
[cmd_index
].keys
[key_index
] = 0;
143 cmds
[cmd_index
].flags
|= COMMAND_KEY_MODIFIED
;
144 check_subcmd_length();
149 /* update key conflict flags */
150 check_key_bindings(cmds
, NULL
, 0);
154 assign_new_key(int cmd_index
, int key_index
)
160 buf
= g_strdup_printf(_("Enter new key for %s: "), cmds
[cmd_index
].name
);
161 key
= screen_getch(buf
);
165 screen_status_printf(_("Aborted"));
169 cmd
= find_key_command(key
, cmds
);
170 if (cmd
!= CMD_NONE
&& cmd
!= cmds
[cmd_index
].command
) {
171 screen_status_printf(_("Error: key %s is already used for %s"),
173 get_key_command_name(cmd
));
178 cmds
[cmd_index
].keys
[key_index
] = key
;
179 cmds
[cmd_index
].flags
|= COMMAND_KEY_MODIFIED
;
181 screen_status_printf(_("Assigned %s to %s"),
182 key2str(key
),cmds
[cmd_index
].name
);
183 check_subcmd_length();
188 /* update key conflict flags */
189 check_key_bindings(cmds
, NULL
, 0);
193 list_callback(unsigned idx
, G_GNUC_UNUSED
void *data
)
195 static char buf
[BUFSIZE
];
198 if (idx
== LIST_ITEM_APPLY())
199 return LIST_ITEM_APPLY_LABEL
;
200 else if (idx
== LIST_ITEM_SAVE())
201 return LIST_ITEM_SAVE_LABEL
;
203 assert(idx
< (unsigned)command_list_length
);
205 return cmds
[idx
].name
;
210 if (idx
== subcmd_addpos
) {
211 g_snprintf(buf
, BUFSIZE
, "%d. %s",
212 idx
+ 1, _("Add new key"));
216 assert(idx
< MAX_COMMAND_KEYS
&& cmds
[subcmd
].keys
[idx
] > 0);
219 BUFSIZE
, "%d. %-20s (%d) ",
221 key2str(cmds
[subcmd
].keys
[idx
]),
222 cmds
[subcmd
].keys
[idx
]);
228 keydef_init(WINDOW
*w
, int cols
, int rows
)
230 lw
= list_window_init(w
, cols
, rows
);
234 keydef_resize(int cols
, int rows
)
236 list_window_resize(lw
, cols
, rows
);
242 list_window_free(lw
);
250 keydef_open(G_GNUC_UNUSED
struct mpdclient
*c
)
253 command_definition_t
*current_cmds
= get_command_definitions();
256 command_list_length
= 0;
257 while (current_cmds
[command_list_length
].name
)
258 command_list_length
++;
260 cmds_size
= (command_list_length
+1) * sizeof(command_definition_t
);
261 cmds
= g_malloc0(cmds_size
);
262 memcpy(cmds
, current_cmds
, cmds_size
);
263 command_list_length
+= STATIC_ITEMS
;
267 list_window_set_length(lw
, LIST_LENGTH());
273 if (cmds
&& !keybindings_changed()) {
277 screen_status_printf(_("Note: Did you forget to \'Apply\' your changes?"));
281 keydef_title(char *str
, size_t size
)
284 return _("Edit key bindings");
286 g_snprintf(str
, size
, _("Edit keys for %s"), cmds
[subcmd
].name
);
293 list_window_paint(lw
, list_callback
, NULL
);
297 keydef_cmd(G_GNUC_UNUSED
struct mpdclient
*c
, command_t cmd
)
299 if (cmd
== CMD_LIST_RANGE_SELECT
)
302 if (list_window_cmd(lw
, cmd
)) {
310 if (lw
->selected
== LIST_ITEM_APPLY())
312 else if (lw
->selected
== LIST_ITEM_SAVE()) {
316 subcmd
= lw
->selected
;
317 list_window_reset(lw
);
318 check_subcmd_length();
323 if (lw
->selected
== 0) { /* up */
324 list_window_set_length(lw
, LIST_LENGTH());
325 list_window_set_cursor(lw
, subcmd
);
330 assign_new_key(subcmd
,
331 lw
->selected
- STATIC_SUB_ITEMS
);
334 case CMD_GO_PARENT_DIRECTORY
:
336 list_window_set_length(lw
, LIST_LENGTH());
337 list_window_set_cursor(lw
, subcmd
);
344 if (subcmd
>= 0 && lw
->selected
>= STATIC_SUB_ITEMS
)
345 delete_key(subcmd
, lw
->selected
- STATIC_SUB_ITEMS
);
348 case CMD_SAVE_PLAYLIST
:
354 case CMD_LIST_FIND_NEXT
:
355 case CMD_LIST_RFIND_NEXT
:
356 screen_find(lw
, cmd
, list_callback
, NULL
);
367 const struct screen_functions screen_keydef
= {
371 .close
= keydef_close
,
372 .resize
= keydef_resize
,
373 .paint
= keydef_paint
,
375 .get_title
= keydef_title
,