1 /*
2 | Copyright (C) 2003 Corey Donohoe <atmos at atmos dot org>
3 | Copyright (C) 2003-2007 Jorg Schuler <jcsjcs at users sourceforge net>
4 | Part of the gtkpod project.
5 |
6 | URL: http://www.gtkpod.org/
7 | URL: http://gtkpod.sourceforge.net/
8 |
9 | This program is free software; you can redistribute it and/or modify
10 | it under the terms of the GNU General Public License as published by
11 | the Free Software Foundation; either version 2 of the License, or
12 | (at your option) any later version.
13 |
14 | This program is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | GNU General Public License for more details.
18 |
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to the Free Software
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 |
23 | iTunes and iPod are trademarks of Apple
24 |
25 | This product is not supported/written/published by Apple!
26 |
27 | $Id$
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33
34 #include "itdb.h"
35 #include "info.h"
36 #include "details.h"
37 #include "display.h"
38 #include "display_itdb.h"
39 #include "file.h"
40 #include "misc.h"
41 #include "misc_track.h"
42 #include "prefs.h"
43 #include "tools.h"
44 #include "repository.h"
45 #include "syncdir.h"
46 #include "display_coverart.h"
47 #include "display_photo.h"
48
49 #define LOCALDEBUG 0
50
51 static guint entry_inst = -1;
52 static GList *selected_tracks = NULL;
53 static Playlist *selected_playlist = NULL;
54 static TabEntry *selected_entry = NULL;
55 static iTunesDB *active_itdb = NULL;
56 /* types of context menus (PM/ST/TM) */
57 typedef enum {
58 CM_PL = 0,
59 CM_ST,
60 CM_TM,
61 CM_NUM,
62 CM_CAD,
63 CM_PH_AV,
64 CM_PH_IV
65 } CM_type;
66
67
68
69 #if LOCALDEBUG
70 /**
71 * do_special - for debugging: change as needed to obtain information
72 * on selected tracks
73 * @mi - the menu item selected
74 * @data - ignored, should be NULL
75 */
76 static void
do_special(GtkWidget * w,gpointer data)77 do_special(GtkWidget *w, gpointer data)
78 {
79 GList *gl;
80
81 for (gl=selected_tracks; gl; gl=gl->next)
82 {
83 gchar *mp;
84 Track *tr = gl->data;
85 g_return_if_fail (tr);
86 g_object_get (tr->itdb->device, "mount-point", &mp, NULL);
87 printf ("mountpoint: %s\n", mp);
88 g_free (mp);
89
90 printf ("track: %p: thumbnails: %p id: %d num: %d\n",
91 tr, tr->artwork->thumbnails, tr->artwork->id, g_list_length (tr->artwork->thumbnails));
92 if (tr->artwork->thumbnails)
93 {
94 GList *gl2;
95 for (gl2=tr->artwork->thumbnails; gl2; gl2=gl2->next)
96 {
97 Thumb *img = gl2->data;
98 g_return_if_fail (img);
99 printf (" %s offset: %d size: %d width: %d height: %d\n", img->filename, img->offset, img->size, img->width, img->height);
100 }
101 }
102 }
103 }
104 #endif
105
106
107
108 /**
109 * export_entries - export the currently selected files to disk
110 * @mi - the menu item selected
111 * @data - ignored, should be NULL
112 */
113 static void
export_entries(GtkWidget * w,gpointer data)114 export_entries(GtkWidget *w, gpointer data)
115 {
116 if(selected_tracks)
117 export_files_init (selected_tracks, NULL, FALSE, NULL);
118 }
119
120 /**
121 * create_playlist_file - write a playlist file containing the
122 * currently selected tracks.
123 * @mi - the menu item selected
124 * @data - ignored, should be NULL
125 */
126 static void
create_playlist_file(GtkWidget * w,gpointer data)127 create_playlist_file(GtkWidget *w, gpointer data)
128 {
129 if(selected_tracks)
130 export_playlist_file_init(selected_tracks);
131 }
132
133
134 /*
135 * play_entries_now - play the entries currently selected in xmms
136 * @mi - the menu item selected
137 * @data - Ignored, should be NULL
138 */
139 static void
play_entries_now(GtkMenuItem * mi,gpointer data)140 play_entries_now (GtkMenuItem *mi, gpointer data)
141 {
142 tools_play_tracks (selected_tracks);
143 }
144
145 /*
146 * play_entries_now - play the entries currently selected in xmms
147 * @mi - the menu item selected
148 * @data - Ignored, should be NULL
149 */
150 static void
play_entries_enqueue(GtkMenuItem * mi,gpointer data)151 play_entries_enqueue (GtkMenuItem *mi, gpointer data)
152 {
153 tools_enqueue_tracks (selected_tracks);
154 }
155
156
157 /*
158 * show_details_entries - show details of tracks currently selected
159 * @mi - the menu item selected
160 * @data - Ignored, should be NULL
161 */
162 static void
edit_details_entries(GtkMenuItem * mi,gpointer data)163 edit_details_entries(GtkMenuItem *mi, gpointer data)
164 {
165 if (selected_playlist)
166 details_edit (selected_playlist->members);
167 else if(selected_entry)
168 details_edit (selected_entry->members);
169 else if(selected_tracks)
170 details_edit (selected_tracks);
171 }
172
173 /*
174 * display the dialog with the full size cd artwork cover
175 * @mi - the menu item selected
176 * @data - Ignored, should be NULL
177 */
178 static void
display_track_artwork(GtkMenuItem * mi,gpointer data)179 display_track_artwork(GtkMenuItem *mi, gpointer data)
180 {
181 if (selected_tracks)
182 coverart_display_big_artwork (selected_tracks);
183 }
184
185 /*
186 * update_entries - update the entries currently selected
187 * @mi - the menu item selected
188 * @data - Ignored, should be NULL
189 */
190 static void
update_entries(GtkMenuItem * mi,gpointer data)191 update_entries(GtkMenuItem *mi, gpointer data)
192 {
193 if (selected_playlist)
194 gp_do_selected_playlist (update_tracks);
195 else if(selected_entry)
196 gp_do_selected_entry (update_tracks, entry_inst);
197 else if(selected_tracks)
198 gp_do_selected_tracks (update_tracks);
199 }
200
201 /*
202 * sync_dirs_ entries - sync the directories of the selected playlist
203 *
204 * @mi - the menu item selected
205 * @data - Ignored, should be NULL
206 */
207 static void
sync_dirs(GtkMenuItem * mi,gpointer data)208 sync_dirs (GtkMenuItem *mi, gpointer data)
209 {
210 if (selected_playlist)
211 {
212 sync_playlist (selected_playlist, NULL,
213 KEY_SYNC_CONFIRM_DIRS, 0,
214 KEY_SYNC_DELETE_TRACKS, 0,
215 KEY_SYNC_CONFIRM_DELETE, 0,
216 KEY_SYNC_SHOW_SUMMARY, 0);
217 }
218 else
219 {
220 g_return_if_reached ();
221 }
222 }
223
224 /**
225 * delete_entries - delete the currently selected entry, be it a playlist,
226 * items in a sort tab, or tracks
227 * @mi - the menu item selected
228 * @data - ignored, should be NULL
229 */
230 static void
delete_entries(GtkMenuItem * mi,gpointer data)231 delete_entries(GtkMenuItem *mi, gpointer data)
232 {
233 DeleteAction deleteaction = GPOINTER_TO_INT (data);
234
235 if (selected_playlist)
236 delete_playlist_head (deleteaction);
237 else if(selected_entry)
238 delete_entry_head (entry_inst, deleteaction);
239 else if(selected_tracks)
240 delete_track_head (deleteaction);
241 }
242
243 /* Edit selected smart playlist */
edit_spl(GtkMenuItem * mi,gpointer data)244 static void edit_spl (GtkMenuItem *mi, gpointer data)
245 {
246 Playlist *pl = NULL;
247
248 if (selected_tracks) pl = pm_get_selected_playlist ();
249 if (selected_entry) pl = pm_get_selected_playlist ();
250 if (selected_playlist) pl = selected_playlist;
251
252 spl_edit (pl);
253 }
254
255 /* Display repository options */
edit_properties(GtkMenuItem * mi,gpointer data)256 static void edit_properties (GtkMenuItem *mi, gpointer data)
257 {
258 g_return_if_fail (selected_playlist);
259
260 repository_edit (selected_playlist->itdb, selected_playlist);
261 }
262
263
264 static void
create_playlist_from_entries(GtkMenuItem * mi,gpointer data)265 create_playlist_from_entries (GtkMenuItem *mi, gpointer data)
266 {
267 generate_new_playlist (active_itdb, selected_tracks);
268 }
269
270 /**
271 * alphabetize - alphabetize the currently selected entry
272 * sort tab). The sort order is being cycled through.
273 * @mi - the menu item selected
274 * @data - ignored, should be NULL
275 */
276 static void
alphabetize(GtkMenuItem * mi,gpointer data)277 alphabetize(GtkMenuItem *mi, gpointer data)
278 {
279 if (selected_entry)
280 {
281 switch (prefs_get_int("st_sort"))
282 {
283 case SORT_ASCENDING:
284 prefs_set_int("st_sort", SORT_DESCENDING);
285 break;
286 case SORT_DESCENDING:
287 prefs_set_int("st_sort", SORT_NONE);
288 break;
289 case SORT_NONE:
290 prefs_set_int("st_sort", SORT_ASCENDING);
291 break;
292 }
293 st_sort (prefs_get_int("st_sort"));
294 }
295 }
296
297
load_ipod(GtkMenuItem * mi,gpointer data)298 static void load_ipod (GtkMenuItem *mi, gpointer data)
299 {
300 g_return_if_fail (selected_playlist);
301
302 gp_load_ipod (selected_playlist->itdb);
303 }
304
305
eject_ipod(GtkMenuItem * mi,gpointer data)306 static void eject_ipod (GtkMenuItem *mi, gpointer data)
307 {
308 iTunesDB *itdb;
309 ExtraiTunesDBData *eitdb;
310
311 /* all of the checks below indicate a programming error -> give a
312 warning through the g_..._fail macros */
313 g_return_if_fail (selected_playlist);
314 itdb = selected_playlist->itdb;
315 g_return_if_fail (itdb);
316 g_return_if_fail (itdb->usertype & GP_ITDB_TYPE_IPOD);
317 eitdb = itdb->userdata;
318 g_return_if_fail (eitdb);
319 g_return_if_fail (eitdb->itdb_imported == TRUE);
320
321 gp_eject_ipod (itdb);
322 /* Set the coverart display based on the selected playlist */
323 coverart_display_update(TRUE);
324 }
325
326
save_changes(GtkMenuItem * mi,gpointer data)327 static void save_changes (GtkMenuItem *mi, gpointer data)
328 {
329 g_return_if_fail (selected_playlist);
330
331 gp_save_itdb (selected_playlist->itdb);
332 }
333
334
335
336
337 /* ------------------------------------------------------------
338
339 Copying selected item(s) to target destination
340
341 ------------------------------------------------------------ */
342
343
344 /*
345 * Copy the selected playlist to a specified itdb.
346 */
347 void
copy_playlist_to_target_itdb(Playlist * pl,iTunesDB * t_itdb)348 copy_playlist_to_target_itdb (Playlist *pl,
349 iTunesDB *t_itdb)
350 {
351 Playlist *pl_n;
352 GList *addtracks = NULL;
353 g_return_if_fail (pl);
354 g_return_if_fail (t_itdb);
355 if (pl->itdb != t_itdb)
356 {
357 addtracks = export_trackglist_when_necessary (pl->itdb,
358 t_itdb,
359 pl->members);
360 if (addtracks || !pl->members)
361 {
362 pl_n = gp_playlist_add_new(t_itdb, pl->name, FALSE, -1);
363 add_trackglist_to_playlist (pl_n, addtracks);
364 gtkpod_statusbar_message (_("Copied \"%s\" playlist to %s"),
365 pl->name, (itdb_playlist_mpl (t_itdb))->name);
366 }
367 g_list_free (addtracks);
368 addtracks = NULL;
369 }
370 else
371 {
372 pl_n = itdb_playlist_duplicate (pl);
373 g_return_if_fail (pl_n);
374 gp_playlist_add (t_itdb, pl_n, -1);
375 }
376 }
377
378
379 /*
380 * Copy selected tracks to a specified itdb.
381 */
382 void
copy_tracks_to_target_itdb(GList * tracks,iTunesDB * t_itdb)383 copy_tracks_to_target_itdb (GList *tracks,
384 iTunesDB *t_itdb)
385 {
386 GList *addtracks = NULL;
387 Track *first = tracks->data;
388 Playlist *mpl;
389 gint n;
390
391 g_return_if_fail(tracks);
392 g_return_if_fail(t_itdb);
393
394 mpl = itdb_playlist_mpl (t_itdb);
395 g_return_if_fail(mpl);
396
397 addtracks = export_trackglist_when_necessary (first->itdb, t_itdb, tracks);
398
399 if (addtracks)
400 {
401 add_trackglist_to_playlist (mpl, addtracks);
402 n = g_list_length (addtracks);
403 gtkpod_statusbar_message (ngettext ("Copied %d track to '%s'",
404 "Copied %d tracks to '%s'", n),
405 n, mpl->name);
406 g_list_free (addtracks);
407 addtracks = NULL;
408 }
409 }
410
411
412 void
copy_playlist_to_target_playlist(Playlist * pl,Playlist * t_pl)413 copy_playlist_to_target_playlist (Playlist *pl,
414 Playlist *t_pl)
415 {
416 GList *addtracks = NULL;
417 Playlist *t_mpl;
418
419 g_return_if_fail (pl);
420 g_return_if_fail (t_pl);
421
422 t_mpl = itdb_playlist_mpl (t_pl->itdb);
423 g_return_if_fail(t_mpl);
424
425 addtracks = export_trackglist_when_necessary (pl->itdb,
426 t_pl->itdb,
427 pl->members);
428 if (addtracks || !pl->members)
429 {
430 add_trackglist_to_playlist (t_pl, addtracks);
431 gtkpod_statusbar_message (_("Copied '%s' playlist to '%s' in '%s'"),
432 pl->name, t_pl->name, t_mpl->name);
433 g_list_free(addtracks);
434 addtracks = NULL;
435 }
436 }
437
438
439
440 void
copy_tracks_to_target_playlist(GList * tracks,Playlist * t_pl)441 copy_tracks_to_target_playlist (GList *tracks,
442 Playlist *t_pl)
443 {
444 GList *addtracks = NULL;
445 Track *first;
446 Playlist *mpl;
447 gint n;
448
449 g_return_if_fail (tracks);
450 g_return_if_fail (t_pl);
451 g_return_if_fail (t_pl->itdb);
452
453 mpl = itdb_playlist_mpl (t_pl->itdb);
454 g_return_if_fail(mpl);
455
456 if (tracks)
457 {
458 first = tracks->data;
459 g_return_if_fail (first);
460 addtracks = export_trackglist_when_necessary (first->itdb, t_pl->itdb, tracks);
461 add_trackglist_to_playlist (t_pl, addtracks);
462 }
463 n = g_list_length (addtracks);
464 gtkpod_statusbar_message (ngettext ("Copied %d track to '%s' in '%s'",
465 "Copied %d tracks to %s in '%s'", n),
466 n, t_pl->name, mpl->name);
467 g_list_free (addtracks);
468 addtracks = NULL;
469 }
470
471
472
copy_selected_to_target_itdb(GtkMenuItem * mi,gpointer * userdata)473 static void copy_selected_to_target_itdb (GtkMenuItem *mi, gpointer *userdata)
474 {
475 iTunesDB *t_itdb = *userdata;
476 g_return_if_fail (t_itdb);
477 if (selected_playlist)
478 copy_playlist_to_target_itdb (selected_playlist, t_itdb);
479 else if (selected_entry)
480 copy_tracks_to_target_itdb (selected_entry->members, t_itdb);
481 else if (selected_tracks)
482 copy_tracks_to_target_itdb (selected_tracks, t_itdb);
483 }
484
485
copy_selected_to_target_playlist(GtkMenuItem * mi,gpointer * userdata)486 static void copy_selected_to_target_playlist (GtkMenuItem *mi, gpointer *userdata)
487 {
488 Playlist *t_pl = *userdata;
489 g_return_if_fail (t_pl);
490 if (selected_playlist)
491 copy_playlist_to_target_playlist (selected_playlist, t_pl);
492 else if (selected_entry)
493 copy_tracks_to_target_playlist (selected_entry->members, t_pl);
494 else if (selected_tracks)
495 copy_tracks_to_target_playlist (selected_tracks, t_pl);
496 }
497
498
499 /* Attach a menu item to your context menu */
500 /* @m - the GtkMenu we're attaching to
501 * @str - a gchar* with the menu label
502 * @stock - name of the stock icon (or NULL if none is to be used)
503 * @func - the callback for when the item is selected (or NULL)
504 * @mi - the GtkWidget we're gonna hook into the menu
505 */
hookup_mi(GtkWidget * m,const gchar * str,const gchar * stock,GCallback func,gpointer userdata)506 GtkWidget *hookup_mi (GtkWidget *m,
507 const gchar *str,
508 const gchar *stock,
509 GCallback func,
510 gpointer userdata)
511 {
512 GtkWidget *mi;
513
514 if (stock)
515 {
516 GtkWidget *image;
517 mi = gtk_image_menu_item_new_with_mnemonic (str);
518 image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
519 gtk_widget_show (image);
520 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), image);
521 }
522 else
523 {
524 mi = gtk_menu_item_new_with_label(str);
525 }
526 gtk_widget_show(mi);
527 gtk_widget_set_sensitive(mi, TRUE);
528 gtk_widget_add_events(mi, GDK_BUTTON_RELEASE_MASK);
529 if (func)
530 g_signal_connect(G_OBJECT(mi), "activate", func, userdata);
531 gtk_container_add (GTK_CONTAINER (m), mi);
532 return mi;
533 }
534
535
536 /* Add separator to Menu @m and return pointer to separator widget */
add_separator(GtkWidget * m)537 GtkWidget *add_separator (GtkWidget *m)
538 {
539 GtkWidget *sep = NULL;
540 if (m)
541 {
542 sep = gtk_separator_menu_item_new ();
543 gtk_widget_show(sep);
544 gtk_widget_set_sensitive(sep, TRUE);
545 gtk_container_add (GTK_CONTAINER (m), sep);
546 }
547 return sep;
548 }
549
550
add_copy_selected_to_target_itdb(GtkWidget * menu,const gchar * title)551 static GtkWidget *add_copy_selected_to_target_itdb (GtkWidget *menu,
552 const gchar *title)
553 {
554 GtkWidget *mi;
555 GtkWidget *sub;
556 GtkWidget *pl_mi;
557 GtkWidget *pl_sub;
558 GList *itdbs;
559 GList *db;
560 struct itdbs_head *itdbs_head;
561 iTunesDB *itdb;
562 const gchar *stock_id = NULL;
563 Playlist *pl;
564
565
566 g_return_val_if_fail (gtkpod_window, NULL);
567 itdbs_head = g_object_get_data (G_OBJECT (gtkpod_window),
568 "itdbs_head");
569
570 mi = hookup_mi (menu, title,
571 GTK_STOCK_COPY,
572 NULL, NULL);
573 sub = gtk_menu_new ();
574 gtk_widget_show (sub);
575 gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), sub);
576
577 for (itdbs=itdbs_head->itdbs; itdbs; itdbs=itdbs->next)
578 {
579 itdb = itdbs->data;
580 ExtraiTunesDBData *eitdb=itdb->userdata;
581 if (itdb->usertype & GP_ITDB_TYPE_LOCAL)
582 {
583 stock_id = GTK_STOCK_HARDDISK;
584 }
585 else
586 {
587 if (eitdb->itdb_imported)
588 {
589 stock_id = GTK_STOCK_CONNECT;
590 }
591 else
592 {
593 stock_id = GTK_STOCK_DISCONNECT;
594 }
595 }
596 pl_mi = hookup_mi (sub, _(itdb_playlist_mpl(itdb)->name),
597 stock_id, NULL, NULL);
598 pl_sub = gtk_menu_new ();
599 gtk_widget_show (pl_sub);
600 gtk_menu_item_set_submenu (GTK_MENU_ITEM (pl_mi), pl_sub);
601 hookup_mi (pl_sub, _(itdb_playlist_mpl(itdb)->name),
602 stock_id, G_CALLBACK(copy_selected_to_target_itdb), &itdbs->data);
603 add_separator(pl_sub);
604 for (db=itdb->playlists; db; db=db->next)
605 {
606 pl=db->data;
607 if (!itdb_playlist_is_mpl (pl))
608 {
609 if (pl->is_spl)
610 stock_id = GTK_STOCK_PROPERTIES;
611 else
612 stock_id = GTK_STOCK_JUSTIFY_LEFT;
613 hookup_mi(pl_sub, _(pl->name), stock_id,
614 G_CALLBACK(copy_selected_to_target_playlist) , &db->data);
615 }
616 }
617 }
618 return mi;
619 }
620
621
add_play_now(GtkWidget * menu)622 static GtkWidget *add_play_now (GtkWidget *menu)
623 {
624 return hookup_mi (menu, _("Play Now"), GTK_STOCK_CDROM,
625 G_CALLBACK (play_entries_now), NULL);
626 }
627
add_enqueue(GtkWidget * menu)628 static GtkWidget *add_enqueue (GtkWidget *menu)
629 {
630 return hookup_mi (menu, _("Enqueue"), GTK_STOCK_CDROM,
631 G_CALLBACK (play_entries_enqueue), NULL);
632 }
633
add_copy_track_to_filesystem(GtkWidget * menu)634 static GtkWidget *add_copy_track_to_filesystem (GtkWidget *menu)
635 {
636 return hookup_mi (menu, _("Copy Tracks to Filesystem"),
637 GTK_STOCK_SAVE_AS,
638 G_CALLBACK (export_entries), NULL);
639 }
640
add_create_playlist_file(GtkWidget * menu)641 static GtkWidget *add_create_playlist_file (GtkWidget *menu)
642 {
643 return hookup_mi (menu, _("Create Playlist File"),
644 GTK_STOCK_SAVE_AS,
645 G_CALLBACK (create_playlist_file), NULL);
646 }
647
add_create_new_playlist(GtkWidget * menu)648 static GtkWidget *add_create_new_playlist (GtkWidget *menu)
649 {
650 return hookup_mi (menu, _("Create new Playlist"),
651 GTK_STOCK_JUSTIFY_LEFT,
652 G_CALLBACK (create_playlist_from_entries), NULL);
653 }
654
add_update_tracks_from_file(GtkWidget * menu)655 static GtkWidget *add_update_tracks_from_file (GtkWidget *menu)
656 {
657 return hookup_mi (menu, _("Update Tracks from File"),
658 GTK_STOCK_REFRESH,
659 G_CALLBACK (update_entries), NULL);
660 }
661
add_edit_smart_playlist(GtkWidget * menu)662 static GtkWidget *add_edit_smart_playlist (GtkWidget *menu)
663 {
664 return hookup_mi (menu, _("Edit Smart Playlist"),
665 GTK_STOCK_PROPERTIES,
666 G_CALLBACK (edit_spl), NULL);
667 }
668
add_sync_playlist_with_dirs(GtkWidget * menu)669 static GtkWidget *add_sync_playlist_with_dirs (GtkWidget *menu)
670 {
671 return hookup_mi (menu, _("Sync Playlist with Dir(s)"),
672 GTK_STOCK_REFRESH,
673 G_CALLBACK (sync_dirs), NULL);
674 }
675
add_remove_all_tracks_from_ipod(GtkWidget * menu)676 static GtkWidget *add_remove_all_tracks_from_ipod (GtkWidget *menu)
677 {
678 GtkWidget *mi;
679 GtkWidget *sub;
680
681 mi = hookup_mi (menu, _("Remove All Tracks from iPod"),
682 GTK_STOCK_DELETE,
683 NULL, NULL);
684 sub = gtk_menu_new ();
685 gtk_widget_show (sub);
686 gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), sub);
687 hookup_mi (sub, _("I'm sure"),
688 NULL,
689 G_CALLBACK (delete_entries),
690 GINT_TO_POINTER (DELETE_ACTION_IPOD));
691 return mi;
692 }
693
add_remove_all_podcasts_from_ipod(GtkWidget * menu)694 static GtkWidget *add_remove_all_podcasts_from_ipod (GtkWidget *menu)
695 {
696 GtkWidget *mi;
697 GtkWidget *sub;
698
699 mi = hookup_mi (menu, _("Remove All Podcasts from iPod"),
700 GTK_STOCK_DELETE,
701 NULL, NULL);
702 sub = gtk_menu_new ();
703 gtk_widget_show (sub);
704 gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), sub);
705 hookup_mi (sub, _("I'm sure"),
706 NULL,
707 G_CALLBACK (delete_entries),
708 GINT_TO_POINTER (DELETE_ACTION_IPOD));
709 return mi;
710 }
711
add_delete_including_tracks(GtkWidget * menu)712 static GtkWidget *add_delete_including_tracks (GtkWidget *menu)
713 {
714 return hookup_mi (menu, _("Delete Including Tracks"),
715 GTK_STOCK_DELETE,
716 G_CALLBACK (delete_entries),
717 GINT_TO_POINTER (DELETE_ACTION_IPOD));
718 }
719
add_delete_but_keep_tracks(GtkWidget * menu)720 static GtkWidget *add_delete_but_keep_tracks (GtkWidget *menu)
721 {
722 return hookup_mi (menu, _("Delete But Keep Tracks"),
723 GTK_STOCK_DELETE,
724 G_CALLBACK (delete_entries),
725 GINT_TO_POINTER (DELETE_ACTION_PLAYLIST));
726 }
727
add_edit_ipod_properties(GtkWidget * menu)728 static GtkWidget *add_edit_ipod_properties (GtkWidget *menu)
729 {
730 return hookup_mi (menu, _("Edit iPod Properties"),
731 GTK_STOCK_PREFERENCES,
732 G_CALLBACK (edit_properties), NULL);
733 }
734
add_edit_repository_properties(GtkWidget * menu)735 static GtkWidget *add_edit_repository_properties (GtkWidget *menu)
736 {
737 return hookup_mi (menu, _("Edit Repository Properties"),
738 GTK_STOCK_PREFERENCES,
739 G_CALLBACK (edit_properties), NULL);
740 }
741
add_edit_playlist_properties(GtkWidget * menu)742 static GtkWidget *add_edit_playlist_properties (GtkWidget *menu)
743 {
744 return hookup_mi (menu, _("Edit Playlist Properties"),
745 GTK_STOCK_PREFERENCES,
746 G_CALLBACK (edit_properties), NULL);
747 }
748
add_edit_track_details(GtkWidget * menu)749 static GtkWidget *add_edit_track_details (GtkWidget *menu)
750 {
751 return hookup_mi (menu, _("Edit Track Details"),
752 GTK_STOCK_EDIT,
753 G_CALLBACK (edit_details_entries), NULL);
754 }
755
add_display_big_coverart(GtkWidget * menu)756 static GtkWidget *add_display_big_coverart (GtkWidget *menu)
757 {
758 const gchar *icon;
759 /* gets defined in gtk+ V2.8, but we only require V2.6 */
760 #ifndef GTK_STOCK_FULLSCREEN
761 #define GTK_STOCK_FULLSCREEN "gtk-fullscreen"
762 #endif
763 if (gtk_check_version (2,8,0) == NULL)
764 {
765 icon = GTK_STOCK_FULLSCREEN;
766 }
767 else
768 {
769 icon = NULL;
770 }
771
772 return hookup_mi (menu, _("View Full Size Artwork"),
773 icon,
774 G_CALLBACK (display_track_artwork), NULL);
775 }
776
add_get_cover_from_file(GtkWidget * menu)777 static GtkWidget *add_get_cover_from_file (GtkWidget *menu)
778 {
779 return hookup_mi (menu, _("Select Cover From File"),
780 GTK_STOCK_FLOPPY,
781 G_CALLBACK (coverart_set_cover_from_file), NULL);
782 }
783
add_check_ipod_files(GtkWidget * menu)784 static GtkWidget *add_check_ipod_files (GtkWidget *menu)
785 {
786 /* FIXME */
787 return NULL;
788 }
789
add_load_ipod(GtkWidget * menu)790 static GtkWidget *add_load_ipod (GtkWidget *menu)
791 {
792 return hookup_mi (menu, _("Load iPod"),
793 GTK_STOCK_CONNECT,
794 G_CALLBACK (load_ipod), NULL);
795 }
796
add_eject_ipod(GtkWidget * menu)797 static GtkWidget *add_eject_ipod (GtkWidget *menu)
798 {
799 return hookup_mi (menu, _("Eject iPod"),
800 GTK_STOCK_DISCONNECT,
801 G_CALLBACK (eject_ipod), NULL);
802 }
803
add_save_changes(GtkWidget * menu)804 static GtkWidget *add_save_changes (GtkWidget *menu)
805 {
806 return hookup_mi (menu, _("Save Changes"),
807 GTK_STOCK_SAVE,
808 G_CALLBACK (save_changes), NULL);
809 }
810
add_remove_all_tracks_from_database(GtkWidget * menu)811 static GtkWidget *add_remove_all_tracks_from_database (GtkWidget *menu)
812 {
813 GtkWidget *mi;
814 GtkWidget *sub;
815
816 mi = hookup_mi (menu, _("Remove All Tracks from Database"),
817 GTK_STOCK_DELETE,
818 NULL, NULL);
819 sub = gtk_menu_new ();
820 gtk_widget_show (sub);
821 gtk_menu_item_set_submenu (GTK_MENU_ITEM (mi), sub);
822 hookup_mi (sub, _("I'm sure"),
823 NULL,
824 G_CALLBACK (delete_entries),
825 GINT_TO_POINTER (DELETE_ACTION_DATABASE));
826 return mi;
827 }
828
add_delete_including_tracks_harddisk(GtkWidget * menu)829 static GtkWidget *add_delete_including_tracks_harddisk (GtkWidget *menu)
830 {
831 return hookup_mi (menu, _("Delete Including Tracks (Harddisk)"),
832 GTK_STOCK_DELETE,
833 G_CALLBACK (delete_entries),
834 GINT_TO_POINTER (DELETE_ACTION_LOCAL));
835 }
836
add_delete_including_tracks_database(GtkWidget * menu)837 static GtkWidget *add_delete_including_tracks_database (GtkWidget *menu)
838 {
839 return hookup_mi (menu, _("Delete Including Tracks (Database)"),
840 GTK_STOCK_DELETE,
841 G_CALLBACK (delete_entries),
842 GINT_TO_POINTER (DELETE_ACTION_DATABASE));
843 }
844
add_delete_from_ipod(GtkWidget * menu)845 static GtkWidget *add_delete_from_ipod (GtkWidget *menu)
846 {
847 return hookup_mi (menu, _("Delete From iPod"),
848 GTK_STOCK_DELETE,
849 G_CALLBACK (delete_entries),
850 GINT_TO_POINTER (DELETE_ACTION_IPOD));
851 }
852
add_delete_from_playlist(GtkWidget * menu)853 static GtkWidget *add_delete_from_playlist (GtkWidget *menu)
854 {
855 return hookup_mi (menu, _("Delete From Playlist"),
856 GTK_STOCK_DELETE,
857 G_CALLBACK (delete_entries),
858 GINT_TO_POINTER (DELETE_ACTION_PLAYLIST));
859 }
860
add_delete_from_harddisk(GtkWidget * menu)861 static GtkWidget *add_delete_from_harddisk (GtkWidget *menu)
862 {
863 return hookup_mi (menu, _("Delete From Harddisk"),
864 GTK_STOCK_DELETE,
865 G_CALLBACK (delete_entries),
866 GINT_TO_POINTER (DELETE_ACTION_LOCAL));
867 }
868
add_delete_from_database(GtkWidget * menu)869 static GtkWidget *add_delete_from_database (GtkWidget *menu)
870 {
871 return hookup_mi (menu, _("Delete From Database"),
872 GTK_STOCK_DELETE,
873 G_CALLBACK (delete_entries),
874 GINT_TO_POINTER (DELETE_ACTION_DATABASE));
875 }
876
add_alphabetize(GtkWidget * menu)877 static GtkWidget *add_alphabetize (GtkWidget *menu)
878 {
879 return hookup_mi (menu, _("Alphabetize"),
880 GTK_STOCK_SORT_ASCENDING,
881 G_CALLBACK (alphabetize), NULL);
882 }
883
884 #if LOCALDEBUG
add_special(GtkWidget * menu)885 static GtkWidget *add_special (GtkWidget *menu)
886 {
887 return hookup_mi (menu, "Special",
888 GTK_STOCK_STOP,
889 G_CALLBACK (do_special), NULL);
890 }
891 #endif
892
gphoto_menuitem_remove_album_from_db_item(GtkWidget * menu)893 GtkWidget *gphoto_menuitem_remove_album_from_db_item(GtkWidget *menu)
894 {
895 return hookup_mi (
896 menu,
897 _("Remove Album"),
898 GTK_STOCK_DELETE,
899 G_CALLBACK (gphoto_remove_album_from_database),
900 NULL);
901 }
902
gphoto_menuitem_remove_photo_from_album_item(GtkWidget * menu)903 GtkWidget *gphoto_menuitem_remove_photo_from_album_item(GtkWidget *menu)
904 {
905 GtkWidget *mitem = hookup_mi (
906 menu,
907 _("Remove Photo"),
908 GTK_STOCK_DELETE,
909 G_CALLBACK (gphoto_remove_selected_photos_from_album),
910 NULL);
911
912 if (gphoto_get_selected_photo_count() == 0)
913 gtk_widget_set_sensitive (mitem, FALSE);
914 else
915 gtk_widget_set_sensitive (mitem, TRUE);
916
917 return mitem;
918 }
919
gphoto_menuitem_rename_photoalbum_item(GtkWidget * menu)920 GtkWidget *gphoto_menuitem_rename_photoalbum_item(GtkWidget *menu)
921 {
922 return hookup_mi (
923 menu,
924 _("Rename Album"),
925 GTK_STOCK_DELETE,
926 G_CALLBACK (gphoto_rename_selected_album),
927 NULL);
928 }
929
create_context_menu(CM_type type)930 void create_context_menu (CM_type type)
931 {
932 static GtkWidget *menu = NULL;
933 Playlist *pl;
934
935 if (menu)
936 { /* free memory for last menu */
937 gtk_widget_destroy (menu);
938 menu = NULL;
939 }
940
941 pl = pm_get_selected_playlist();
942 if (pl)
943 {
944 ExtraiTunesDBData *eitdb;
945 iTunesDB *itdb = pl->itdb;
946 g_return_if_fail (itdb);
947 eitdb = itdb->userdata;
948 g_return_if_fail (eitdb);
949
950 menu = gtk_menu_new ();
951
952 switch (type)
953 {
954 case CM_PL:
955 if (itdb->usertype & GP_ITDB_TYPE_IPOD)
956 {
957 if (eitdb->itdb_imported)
958 {
959 add_play_now (menu);
960 add_enqueue (menu);
961 add_copy_track_to_filesystem (menu);
962 add_create_playlist_file (menu);
963 add_update_tracks_from_file (menu);
964 if (!pl->is_spl)
965 {
966 add_sync_playlist_with_dirs (menu);
967 }
968 add_separator (menu);
969 if (itdb_playlist_is_mpl (pl))
970 {
971 add_remove_all_tracks_from_ipod (menu);
972 }
973 else if (itdb_playlist_is_podcasts (pl))
974 {
975 add_remove_all_podcasts_from_ipod (menu);
976 }
977 else
978 {
979 add_delete_including_tracks (menu);
980 add_delete_but_keep_tracks (menu);
981 }
982 add_copy_selected_to_target_itdb (menu,
983 _("Copy selected playlist to..."));
984 add_separator (menu);
985 add_edit_track_details (menu);
986 if (pl->is_spl)
987 {
988 add_edit_smart_playlist (menu);
989 }
990 if (itdb_playlist_is_mpl (pl))
991 {
992 add_edit_ipod_properties (menu);
993 }
994 else
995 {
996 add_edit_playlist_properties (menu);
997 }
998 add_check_ipod_files (menu);
999 add_eject_ipod (menu);
1000 }
1001 else
1002 { /* not imported */
1003 add_edit_ipod_properties (menu);
1004 add_check_ipod_files (menu);
1005 add_separator (menu);
1006 add_load_ipod (menu);
1007 }
1008 }
1009 if (itdb->usertype & GP_ITDB_TYPE_LOCAL)
1010 {
1011 add_play_now (menu);
1012 add_enqueue (menu);
1013 add_copy_track_to_filesystem (menu);
1014 add_create_playlist_file (menu);
1015 add_update_tracks_from_file (menu);
1016 if (!pl->is_spl)
1017 {
1018 add_sync_playlist_with_dirs (menu);
1019 }
1020 add_separator (menu);
1021 if (itdb_playlist_is_mpl (pl))
1022 {
1023 add_remove_all_tracks_from_database (menu);
1024 }
1025 else
1026 {
1027 add_delete_including_tracks_database (menu);
1028 add_delete_including_tracks_harddisk (menu);
1029 add_delete_but_keep_tracks (menu);
1030 }
1031 add_copy_selected_to_target_itdb (menu,
1032 _("Copy selected playlist to..."));
1033 add_separator (menu);
1034 add_edit_track_details (menu);
1035 if (pl->is_spl)
1036 {
1037 add_edit_smart_playlist (menu);
1038 }
1039 if (itdb_playlist_is_mpl (pl))
1040 {
1041 add_edit_repository_properties (menu);
1042 }
1043 else
1044 {
1045 add_edit_playlist_properties (menu);
1046 }
1047 add_save_changes (menu);
1048 }
1049 break;
1050 case CM_ST:
1051 case CM_TM:
1052 add_play_now (menu);
1053 add_enqueue (menu);
1054 add_copy_track_to_filesystem (menu);
1055 add_create_playlist_file (menu);
1056 add_create_new_playlist (menu);
1057 add_update_tracks_from_file (menu);
1058 if (!pl->is_spl)
1059 {
1060 add_sync_playlist_with_dirs (menu);
1061 }
1062 if (type == CM_ST)
1063 {
1064 add_alphabetize (menu);
1065 }
1066 add_separator (menu);
1067 if (itdb->usertype & GP_ITDB_TYPE_IPOD)
1068 {
1069 add_delete_from_ipod (menu);
1070 if (!itdb_playlist_is_mpl (pl))
1071 {
1072 add_delete_from_playlist (menu);
1073 }
1074 }
1075 if (itdb->usertype & GP_ITDB_TYPE_LOCAL)
1076 {
1077 add_delete_from_harddisk (menu);
1078 add_delete_from_database (menu);
1079 if (!itdb_playlist_is_mpl (pl))
1080 {
1081 add_delete_from_playlist (menu);
1082 }
1083 }
1084 add_copy_selected_to_target_itdb (menu,
1085 _("Copy selected track(s) to..."));
1086 add_separator (menu);
1087 add_edit_track_details (menu);
1088 #if LOCALDEBUG
1089 /* This is for debugging purposes -- this allows to inspect
1090 * any track with a custom function */
1091 if (type == CM_TM)
1092 {
1093 add_special (menu);
1094 }
1095 #endif
1096 break;
1097 case CM_CAD:
1098 add_get_cover_from_file (menu);
1099 add_display_big_coverart (menu);
1100 add_edit_track_details (menu);
1101 break;
1102 case CM_PH_AV:
1103 gphoto_menuitem_remove_album_from_db_item (menu);
1104 gphoto_menuitem_rename_photoalbum_item (menu);
1105 break;
1106 case CM_PH_IV:
1107 gphoto_menuitem_remove_photo_from_album_item (menu);
1108 break;
1109 case CM_NUM:
1110 g_return_if_reached ();
1111 }
1112 }
1113 /*
1114 * button should be button 0 as per the docs because we're calling
1115 * from a button release event
1116 */
1117 if (menu)
1118 {
1119 gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
1120 NULL, NULL, 0, gtk_get_current_event_time());
1121 }
1122 }
1123
1124
1125 /**
1126 * tm_context_menu_init - initialize the right click menu for tracks
1127 */
1128 void
tm_context_menu_init(void)1129 tm_context_menu_init(void)
1130 {
1131 if (widgets_blocked) return;
1132
1133 tm_stop_editing (TRUE);
1134
1135 selected_entry = NULL;
1136 selected_playlist = NULL;
1137 active_itdb = gp_get_selected_itdb ();
1138 entry_inst = -1;
1139 if (selected_tracks) g_list_free (selected_tracks);
1140 selected_tracks = tm_get_selected_tracks();
1141 if(selected_tracks)
1142 {
1143 create_context_menu (CM_TM);
1144 }
1145 }
1146
1147 /**
1148 * cad_context_menu_init - initialize the right click menu for coverart display
1149 */
1150 void
cad_context_menu_init(void)1151 cad_context_menu_init(void)
1152 {
1153 if (widgets_blocked) return;
1154
1155 selected_entry = NULL;
1156 selected_playlist = NULL;
1157 selected_tracks = NULL;
1158 active_itdb = gp_get_selected_itdb ();
1159 entry_inst = -1;
1160
1161 if (selected_tracks) g_list_free (selected_tracks);
1162 selected_tracks = g_list_copy (coverart_get_displayed_tracks());
1163
1164 if(selected_tracks)
1165 create_context_menu (CM_CAD);
1166 }
1167
1168 /**
1169 * photo_context_menu_init - initialize the right click menu for photo management display
1170 */
1171 void
gphoto_context_menu_init(gint component)1172 gphoto_context_menu_init (gint component)
1173 {
1174 if (widgets_blocked) return;
1175
1176 selected_entry = NULL;
1177 selected_playlist = NULL;
1178 selected_tracks = NULL;
1179 active_itdb = gp_get_selected_itdb ();
1180 entry_inst = -1;
1181
1182 if (selected_tracks) g_list_free (selected_tracks);
1183
1184 switch (component)
1185 {
1186 case GPHOTO_ALBUM_VIEW:
1187 create_context_menu (CM_PH_AV);
1188 break;
1189 case GPHOTO_ICON_VIEW:
1190 create_context_menu (CM_PH_IV);
1191 }
1192 }
1193
1194 /**
1195 * pm_context_menu_init - initialize the right click menu for playlists
1196 */
1197 void
pm_context_menu_init(void)1198 pm_context_menu_init(void)
1199 {
1200 if (widgets_blocked) return;
1201
1202 pm_stop_editing (TRUE);
1203
1204 if (selected_tracks) g_list_free (selected_tracks);
1205 selected_tracks = NULL;
1206 selected_entry = NULL;
1207 entry_inst = -1;
1208 selected_playlist = pm_get_selected_playlist();
1209
1210 active_itdb = gp_get_selected_itdb ();
1211
1212 if(selected_playlist)
1213 {
1214 selected_tracks = g_list_copy (selected_playlist->members);
1215 create_context_menu (CM_PL);
1216 }
1217 }
1218
1219 /**
1220 * st_context_menu_init - initialize the right click menu for sort tabs
1221 * FIXME: This needs to be hooked in.
1222 */
1223 void
st_context_menu_init(gint inst)1224 st_context_menu_init(gint inst)
1225 {
1226 if (widgets_blocked) return;
1227
1228 st_stop_editing (inst, TRUE);
1229
1230 if (selected_tracks) g_list_free (selected_tracks);
1231 selected_tracks = NULL;
1232 selected_playlist = NULL;
1233 selected_entry = st_get_selected_entry (inst);
1234 active_itdb = gp_get_selected_itdb ();
1235 if(selected_entry)
1236 {
1237 entry_inst = inst;
1238 selected_tracks = g_list_copy (selected_entry->members);
1239 create_context_menu (CM_ST);
1240 }
1241 }
1242