1 /*
2 gtkui hotkey handlers
3 Copyright (C) 2009-2013 Alexey Yakovenko and other contributors
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source distribution.
22 */
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <gtk/gtk.h>
30 #include <unistd.h>
31 #include "../../gettext.h"
32 #include "../../deadbeef.h"
33 #include "gtkui.h"
34 #include "progress.h"
35 #include "ddblistview.h"
36 #include "search.h"
37 #include "support.h"
38 #include "wingeom.h"
39 #include "interface.h"
40 #include "trkproperties.h"
41 #include "callbacks.h"
42 #include <sys/stat.h>
43
44 // disable custom title function, until we have new title formatting (0.7)
45 #define DISABLE_CUSTOM_TITLE
46
47 extern GtkWidget *mainwin;
48 extern DB_functions_t *deadbeef;
49
50 static gboolean
file_filter_func(const GtkFileFilterInfo * filter_info,gpointer data)51 file_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
52 // get ext
53 const char *p = strrchr (filter_info->filename, '.');
54 if (!p) {
55 return FALSE;
56 }
57 p++;
58
59 // get beginning of fname
60 const char *fn = strrchr (filter_info->filename, '/');
61 if (!fn) {
62 fn = filter_info->filename;
63 }
64 else {
65 fn++;
66 }
67
68
69 DB_decoder_t **codecs = deadbeef->plug_get_decoder_list ();
70 for (int i = 0; codecs[i]; i++) {
71 if (codecs[i]->exts && codecs[i]->insert) {
72 const char **exts = codecs[i]->exts;
73 for (int e = 0; exts[e]; e++) {
74 if (!strcasecmp (exts[e], p)) {
75 return TRUE;
76 }
77 }
78 }
79 if (codecs[i]->prefixes && codecs[i]->insert) {
80 const char **prefixes = codecs[i]->prefixes;
81 for (int e = 0; prefixes[e]; e++) {
82 if (!strncasecmp (prefixes[e], fn, strlen(prefixes[e])) && *(fn + strlen (prefixes[e])) == '.') {
83 return TRUE;
84 }
85 }
86 }
87 }
88 #if 0
89 if (!strcasecmp (p, "pls")) {
90 return TRUE;
91 }
92 if (!strcasecmp (p, "m3u")) {
93 return TRUE;
94 }
95 #endif
96
97 // test container (vfs) formats
98 DB_vfs_t **vfsplugs = deadbeef->plug_get_vfs_list ();
99 for (int i = 0; vfsplugs[i]; i++) {
100 if (vfsplugs[i]->is_container) {
101 if (vfsplugs[i]->is_container (filter_info->filename)) {
102 return TRUE;
103 }
104 }
105 }
106
107 return FALSE;
108 }
109
110 static GtkFileFilter *
set_file_filter(GtkWidget * dlg,const char * name)111 set_file_filter (GtkWidget *dlg, const char *name) {
112 if (!name) {
113 name = _("Supported sound formats");
114 }
115
116 GtkFileFilter* flt;
117 flt = gtk_file_filter_new ();
118 gtk_file_filter_set_name (flt, name);
119
120 gtk_file_filter_add_custom (flt, GTK_FILE_FILTER_FILENAME, file_filter_func, NULL, NULL);
121 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
122 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dlg), flt);
123 flt = gtk_file_filter_new ();
124 gtk_file_filter_set_name (flt, _("All files (*)"));
125 gtk_file_filter_add_pattern (flt, "*");
126 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
127 return flt;
128 }
129
130 gboolean
action_open_files_handler_cb(void * userdata)131 action_open_files_handler_cb (void *userdata) {
132 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Open file(s)..."), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
133
134 set_file_filter (dlg, NULL);
135
136 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
137 // restore folder
138 deadbeef->conf_lock ();
139 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
140 deadbeef->conf_unlock ();
141 int response = gtk_dialog_run (GTK_DIALOG (dlg));
142 // store folder
143 gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
144 if (folder) {
145 deadbeef->conf_set_str ("filechooser.lastdir", folder);
146 g_free (folder);
147 }
148 if (response == GTK_RESPONSE_OK)
149 {
150 deadbeef->pl_clear ();
151 GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
152 gtk_widget_destroy (dlg);
153 if (lst) {
154 gtkui_open_files (lst);
155 }
156 }
157 else {
158 gtk_widget_destroy (dlg);
159 }
160 return FALSE;
161 }
162
163 int
action_open_files_handler(struct DB_plugin_action_s * action,int ctx)164 action_open_files_handler (struct DB_plugin_action_s *action, int ctx) {
165 gdk_threads_add_idle (action_open_files_handler_cb, NULL);
166 return 0;
167 }
168
169 gboolean
action_add_files_handler_cb(void * user_data)170 action_add_files_handler_cb (void *user_data) {
171 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Add file(s) to playlist..."), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
172
173 set_file_filter (dlg, NULL);
174
175 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
176
177 // restore folder
178 deadbeef->conf_lock ();
179 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
180 deadbeef->conf_unlock ();
181 int response = gtk_dialog_run (GTK_DIALOG (dlg));
182 // store folder
183 gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
184 if (folder) {
185 deadbeef->conf_set_str ("filechooser.lastdir", folder);
186 g_free (folder);
187 }
188 if (response == GTK_RESPONSE_OK)
189 {
190 GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
191 gtk_widget_destroy (dlg);
192 if (lst) {
193 gtkui_add_files (lst);
194 }
195 }
196 else {
197 gtk_widget_destroy (dlg);
198 }
199 return FALSE;
200 }
201
202 int
action_add_files_handler(struct DB_plugin_action_s * action,int ctx)203 action_add_files_handler (struct DB_plugin_action_s *action, int ctx) {
204 gdk_threads_add_idle (action_add_files_handler_cb, NULL);
205 return 0;
206 }
207
208 static void
on_follow_symlinks_toggled(GtkToggleButton * togglebutton,gpointer user_data)209 on_follow_symlinks_toggled (GtkToggleButton *togglebutton,
210 gpointer user_data)
211 {
212 deadbeef->conf_set_int ("add_folders_follow_symlinks", gtk_toggle_button_get_active (togglebutton));
213 }
214
215 gboolean
action_add_folders_handler_cb(void * user_data)216 action_add_folders_handler_cb (void *user_data) {
217 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Add folder(s) to playlist..."), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
218
219 GtkWidget *box = gtk_hbox_new (FALSE, 8);
220 gtk_widget_show (box);
221
222 GtkWidget *check = gtk_check_button_new_with_mnemonic (_("Follow symlinks"));
223 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), deadbeef->conf_get_int ("add_folders_follow_symlinks", 0));
224 g_signal_connect ((gpointer) check, "toggled",
225 G_CALLBACK (on_follow_symlinks_toggled),
226 NULL);
227 gtk_widget_show (check);
228 gtk_box_pack_start (GTK_BOX (box), check, FALSE, FALSE, 0);
229
230 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dlg), box);
231
232 // gtk devs broke this in 3.6 - thanks guys
233 // set_file_filter (dlg, NULL);
234
235 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE);
236 // restore folder
237 deadbeef->conf_lock ();
238 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.lastdir", ""));
239 deadbeef->conf_unlock ();
240 int response = gtk_dialog_run (GTK_DIALOG (dlg));
241 // store folder
242 gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
243 if (folder) {
244 deadbeef->conf_set_str ("filechooser.lastdir", folder);
245 g_free (folder);
246 }
247 if (response == GTK_RESPONSE_OK)
248 {
249 //gchar *folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
250 GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg));
251 gtk_widget_destroy (dlg);
252 if (lst) {
253 gtkui_add_dirs (lst);
254 }
255 }
256 else {
257 gtk_widget_destroy (dlg);
258 }
259 return FALSE;
260 }
261
262 int
action_add_folders_handler(struct DB_plugin_action_s * action,int ctx)263 action_add_folders_handler (struct DB_plugin_action_s *action, int ctx) {
264 gdk_threads_add_idle (action_add_folders_handler_cb, NULL);
265 return 0;
266 }
267
268 gboolean
action_quit_handler_cb(void * user_data)269 action_quit_handler_cb (void *user_data) {
270 gtkui_quit ();
271 return FALSE;
272 }
273
274 int
action_quit_handler(DB_plugin_action_t * act,int ctx)275 action_quit_handler (DB_plugin_action_t *act, int ctx) {
276 g_idle_add (action_quit_handler_cb, NULL);
277 return 0;
278 }
279
280 gboolean
action_deselect_all_handler_cb(void * user_data)281 action_deselect_all_handler_cb (void *user_data) {
282 deadbeef->pl_lock ();
283 DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN);
284 while (it) {
285 if (deadbeef->pl_is_selected (it)) {
286 deadbeef->pl_set_selected (it, 0);
287 }
288 DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
289 deadbeef->pl_item_unref (it);
290 it = next;
291 }
292 deadbeef->pl_unlock ();
293 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_SELECTION, 0);
294 DdbListview *pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
295 if (pl) {
296 ddb_listview_refresh (pl, DDB_REFRESH_LIST);
297 }
298 return FALSE;
299 }
300
301 int
action_deselect_all_handler(struct DB_plugin_action_s * action,int ctx)302 action_deselect_all_handler (struct DB_plugin_action_s *action, int ctx) {
303 g_idle_add (action_deselect_all_handler_cb, NULL);
304 return 0;
305 }
306
307 gboolean
action_select_all_handler_cb(void * user_data)308 action_select_all_handler_cb (void *user_data) {
309 deadbeef->pl_select_all ();
310 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_SELECTION, 0);
311 DdbListview *pl = DDB_LISTVIEW (lookup_widget (searchwin, "searchlist"));
312 if (pl) {
313 ddb_listview_refresh (pl, DDB_REFRESH_LIST);
314 }
315 return FALSE;
316 }
317
318 int
action_select_all_handler(struct DB_plugin_action_s * action,int ctx)319 action_select_all_handler (struct DB_plugin_action_s *action, int ctx) {
320 g_idle_add (action_select_all_handler_cb, NULL);
321 return 0;
322 }
323
324 gboolean
action_new_playlist_handler_cb(void * user_data)325 action_new_playlist_handler_cb (void *user_data) {
326 int pl = gtkui_add_new_playlist ();
327 if (pl != -1) {
328 deadbeef->plt_set_curr_idx (pl);
329 deadbeef->conf_set_int ("playlist.current", pl);
330 }
331 return FALSE;
332 }
333
334 int
action_new_playlist_handler(struct DB_plugin_action_s * action,int ctx)335 action_new_playlist_handler (struct DB_plugin_action_s *action, int ctx) {
336 gdk_threads_add_idle (action_new_playlist_handler_cb, NULL);
337 return 0;
338 }
339
340 int
action_remove_current_playlist_handler(struct DB_plugin_action_s * action,int ctx)341 action_remove_current_playlist_handler (struct DB_plugin_action_s *action, int ctx) {
342 int idx = deadbeef->plt_get_curr_idx ();
343 if (idx != -1) {
344 deadbeef->plt_remove (idx);
345 }
346 return 0;
347 }
348
349 gboolean
action_toggle_mainwin_handler_cb(void * user_data)350 action_toggle_mainwin_handler_cb (void *user_data) {
351 mainwin_toggle_visible ();
352 return FALSE;
353 }
354
355 int
action_toggle_mainwin_handler(struct DB_plugin_action_s * action,int ctx)356 action_toggle_mainwin_handler (struct DB_plugin_action_s *action, int ctx) {
357 g_idle_add (action_toggle_mainwin_handler_cb, NULL);
358 return 0;
359 }
360
361 gboolean
action_show_mainwin_handler_cb(void * user_data)362 action_show_mainwin_handler_cb (void *user_data) {
363 int iconified = gdk_window_get_state(gtk_widget_get_window(mainwin)) & GDK_WINDOW_STATE_ICONIFIED;
364 if (!(gtk_widget_get_visible (mainwin) && !iconified)) {
365 wingeom_restore (mainwin, "mainwin", 40, 40, 500, 300, 0);
366 if (iconified) {
367 gtk_window_deiconify (GTK_WINDOW(mainwin));
368 }
369 else {
370 gtk_window_present (GTK_WINDOW (mainwin));
371 }
372 }
373 return FALSE;
374 }
375
376 int
action_show_mainwin_handler(struct DB_plugin_action_s * action,int ctx)377 action_show_mainwin_handler (struct DB_plugin_action_s *action, int ctx) {
378 g_idle_add (action_show_mainwin_handler_cb, NULL);
379 return 0;
380 }
381
382 gboolean
action_hide_mainwin_handler_cb(void * user_data)383 action_hide_mainwin_handler_cb (void *user_data) {
384 int iconified = gdk_window_get_state(gtk_widget_get_window(mainwin)) & GDK_WINDOW_STATE_ICONIFIED;
385 if (gtk_widget_get_visible (mainwin) && !iconified) {
386 gtk_widget_hide (mainwin);
387 }
388 return FALSE;
389 }
390
391 int
action_hide_mainwin_handler(struct DB_plugin_action_s * action,int ctx)392 action_hide_mainwin_handler (struct DB_plugin_action_s *action, int ctx) {
393 g_idle_add (action_hide_mainwin_handler_cb, NULL);
394 return 0;
395 }
396
397 static void
on_toggle_set_custom_title(GtkToggleButton * togglebutton,gpointer user_data)398 on_toggle_set_custom_title (GtkToggleButton *togglebutton, gpointer user_data) {
399 gboolean active = gtk_toggle_button_get_active (togglebutton);
400 deadbeef->conf_set_int ("gtkui.location_set_custom_title", active);
401
402 GtkWidget *ct = lookup_widget (GTK_WIDGET (user_data), "custom_title");
403 gtk_widget_set_sensitive (ct, active);
404
405 deadbeef->conf_save ();
406 }
407
408 gboolean
action_add_location_handler_cb(void * user_data)409 action_add_location_handler_cb (void *user_data) {
410 GtkWidget *dlg = create_addlocationdlg ();
411
412 GtkWidget *sct = lookup_widget (dlg, "set_custom_title");
413 GtkWidget *ct = lookup_widget (dlg, "custom_title");
414
415 #ifndef DISABLE_CUSTOM_TITLE
416 if (deadbeef->conf_get_int ("gtkui.location_set_custom_title", 0)) {
417 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sct), TRUE);
418 gtk_widget_set_sensitive (ct, TRUE);
419 }
420 else
421 #endif
422 {
423 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sct), FALSE);
424 gtk_widget_set_sensitive (ct, FALSE);
425 }
426
427 #ifndef DISABLE_CUSTOM_TITLE
428 g_signal_connect ((gpointer) sct, "toggled",
429 G_CALLBACK (on_toggle_set_custom_title),
430 dlg);
431 #endif
432
433 gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
434 int res = gtk_dialog_run (GTK_DIALOG (dlg));
435 if (res == GTK_RESPONSE_OK) {
436 GtkEntry *entry = GTK_ENTRY (lookup_widget (dlg, "addlocation_entry"));
437 if (entry) {
438 const char *text = gtk_entry_get_text (entry);
439 if (text) {
440 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
441 if (!deadbeef->plt_add_files_begin (plt, 0)) {
442 DB_playItem_t *tail = deadbeef->plt_get_last (plt, PL_MAIN);
443 DB_playItem_t *it = deadbeef->plt_insert_file2 (0, plt, tail, text, NULL, NULL, NULL);
444 #ifndef DISABLE_CUSTOM_TITLE
445 if (it && deadbeef->conf_get_int ("gtkui.location_set_custom_title", 0)) {
446 deadbeef->pl_replace_meta (it, ":CUSTOM_TITLE", gtk_entry_get_text (GTK_ENTRY (ct)));
447 }
448 #endif
449 if (tail) {
450 deadbeef->pl_item_unref (tail);
451 }
452 deadbeef->plt_add_files_end (plt, 0);
453 playlist_refresh ();
454 }
455 if (plt) {
456 deadbeef->plt_unref (plt);
457 }
458 }
459 }
460 }
461 gtk_widget_destroy (dlg);
462 return FALSE;
463 }
464
465 int
action_add_location_handler(DB_plugin_action_t * act,int ctx)466 action_add_location_handler (DB_plugin_action_t *act, int ctx) {
467 gdk_threads_add_idle (action_add_location_handler_cb, NULL);
468 return 0;
469 }
470
471 static GtkWidget *helpwindow;
472
473 gboolean
action_show_help_handler_cb(void * user_data)474 action_show_help_handler_cb (void *user_data) {
475 char fname[PATH_MAX];
476 snprintf (fname, sizeof (fname), "%s/%s", deadbeef->get_doc_dir (), _("help.txt"));
477 gtkui_show_info_window (fname, _("Help"), &helpwindow);
478 return FALSE;
479 }
480
481 int
action_show_help_handler(DB_plugin_action_t * act,int ctx)482 action_show_help_handler (DB_plugin_action_t *act, int ctx) {
483 gdk_threads_add_idle (action_show_help_handler_cb, NULL);
484 return 0;
485 }
486
487 int
action_remove_from_playlist_handler(DB_plugin_action_t * act,int ctx)488 action_remove_from_playlist_handler (DB_plugin_action_t *act, int ctx) {
489 if (ctx == DDB_ACTION_CTX_SELECTION) {
490 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
491 if (plt) {
492 int cursor = deadbeef->plt_delete_selected (plt);
493 if (cursor != -1) {
494 DB_playItem_t *it = deadbeef->plt_get_item_for_idx (plt, cursor, PL_MAIN);
495 if (it) {
496 deadbeef->pl_set_selected (it, 1);
497 deadbeef->pl_item_unref (it);
498 }
499 }
500 deadbeef->plt_save_config (plt);
501 deadbeef->plt_unref (plt);
502 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
503 }
504 }
505 else if (ctx == DDB_ACTION_CTX_PLAYLIST) {
506 ddb_playlist_t *plt_curr = deadbeef->plt_get_curr ();
507 ddb_playlist_t *plt = deadbeef->action_get_playlist ();
508 deadbeef->plt_clear (plt);
509 deadbeef->plt_save_config (plt);
510 if (plt == plt_curr) {
511 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
512 }
513 deadbeef->plt_unref (plt);
514 deadbeef->plt_unref (plt_curr);
515 }
516 else if (ctx == DDB_ACTION_CTX_NOWPLAYING) {
517 int success = 0;
518 deadbeef->pl_lock ();
519 DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
520 if (it) {
521 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
522 if (plt) {
523 int idx = deadbeef->plt_get_item_idx (plt, it, PL_MAIN);
524 if (idx != -1) {
525 deadbeef->plt_remove_item (plt, it);
526 deadbeef->pl_save_current ();
527 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
528 }
529 deadbeef->plt_unref (plt);
530 }
531 deadbeef->pl_item_unref (it);
532 }
533 deadbeef->pl_unlock ();
534 }
535 return 0;
536 }
537
538 void
delete_and_remove_track(const char * uri,ddb_playlist_t * plt,ddb_playItem_t * it)539 delete_and_remove_track (const char *uri, ddb_playlist_t *plt, ddb_playItem_t *it) {
540 int res = unlink (uri);
541
542 // check if file exists
543 struct stat buf;
544 memset (&buf, 0, sizeof (buf));
545 int stat_res = stat (uri, &buf);
546 if (stat_res != 0) {
547 deadbeef->plt_remove_item (plt, it);
548 }
549 }
550
551 gboolean
action_delete_from_disk_handler_cb(void * data)552 action_delete_from_disk_handler_cb (void *data) {
553 int ctx = (intptr_t)data;
554 if (deadbeef->conf_get_int ("gtkui.delete_files_ask", 1)) {
555 GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("Delete files from disk"));
556 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("Files will be lost. Proceed?\n(This dialog can be turned off in GTKUI plugin settings)"));
557 gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
558
559 int response = gtk_dialog_run (GTK_DIALOG (dlg));
560 gtk_widget_destroy (dlg);
561 if (response != GTK_RESPONSE_YES) {
562 return FALSE;
563 }
564 }
565
566 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
567 if (!plt) {
568 return FALSE;
569 }
570 deadbeef->pl_lock ();
571
572 if (ctx == DDB_ACTION_CTX_SELECTION) {
573 DB_playItem_t *it = deadbeef->plt_get_first (plt, PL_MAIN);
574 while (it) {
575 const char *uri = deadbeef->pl_find_meta (it, ":URI");
576 if (deadbeef->pl_is_selected (it) && deadbeef->is_local_file (uri)) {
577 delete_and_remove_track (uri, plt, it);
578 }
579 DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
580 deadbeef->pl_item_unref (it);
581 it = next;
582 }
583
584 deadbeef->pl_save_current ();
585 }
586 else if (ctx == DDB_ACTION_CTX_PLAYLIST) {
587 DB_playItem_t *it = deadbeef->plt_get_first (plt, PL_MAIN);
588 while (it) {
589 const char *uri = deadbeef->pl_find_meta (it, ":URI");
590 if (deadbeef->is_local_file (uri)) {
591 delete_and_remove_track (uri, plt, it);
592 // FIXME: this dialog should allow something like "cancel" and "ignore all", then
593 // it will be usable
594 // else {
595 // GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Can't delete the file. Perhaps it doesn't exist, read-only, or part of read-only VFS, or all of the above."));
596 // gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), uri);
597 // gtk_window_set_title (GTK_WINDOW (dlg), _("Warning"));
598 //
599 // int response = gtk_dialog_run (GTK_DIALOG (dlg));
600 // gtk_widget_destroy (dlg);
601 // }
602 }
603 DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN);
604 deadbeef->pl_item_unref (it);
605 it = next;
606 }
607
608 deadbeef->pl_save_current ();
609 }
610 else if (ctx == DDB_ACTION_CTX_NOWPLAYING) {
611 DB_playItem_t *it = deadbeef->streamer_get_playing_track ();
612 if (it) {
613 const char *uri = deadbeef->pl_find_meta (it, ":URI");
614 if (deadbeef->is_local_file (uri)) {
615 int idx = deadbeef->plt_get_item_idx (plt, it, PL_MAIN);
616 if (idx != -1) {
617 delete_and_remove_track (uri, plt, it);
618 }
619 }
620 deadbeef->pl_item_unref (it);
621 }
622 }
623 deadbeef->pl_unlock ();
624 deadbeef->plt_unref (plt);
625
626 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
627 return FALSE;
628 }
629
630 int
action_delete_from_disk_handler(DB_plugin_action_t * act,int ctx)631 action_delete_from_disk_handler (DB_plugin_action_t *act, int ctx) {
632 gdk_threads_add_idle (action_delete_from_disk_handler_cb, (void *)(intptr_t)ctx);
633 return 0;
634 }
635
636 typedef struct {
637 int ctx;
638 ddb_playlist_t *plt;
639 } trkproperties_action_ctx_t;
640
641 gboolean
action_show_track_properties_handler_cb(void * data)642 action_show_track_properties_handler_cb (void *data) {
643 trkproperties_action_ctx_t *ctx = data;
644 show_track_properties_dlg (ctx->ctx, ctx->plt);
645 deadbeef->plt_unref (ctx->plt);
646 free (data);
647 return FALSE;
648 }
649
650 int
action_show_track_properties_handler(DB_plugin_action_t * act,int ctx)651 action_show_track_properties_handler (DB_plugin_action_t *act, int ctx) {
652 trkproperties_action_ctx_t *data = calloc (1, sizeof (trkproperties_action_ctx_t));
653 data->ctx = ctx;
654 data->plt = deadbeef->action_get_playlist ();
655 gdk_threads_add_idle (action_show_track_properties_handler_cb, data);
656 return 0;
657 }
658
659 gboolean
action_find_handler_cb(void * data)660 action_find_handler_cb (void *data) {
661 search_start ();
662 return FALSE;
663 }
664
665 int
action_find_handler(DB_plugin_action_t * act,int ctx)666 action_find_handler (DB_plugin_action_t *act, int ctx) {
667 gdk_threads_add_idle (action_find_handler_cb, NULL);
668 return 0;
669 }
670
671 gboolean
action_scroll_follows_playback_handler_cb(void * data)672 action_scroll_follows_playback_handler_cb (void *data) {
673 int val = 1 - deadbeef->conf_get_int ("playlist.scroll.followplayback", 1);
674 deadbeef->conf_set_int ("playlist.scroll.followplayback", val);
675 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "scroll_follows_playback")), val);
676 return FALSE;
677 }
678
679 int
action_scroll_follows_playback_handler(DB_plugin_action_t * act,int ctx)680 action_scroll_follows_playback_handler (DB_plugin_action_t *act, int ctx) {
681 g_idle_add (action_scroll_follows_playback_handler_cb, NULL);
682 return 0;
683 }
684
685 gboolean
action_cursor_follows_playback_handler_cb(void * data)686 action_cursor_follows_playback_handler_cb (void *data) {
687 int val = 1 - deadbeef->conf_get_int ("playlist.scroll.cursorfollowplayback", 1);
688 deadbeef->conf_set_int ("playlist.scroll.cursorfollowplayback", val);
689 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "cursor_follows_playback")), val);
690 return FALSE;
691 }
692
693 int
action_cursor_follows_playback_handler(DB_plugin_action_t * act,int ctx)694 action_cursor_follows_playback_handler (DB_plugin_action_t *act, int ctx) {
695 g_idle_add (action_cursor_follows_playback_handler_cb, NULL);
696 return 0;
697 }
698
699 static gboolean
playlist_filter_func(const GtkFileFilterInfo * filter_info,gpointer data)700 playlist_filter_func (const GtkFileFilterInfo *filter_info, gpointer data) {
701 // get ext
702 const char *p = strrchr (filter_info->filename, '.');
703 if (!p) {
704 return FALSE;
705 }
706 p++;
707 DB_playlist_t **plug = deadbeef->plug_get_playlist_list ();
708 for (int i = 0; plug[i]; i++) {
709 if (plug[i]->extensions && plug[i]->load) {
710 const char **exts = plug[i]->extensions;
711 if (exts) {
712 for (int e = 0; exts[e]; e++) {
713 if (!strcasecmp (exts[e], p)) {
714 return TRUE;
715 }
716 }
717 }
718 }
719 }
720 return FALSE;
721 }
722
723 static void
load_playlist_thread(void * data)724 load_playlist_thread (void *data) {
725 char *fname = data;
726 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
727 if (plt) {
728 if (!deadbeef->plt_add_files_begin (plt, 0)) {
729 deadbeef->plt_clear (plt);
730 int abort = 0;
731 DB_playItem_t *it = deadbeef->plt_load2 (0, plt, NULL, fname, &abort, NULL, NULL);
732 deadbeef->plt_save_config (plt);
733 deadbeef->plt_add_files_end (plt, 0);
734 }
735 deadbeef->plt_unref (plt);
736 }
737 g_free (fname);
738 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
739 }
740
741
742 gboolean
action_load_playlist_handler_cb(void * data)743 action_load_playlist_handler_cb (void *data) {
744 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Load Playlist"), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
745
746 // restore folder
747 deadbeef->conf_lock ();
748 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.playlist.lastdir", ""));
749 deadbeef->conf_unlock ();
750
751 GtkFileFilter* flt;
752 flt = gtk_file_filter_new ();
753 gtk_file_filter_set_name (flt, "Supported playlist formats");
754 gtk_file_filter_add_custom (flt, GTK_FILE_FILTER_FILENAME, playlist_filter_func, NULL, NULL);
755 gtk_file_filter_add_pattern (flt, "*.dbpl");
756 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
757 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dlg), flt);
758 flt = gtk_file_filter_new ();
759 gtk_file_filter_set_name (flt, _("Other files (*)"));
760 gtk_file_filter_add_pattern (flt, "*");
761 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
762
763 int res = gtk_dialog_run (GTK_DIALOG (dlg));
764 // store folder
765 gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
766 if (folder) {
767 deadbeef->conf_set_str ("filechooser.playlist.lastdir", folder);
768 g_free (folder);
769 }
770 if (res == GTK_RESPONSE_OK)
771 {
772 gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
773 gtk_widget_destroy (dlg);
774 if (fname) {
775 uintptr_t tid = deadbeef->thread_start (load_playlist_thread, fname);
776 deadbeef->thread_detach (tid);
777 }
778 }
779 else {
780 gtk_widget_destroy (dlg);
781 }
782 return FALSE;
783 }
784
785 int
action_load_playlist_handler(DB_plugin_action_t * act,int ctx)786 action_load_playlist_handler (DB_plugin_action_t *act, int ctx) {
787 gdk_threads_add_idle (action_load_playlist_handler_cb, NULL);
788 return 0;
789 }
790
791 gboolean
action_save_playlist_handler_cb(void * data)792 action_save_playlist_handler_cb (void *data) {
793 GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Save Playlist As"), GTK_WINDOW (mainwin), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL);
794
795 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dlg), TRUE);
796 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlg), "untitled.dbpl");
797 // restore folder
798 deadbeef->conf_lock ();
799 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), deadbeef->conf_get_str_fast ("filechooser.playlist.lastdir", ""));
800 deadbeef->conf_unlock ();
801
802 GtkFileFilter* flt;
803 flt = gtk_file_filter_new ();
804 gtk_file_filter_set_name (flt, _("DeaDBeeF playlist files (*.dbpl)"));
805 gtk_file_filter_add_pattern (flt, "*.dbpl");
806 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
807 DB_playlist_t **plug = deadbeef->plug_get_playlist_list ();
808 for (int i = 0; plug[i]; i++) {
809 if (plug[i]->extensions && plug[i]->load) {
810 const char **exts = plug[i]->extensions;
811 if (exts && plug[i]->save) {
812 for (int e = 0; exts[e]; e++) {
813 char s[100];
814 flt = gtk_file_filter_new ();
815 gtk_file_filter_set_name (flt, exts[e]);
816 snprintf (s, sizeof (s), "*.%s", exts[e]);
817 gtk_file_filter_add_pattern (flt, s);
818 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt);
819 }
820 }
821 }
822 }
823
824 int res = gtk_dialog_run (GTK_DIALOG (dlg));
825 // store folder
826 gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg));
827 if (folder) {
828 deadbeef->conf_set_str ("filechooser.playlist.lastdir", folder);
829 g_free (folder);
830 }
831 if (res == GTK_RESPONSE_OK)
832 {
833 gchar *fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
834 gtk_widget_destroy (dlg);
835
836 if (fname) {
837 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
838 if (plt) {
839 int res = deadbeef->plt_save (plt, NULL, NULL, fname, NULL, NULL, NULL);
840 if (res >= 0 && strlen (fname) < 1024) {
841 deadbeef->conf_set_str ("gtkui.last_playlist_save_name", fname);
842 }
843 deadbeef->plt_unref (plt);
844 }
845 g_free (fname);
846 }
847 }
848 else {
849 gtk_widget_destroy (dlg);
850 }
851 return FALSE;
852 }
853
854 int
action_save_playlist_handler(DB_plugin_action_t * act,int ctx)855 action_save_playlist_handler (DB_plugin_action_t *act, int ctx) {
856 gdk_threads_add_idle (action_save_playlist_handler_cb, NULL);
857 return 0;
858 }
859
860 gboolean
action_toggle_menu_handler_cb(void * data)861 action_toggle_menu_handler_cb (void *data) {
862 GtkWidget *menu = lookup_widget (mainwin, "menubar");
863 int val = 1-deadbeef->conf_get_int ("gtkui.show_menu", 1);
864 val ? gtk_widget_show (menu) : gtk_widget_hide (menu);
865 deadbeef->conf_set_int ("gtkui.show_menu", val);
866 return FALSE;
867 }
868
869 int
action_toggle_menu_handler(DB_plugin_action_t * act,int ctx)870 action_toggle_menu_handler (DB_plugin_action_t *act, int ctx) {
871 g_idle_add (action_toggle_menu_handler_cb, NULL);
872 return 0;
873 }
874
875 gboolean
action_toggle_statusbar_handler_cb(void * data)876 action_toggle_statusbar_handler_cb (void *data) {
877 GtkWidget *sb = lookup_widget (mainwin, "statusbar");
878 if (sb) {
879 int val = 1 - deadbeef->conf_get_int ("gtkui.statusbar.visible", 1);
880 deadbeef->conf_set_int ("gtkui.statusbar.visible", val);
881 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "view_status_bar")), val);
882 val ? gtk_widget_show (sb) : gtk_widget_hide (sb);
883 deadbeef->conf_save ();
884 }
885 return FALSE;
886 }
887
888 int
action_toggle_statusbar_handler(DB_plugin_action_t * act,int ctx)889 action_toggle_statusbar_handler (DB_plugin_action_t *act, int ctx) {
890 g_idle_add (action_toggle_statusbar_handler_cb, NULL);
891 return 0;
892 }
893
894 gboolean
action_toggle_designmode_handler_cb(void * data)895 action_toggle_designmode_handler_cb (void *data) {
896 GtkWidget *menuitem = lookup_widget (mainwin, "design_mode1");
897 gboolean act = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem));
898 act = !act;
899 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), act);
900 return FALSE;
901 }
902
903 int
action_toggle_designmode_handler(DB_plugin_action_t * act,int ctx)904 action_toggle_designmode_handler (DB_plugin_action_t *act, int ctx) {
905 g_idle_add (action_toggle_designmode_handler_cb, NULL);
906 return 0;
907 }
908
909 gboolean
action_preferences_handler_cb(void * data)910 action_preferences_handler_cb (void *data) {
911 gtkui_run_preferences_dlg ();
912 return FALSE;
913 }
914
915 int
action_preferences_handler(DB_plugin_action_t * act,int ctx)916 action_preferences_handler (DB_plugin_action_t *act, int ctx) {
917 gdk_threads_add_idle (action_preferences_handler_cb, NULL);
918 return 0;
919 }
920
921 gboolean
action_sort_custom_handler_cb(void * data)922 action_sort_custom_handler_cb (void *data) {
923 GtkWidget *dlg = create_sortbydlg ();
924 gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
925
926 GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (dlg, "sortorder"));
927 GtkEntry *entry = GTK_ENTRY (lookup_widget (dlg, "sortfmt"));
928
929 gtk_combo_box_set_active (combo, deadbeef->conf_get_int ("gtkui.sortby_order", 0));
930 deadbeef->conf_lock ();
931 gtk_entry_set_text (entry, deadbeef->conf_get_str_fast ("gtkui.sortby_fmt_v2", ""));
932 deadbeef->conf_unlock ();
933
934 int r = gtk_dialog_run (GTK_DIALOG (dlg));
935
936 if (r == GTK_RESPONSE_OK) {
937 GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (dlg, "sortorder"));
938 GtkEntry *entry = GTK_ENTRY (lookup_widget (dlg, "sortfmt"));
939 int order = gtk_combo_box_get_active (combo);
940 const char *fmt = gtk_entry_get_text (entry);
941
942 deadbeef->conf_set_int ("gtkui.sortby_order", order);
943 deadbeef->conf_set_str ("gtkui.sortby_fmt_v2", fmt);
944
945 ddb_playlist_t *plt = deadbeef->plt_get_curr ();
946 deadbeef->plt_sort_v2 (plt, PL_MAIN, -1, fmt, order == 0 ? DDB_SORT_ASCENDING : DDB_SORT_DESCENDING);
947 deadbeef->plt_save_config (plt);
948 deadbeef->plt_unref (plt);
949
950 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
951 }
952
953 gtk_widget_destroy (dlg);
954 dlg = NULL;
955 return FALSE;
956 }
957
958 int
action_sort_custom_handler(DB_plugin_action_t * act,int ctx)959 action_sort_custom_handler (DB_plugin_action_t *act, int ctx) {
960 gdk_threads_add_idle (action_sort_custom_handler_cb, NULL);
961 return 0;
962 }
963
964 int
action_crop_selected_handler(DB_plugin_action_t * act,int ctx)965 action_crop_selected_handler (DB_plugin_action_t *act, int ctx) {
966 deadbeef->pl_crop_selected ();
967 deadbeef->pl_save_current ();
968 deadbeef->sendmessage (DB_EV_PLAYLISTCHANGED, 0, DDB_PLAYLIST_CHANGE_CONTENT, 0);
969 return 0;
970 }
971
972 gboolean
action_toggle_eq_handler_cb(void * data)973 action_toggle_eq_handler_cb (void *data) {
974 GtkWidget *menuitem = lookup_widget (mainwin, "view_eq");
975 gboolean act = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem));
976 act = !act;
977 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), act);
978 return FALSE;
979 }
980
981 int
action_toggle_eq_handler(DB_plugin_action_t * act,int ctx)982 action_toggle_eq_handler (DB_plugin_action_t *act, int ctx) {
983 g_idle_add (action_toggle_eq_handler_cb, NULL);
984 return 0;
985 }
986
987 gboolean
action_show_eq_handler_cb(void * data)988 action_show_eq_handler_cb (void *data) {
989 GtkWidget *menuitem = lookup_widget (mainwin, "view_eq");
990 gboolean act = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem));
991 if (!act) {
992 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), 1);
993 }
994 return FALSE;
995 }
996
997 int
action_show_eq_handler(DB_plugin_action_t * act,int ctx)998 action_show_eq_handler(DB_plugin_action_t *act, int ctx) {
999 g_idle_add (action_show_eq_handler_cb, NULL);
1000 return 0;
1001 }
1002
1003 gboolean
action_hide_eq_handler_cb(void * data)1004 action_hide_eq_handler_cb (void *data) {
1005 GtkWidget *menuitem = lookup_widget (mainwin, "view_eq");
1006 gboolean act = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem));
1007 if (act) {
1008 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), 0);
1009 }
1010 return FALSE;
1011 }
1012
1013 int
action_hide_eq_handler(DB_plugin_action_t * act,int ctx)1014 action_hide_eq_handler(DB_plugin_action_t *act, int ctx) {
1015 g_idle_add (action_hide_eq_handler_cb, NULL);
1016 return 0;
1017 }
1018
1019 gboolean
action_playback_loop_off_handler_cb(void * data)1020 action_playback_loop_off_handler_cb (void *data) {
1021 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_disable")), 1);
1022 return FALSE;
1023 }
1024
1025 int
action_playback_loop_off_handler(DB_plugin_action_t * act,int ctx)1026 action_playback_loop_off_handler(DB_plugin_action_t *act, int ctx) {
1027 g_idle_add (action_playback_loop_off_handler_cb, NULL);
1028 return 0;
1029 }
1030
1031 gboolean
action_playback_loop_single_handler_cb(void * data)1032 action_playback_loop_single_handler_cb (void *data) {
1033 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_single")), 1);
1034 return FALSE;
1035 }
1036
1037 int
action_playback_loop_single_handler(DB_plugin_action_t * act,int ctx)1038 action_playback_loop_single_handler(DB_plugin_action_t *act, int ctx) {
1039 g_idle_add (action_playback_loop_single_handler_cb, NULL);
1040 return 0;
1041 }
1042
1043 gboolean
action_playback_loop_all_handler_cb(void * data)1044 action_playback_loop_all_handler_cb (void *data) {
1045 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_all")), 1);
1046 return FALSE;
1047 }
1048
1049 int
action_playback_loop_all_handler(DB_plugin_action_t * act,int ctx)1050 action_playback_loop_all_handler(DB_plugin_action_t *act, int ctx) {
1051 g_idle_add (action_playback_loop_all_handler_cb, NULL);
1052 return 0;
1053 }
1054
1055 gboolean
action_playback_order_random_handler_cb(void * data)1056 action_playback_order_random_handler_cb (void *data) {
1057 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_random")), 1);
1058 return FALSE;
1059 }
1060
1061 int
action_playback_order_random_handler(DB_plugin_action_t * act,int ctx)1062 action_playback_order_random_handler(DB_plugin_action_t *act, int ctx) {
1063 g_idle_add (action_playback_order_random_handler_cb, NULL);
1064 return 0;
1065 }
1066
1067 gboolean
action_playback_order_shuffle_albums_handler_cb(void * data)1068 action_playback_order_shuffle_albums_handler_cb (void *data) {
1069 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_shuffle_albums")), 1);
1070 return FALSE;
1071 }
1072
1073 int
action_playback_order_shuffle_albums_handler(DB_plugin_action_t * act,int ctx)1074 action_playback_order_shuffle_albums_handler(DB_plugin_action_t *act, int ctx) {
1075 g_idle_add (action_playback_order_shuffle_albums_handler_cb, NULL);
1076 return 0;
1077 }
1078
1079 gboolean
action_playback_order_shuffle_handler_cb(void * data)1080 action_playback_order_shuffle_handler_cb (void *data) {
1081 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_shuffle")), 1);
1082 return FALSE;
1083 }
1084
1085 int
action_playback_order_shuffle_handler(DB_plugin_action_t * act,int ctx)1086 action_playback_order_shuffle_handler(DB_plugin_action_t *act, int ctx) {
1087 g_idle_add (action_playback_order_shuffle_handler_cb, NULL);
1088 return 0;
1089 }
1090
1091 gboolean
action_playback_order_linear_handler_cb(void * data)1092 action_playback_order_linear_handler_cb (void *data) {
1093 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_linear")), 1);
1094 return FALSE;
1095 }
1096
1097 int
action_playback_order_linear_handler(DB_plugin_action_t * act,int ctx)1098 action_playback_order_linear_handler(DB_plugin_action_t *act, int ctx) {
1099 g_idle_add (action_playback_order_linear_handler_cb, NULL);
1100 return 0;
1101 }
1102
1103 gboolean
action_playback_order_cycle_handler_cb(void * data)1104 action_playback_order_cycle_handler_cb (void *data) {
1105 int ord = deadbeef->conf_get_int ("playback.order", PLAYBACK_ORDER_LINEAR);
1106 switch (ord) {
1107 case PLAYBACK_ORDER_LINEAR:
1108 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_shuffle")), 1);
1109 break;
1110 case PLAYBACK_ORDER_SHUFFLE_TRACKS:
1111 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_shuffle_albums")), 1);
1112 break;
1113 case PLAYBACK_ORDER_SHUFFLE_ALBUMS:
1114 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_random")), 1);
1115 break;
1116 case PLAYBACK_ORDER_RANDOM:
1117 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "order_linear")), 1);
1118 break;
1119 }
1120 return FALSE;
1121 }
1122
1123 int
action_playback_order_cycle_handler(DB_plugin_action_t * act,int ctx)1124 action_playback_order_cycle_handler(DB_plugin_action_t *act, int ctx) {
1125 g_idle_add (action_playback_order_cycle_handler_cb, NULL);
1126 return 0;
1127 }
1128
1129 gboolean
action_playback_loop_cycle_handler_cb(void * data)1130 action_playback_loop_cycle_handler_cb (void *data) {
1131 int ord = deadbeef->conf_get_int ("playback.loop", PLAYBACK_MODE_LOOP_ALL);
1132 switch (ord) {
1133 case PLAYBACK_MODE_LOOP_ALL:
1134 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_single")), 1);
1135 break;
1136 case PLAYBACK_MODE_LOOP_SINGLE:
1137 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_disable")), 1);
1138 break;
1139 case PLAYBACK_MODE_NOLOOP:
1140 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "loop_all")), 1);
1141 break;
1142 }
1143 return FALSE;
1144 }
1145
1146 int
action_playback_loop_cycle_handler(DB_plugin_action_t * act,int ctx)1147 action_playback_loop_cycle_handler(DB_plugin_action_t *act, int ctx) {
1148 g_idle_add (action_playback_loop_cycle_handler_cb, NULL);
1149 return 0;
1150 }
1151