~elementary-apps/noise/trunk

« back to all changes in this revision

Viewing changes to src/LibraryWindow.vala

  • Committer: Scott Ringwelski
  • Date: 2011-02-10 21:30:53 UTC
  • Revision ID: sgringwe@mtu.edu-20110210213053-d3c7mnexeref3cwj
sexy icons, sexy waf

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
using Gtk;
 
2
using Gee;
 
3
using WebKit;
 
4
//using Notify;
 
5
 
 
6
public class BeatBox.LibraryWindow : Gtk.Window {
 
7
        BeatBox.LibraryManager lm;
 
8
        BeatBox.Settings settings;
 
9
        BeatBox.StreamPlayer player;
 
10
        
 
11
        string current_view_path;
 
12
        bool queriedlastfm; // whether or not we have queried last fm for the current song info
 
13
        bool song_considered_played; //whether or not we have updated last played and added to already played list
 
14
        bool added_to_play_count; // whether or not we have added one to play count on playing song
 
15
        bool loaded_pandora;
 
16
        bool loaded_groove_shark;
 
17
        string timeout_search;
 
18
        
 
19
        VBox verticalBox;
 
20
        VBox mainViews;
 
21
        HPaned sourcesToSongs; //allows for draggable
 
22
        ScrolledWindow sideTreeScroll;
 
23
        VBox sideBar;
 
24
        VBox contentBox;
 
25
        SideTreeView sideTree;
 
26
        ScrolledWindow songInfoScroll;
 
27
        ScrolledWindow pandoraScroll;
 
28
        ScrolledWindow grooveSharkScroll;
 
29
        WebView songInfo;
 
30
        WebView pandora;
 
31
        WebView grooveShark;
 
32
        Image coverArt;
 
33
        Toolbar topControls;
 
34
        ToolButton previousButton;
 
35
        ToolButton playButton;
 
36
        ToolButton nextButton;
 
37
        Button shuffleButton;
 
38
        Button loveButton;
 
39
        Button banButton;
 
40
        ElementaryWidgets.TopDisplay topDisplay;
 
41
        ElementaryWidgets.ElementarySearchEntry searchField;
 
42
        ElementaryWidgets.AppMenu appMenu;
 
43
        Statusbar statusBar;
 
44
        
 
45
        MenuBar topMenu;
 
46
        
 
47
        // basic file stuff
 
48
        MenuItem fileRescanMusicFolder;
 
49
        MenuItem helpOnline;
 
50
        MenuItem helpTranslate;
 
51
        MenuItem helpReport;
 
52
        MenuItem helpAbout;
 
53
        MenuItem editPreferences;
 
54
        
 
55
        Menu settingsMenu;
 
56
        
 
57
        //Notify.Notification notification;
 
58
        
 
59
        public LibraryWindow(BeatBox.DataBaseManager dbm, BeatBox.StreamPlayer player) {
 
60
                settings = new BeatBox.Settings();
 
61
                this.player = player;
 
62
                
 
63
                //this is used by many objects, is the media backend
 
64
                lm = new BeatBox.LibraryManager(player, dbm, settings);
 
65
                
 
66
                build_ui();
 
67
                
 
68
                this.player.end_of_stream.connect(end_of_stream);
 
69
                this.player.current_position_update.connect(current_position_update);
 
70
                this.lm.music_added.connect(musicAdded);
 
71
                this.lm.music_rescanned.connect(musicRescanned);
 
72
                this.lm.progress_notification.connect(progressNotification);
 
73
                this.lm.song_removed.connect(songRemovedFromManager);
 
74
                this.lm.song_played.connect(song_played);
 
75
                destroy.connect (on_quit);
 
76
                check_resize.connect(on_resize);
 
77
                this.destroy.connect (Gtk.main_quit);
 
78
        }
 
79
        
 
80
        public void build_ui() {
 
81
                // simple message to terminal
 
82
                stdout.printf("Building user interface\n");
 
83
                
 
84
                // set the size based on saved gconf settings
 
85
                set_size_request(settings.getWindowWidth(), settings.getWindowHeight());
 
86
                allow_shrink = true;
 
87
                
 
88
                // set the title
 
89
                set_title("BeatBox");
 
90
                
 
91
                /* Initialize all components */
 
92
                verticalBox = new VBox(false, 0);
 
93
                sourcesToSongs = new HPaned();
 
94
                contentBox = new VBox(false, 0);
 
95
                mainViews = new VBox(false, 0);
 
96
                sideTree = new SideTreeView(lm, this);  
 
97
                sideTreeScroll = new ScrolledWindow(null, null);        
 
98
                topMenu = new MenuBar();
 
99
                fileRescanMusicFolder = new MenuItem.with_label("Rescan Music Folder");
 
100
                helpOnline = new MenuItem.with_label("Get Help Online...");
 
101
                helpTranslate = new MenuItem.with_label("Translate This Application...");
 
102
                helpReport = new MenuItem.with_label("Report a Problem...");
 
103
                helpAbout = new MenuItem.with_label("About");
 
104
                editPreferences = new MenuItem.with_label("Preferences");
 
105
                settingsMenu = new Menu();
 
106
                topControls = new Toolbar();
 
107
                previousButton = new ToolButton.from_stock(Gtk.Stock.MEDIA_PREVIOUS);
 
108
                playButton = new ToolButton.from_stock(Gtk.Stock.MEDIA_PLAY);
 
109
                nextButton = new ToolButton.from_stock(Gtk.Stock.MEDIA_NEXT);
 
110
                shuffleButton = new Button.with_label("Shuffle");
 
111
                loveButton = new Button.with_label("Love");
 
112
                banButton = new Button.with_label("Ban");
 
113
                topDisplay = new ElementaryWidgets.TopDisplay(lm);
 
114
                searchField = new ElementaryWidgets.ElementarySearchEntry("Search...");
 
115
                appMenu = new ElementaryWidgets.AppMenu.from_stock(Gtk.Stock.PROPERTIES, Gtk.IconSize.MENU, "Menu", settingsMenu);
 
116
                songInfoScroll = new ScrolledWindow(null, null);
 
117
                pandoraScroll = new ScrolledWindow(null, null);
 
118
                grooveSharkScroll = new ScrolledWindow(null, null);
 
119
                songInfo = new WebView();
 
120
                pandora = new WebView();
 
121
                grooveShark = new WebView();
 
122
                sideBar = new VBox(false, 0);
 
123
                coverArt = new Image.from_file(Environment.get_home_dir () + "/.beatbox/default_cover.jpg");
 
124
                statusBar = new Statusbar();
 
125
                //notification = new Notification("Title", "Artist\nAlbum", "", null);
 
126
                
 
127
                /* Set properties of various controls */
 
128
                sourcesToSongs.child1_resize = 1;
 
129
                sideBar.set_size_request(settings.getSidebarWidth(), -1);
 
130
                buildSideTree();
 
131
                
 
132
                shuffleButton.relief = Gtk.ReliefStyle.NONE;
 
133
                //shuffleButton.image = new Gtk.Image.from_stock(Gtk.Stock.MEDIA_SHUFFLE, Gtk.IconSize.SMALL_TOOLBAR);
 
134
                loveButton.relief = Gtk.ReliefStyle.NONE;
 
135
                banButton.relief = Gtk.ReliefStyle.NONE;
 
136
                
 
137
                if(lm.song_count() != 0)
 
138
                        searchField.set_sensitive(true);
 
139
                else
 
140
                        searchField.set_sensitive(false);
 
141
                
 
142
                settingsMenu.append(fileRescanMusicFolder);
 
143
                settingsMenu.append(new SeparatorMenuItem());
 
144
                settingsMenu.append(helpOnline);
 
145
                settingsMenu.append(helpTranslate);
 
146
                settingsMenu.append(helpReport);
 
147
                settingsMenu.append(new SeparatorMenuItem());
 
148
                settingsMenu.append(helpAbout);
 
149
                settingsMenu.append(editPreferences);
 
150
                
 
151
                fileRescanMusicFolder.activate.connect(fileRescanMusicFolderClick);
 
152
                helpOnline.activate.connect( () => {
 
153
                        string auth_uri = "https://answers.launchpad.net/beat-box";
 
154
                        GLib.AppInfo.launch_default_for_uri (auth_uri, null);
 
155
                });
 
156
                helpTranslate.activate.connect( () => {
 
157
                        string auth_uri = "https://translations.launchpad.net/beat-box";
 
158
                        GLib.AppInfo.launch_default_for_uri (auth_uri, null);
 
159
                });
 
160
                helpReport.activate.connect( () => {
 
161
                        string auth_uri = "https://bugs.launchpad.net/beat-box";
 
162
                        GLib.AppInfo.launch_default_for_uri (auth_uri, null);
 
163
                });
 
164
                helpAbout.activate.connect(helpAboutClick);
 
165
                editPreferences.activate.connect(editPreferencesClick);
 
166
                
 
167
                songInfo.open("file://"+Environment.get_home_dir () + "/.beatbox/song_info.html");
 
168
                
 
169
                statusBar.has_resize_grip = true;
 
170
                
 
171
                /* Add controls to the GUI */
 
172
                add(verticalBox);
 
173
                verticalBox.pack_start(topMenu, false, true, 0);
 
174
                verticalBox.pack_start(topControls, false, true, 0);
 
175
        verticalBox.pack_start(sourcesToSongs, true, true, 0);
 
176
        //verticalBox.pack_start(statusBar, false, true, 0);
 
177
        
 
178
        ToolItem topDisplayBin = new ToolItem();
 
179
        ToolItem searchFieldBin = new ToolItem();
 
180
        ToolItem appMenuBin = new ToolItem();
 
181
        topDisplayBin.add(topDisplay);
 
182
        searchFieldBin.add(searchField);
 
183
        appMenuBin.add(appMenu);
 
184
        
 
185
        topDisplayBin.set_expand(true);
 
186
        
 
187
        topControls.insert(previousButton, 0);
 
188
        topControls.insert(playButton, 1);
 
189
        topControls.insert(nextButton, 2);
 
190
        topControls.insert(topDisplayBin, 3);
 
191
        topControls.insert(searchFieldBin, 4);
 
192
        topControls.insert(appMenuBin, 5);
 
193
                
 
194
                //set the name for elementary theming
 
195
                sourcesToSongs.name = "SidebarHandleLeft";
 
196
                sideTree.name = "SidebarContent";
 
197
                
 
198
                contentBox.pack_start(mainViews, true, true, 0);
 
199
                contentBox.pack_start(statusBar, false, true, 0);
 
200
                
 
201
                sourcesToSongs.add1(sideBar);
 
202
                sourcesToSongs.add2(contentBox);
 
203
                
 
204
                songInfoScroll.add(songInfo);
 
205
                pandoraScroll.add(pandora);
 
206
                grooveSharkScroll.add(grooveShark);
 
207
                
 
208
                songInfo.window_features.scrollbar_visible = false;
 
209
                
 
210
                sideBar.pack_start(sideTreeScroll, true, true, 0);
 
211
                sideBar.pack_end(coverArt, false, true, 0);
 
212
                
 
213
                statusBar.pack_start(shuffleButton);
 
214
                
 
215
                /* Connect events to functions */
 
216
                sourcesToSongs.child1.size_allocate.connect(sourcesToSongsHandleSet);
 
217
                sideTree.row_activated.connect(sideListDoubleClick);
 
218
                previousButton.clicked.connect(previousClicked);
 
219
                playButton.clicked.connect(playClicked);
 
220
                nextButton.clicked.connect(nextClicked);
 
221
                shuffleButton.clicked.connect(shuffleClicked);
 
222
                loveButton.clicked.connect(loveButtonClicked);
 
223
                banButton.clicked.connect(banButtonClicked);
 
224
                topDisplay.scale_value_changed.connect(topDisplaySliderMoved);
 
225
                searchField.changed.connect(searchFieldChanged);
 
226
                
 
227
                show_all();
 
228
                topMenu.hide();
 
229
                topDisplay.show_scale();
 
230
                coverArt.hide();
 
231
                sideTree.resetView();
 
232
        }
 
233
        
 
234
        /** Builds the side tree on TreeView view
 
235
         * @param view The side tree to build it on
 
236
         */
 
237
        private void buildSideTree() {
 
238
                MusicTreeView mtv;
 
239
                
 
240
                // put song info first so it is on top when using multiple views
 
241
                sideTree.addItem(null, new GLib.Object(), songInfoScroll, "Song Info");
 
242
                mainViews.pack_start(songInfoScroll, true, true, 0);
 
243
                
 
244
                mtv = new MusicTreeView(lm, this, -1);
 
245
                mtv.set_hint("queue");
 
246
                mtv.populateView(lm.queue(), false);
 
247
                mtv.view_being_searched.connect(musicTreeViewSearched);
 
248
                sideTree.addItem(null, null, mtv, "Queue");
 
249
                mainViews.pack_start(mtv, true, true, 0);
 
250
                
 
251
                mtv = new MusicTreeView(lm, this, -1);
 
252
                mtv.set_hint("already played");
 
253
                mtv.populateView(lm.already_played(), false);
 
254
                mtv.view_being_searched.connect(musicTreeViewSearched);
 
255
                sideTree.addItem(null, null, mtv, "Already Played");
 
256
                mainViews.pack_start(mtv, true, true, 0);
 
257
                
 
258
                mtv = new MusicTreeView(lm, this, -1);
 
259
                mtv.set_hint("library");
 
260
                mtv.populateView(lm.song_ids(), false);
 
261
                mtv.view_being_searched.connect(musicTreeViewSearched);
 
262
                sideTree.addItem(null, null, mtv, "Library");
 
263
                mainViews.pack_start(mtv, true, true, 0);
 
264
                
 
265
                //why should i have internet sources on a music player???
 
266
                //I should just concentrate on playing local music files
 
267
                /*pandora
 
268
                sideTree.addItem(sideTree.get_internet_iter(), new GLib.Object(), pandoraScroll, "Pandora");
 
269
                mainViews.pack_start(pandoraScroll, true, true, 0);
 
270
                
 
271
                //groooveshark
 
272
                sideTree.addItem(sideTree.get_internet_iter(), new GLib.Object(), grooveSharkScroll, "Groove Shark");
 
273
                mainViews.pack_start(grooveSharkScroll, true, true, 0);*/
 
274
                
 
275
                // load smart playlists
 
276
                foreach(SmartPlaylist p in lm.smart_playlists()) {
 
277
                        addSideListItem(p);
 
278
                }
 
279
                
 
280
                // load playlists
 
281
                foreach(Playlist p in lm.playlists()) {
 
282
                        addSideListItem(p);
 
283
                }
 
284
                
 
285
                
 
286
                sideTree.get_selection().select_iter(sideTree.get_library_iter());
 
287
                sideTree.sideListSelectionChange();
 
288
                sideTree.expand_all();
 
289
                
 
290
                sideTreeScroll = new ScrolledWindow(null, null);
 
291
                sideTreeScroll.set_policy (PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
 
292
                sideTreeScroll.add(sideTree);
 
293
        }
 
294
        
 
295
        public void addSideListItem(GLib.Object o) {
 
296
                TreeIter item = sideTree.get_library_iter();
 
297
                int index = 0;
 
298
                MusicTreeView mtv = null;
 
299
                
 
300
                if(o is Playlist) {
 
301
                        Playlist p = (Playlist)o;
 
302
                        
 
303
                        mtv = new MusicTreeView(lm, this, -1);
 
304
                        mtv.set_hint("playlist");
 
305
                        mtv.set_id(p.rowid);
 
306
                        mtv.populateView(lm.songs_from_playlist(p.rowid), false);
 
307
                        item = sideTree.addItem(sideTree.get_library_iter(), p, mtv, p.name);
 
308
                        mainViews.pack_start(mtv, true, true, 0);
 
309
                }
 
310
                else if(o is SmartPlaylist) {
 
311
                        SmartPlaylist p = (SmartPlaylist)o;
 
312
                        
 
313
                        mtv = new MusicTreeView(lm, this, -1);
 
314
                        mtv.set_hint("smart playlist");
 
315
                        mtv.set_id(p.rowid);
 
316
                        mtv.populateView(lm.songs_from_smart_playlist(p.rowid), false);
 
317
                        item = sideTree.addItem(sideTree.get_library_iter(), p, mtv, p.name);
 
318
                        mainViews.pack_start(mtv, true, true, 0);
 
319
                }
 
320
                
 
321
                mtv.show_all();
 
322
                mtv.view_being_searched.connect(musicTreeViewSearched);
 
323
                sideTree.get_selection().unselect_all();
 
324
                sideTree.get_selection().select_iter(item);
 
325
        }
 
326
        
 
327
        public virtual void progressNotification(string? message, double progress) {
 
328
                /*if(message != null)
 
329
                        topDisplay.set_label_text(message);
 
330
                
 
331
                topDisplay.set_progress_value(progress);*/
 
332
        }
 
333
        
 
334
        public virtual void sideListDoubleClick (TreePath path, TreeViewColumn column) {
 
335
                
 
336
        }
 
337
        
 
338
        public bool updateCurrentSong() {
 
339
                //loop through all musictreeviews and call updatecurrentsong
 
340
                
 
341
                string file = "";
 
342
                if((file = lm.get_album_location(lm.song_info.song.rowid)) != null) {
 
343
                        coverArt.show();
 
344
                        coverArt.set_from_file(file);
 
345
                }
 
346
                else if(lm.song_info.album.url_image.image != null) {
 
347
                        coverArt.show();
 
348
                        coverArt.set_from_pixbuf(lm.song_info.album.url_image.image);
 
349
                }
 
350
                else
 
351
                        coverArt.hide();
 
352
                
 
353
                return false;
 
354
        }
 
355
        
 
356
        /** This should be used whenever a call to play a new song is made
 
357
         * @param s The song that is now playing
 
358
         */
 
359
        public virtual void song_played(int i) {
 
360
                //set the title
 
361
                var song_label = lm.song_from_id(i).title + " by " + lm.song_from_id(i).artist + " on " + lm.song_from_id(i).album;
 
362
                topDisplay.set_label_text(song_label);
 
363
                
 
364
                //reset the song position
 
365
                topDisplay.set_scale_range(0.0, lm.song_info.song.length);
 
366
                topDisplay.set_scale_value(0.0);
 
367
                
 
368
                //if(!songPosition.get_sensitive())
 
369
                //      songPosition.set_sensitive(true);
 
370
                
 
371
                //reset some booleans
 
372
                queriedlastfm = false;
 
373
                song_considered_played = false;
 
374
                added_to_play_count = false;
 
375
                
 
376
                
 
377
                //update the notifier
 
378
                //notification.close();
 
379
                //notification.summary = lm.song_from_id(i).title;
 
380
                //notification.body = lm.song_from_id(i).artist + "\n" + lm.song_from_id(i).album;
 
381
                
 
382
                //look for album art
 
383
                string file = "";
 
384
                if((file = lm.get_album_location(lm.song_info.song.rowid)) != null) {
 
385
                        coverArt.show();
 
386
                        coverArt.set_from_pixbuf(new LastFM.Image.with_url("file://" + file, true).image);
 
387
                        //notification.set_image_from_pixbuf(new Gdk.Pixbuf.from_file(file));
 
388
                }
 
389
                else {
 
390
                        //notification.set_image_from_pixbuf(new Gdk.Pixbuf.from_file(Environment.get_home_dir () + "/.beatbox/default_cover.jpg"));
 
391
                        coverArt.hide();
 
392
                }
 
393
                
 
394
                //show the notifier
 
395
                //notification.show();
 
396
                
 
397
                sideTree.updatePlayQueue();
 
398
        }
 
399
        
 
400
        public void* lastfm_thread_function () {
 
401
                bool update_track = false, update_artist = false, update_album = false;
 
402
                LastFM.ArtistInfo artist = new LastFM.ArtistInfo.basic();
 
403
                LastFM.TrackInfo track = new LastFM.TrackInfo.basic();
 
404
                LastFM.AlbumInfo album = new LastFM.AlbumInfo.basic();
 
405
                
 
406
                if(lm.song_info.album.name != lm.song_info.song.album || lm.song_info.album.artist != lm.song_info.song.artist) {
 
407
                        update_album = true;
 
408
                        
 
409
                        if(!lm.album_info_exists(lm.song_info.song.album + " by " + lm.song_info.song.artist)) {
 
410
                                //stdout.printf("Downloading new Album Info from Last FM\n");
 
411
                                album = new LastFM.AlbumInfo.with_info(lm.song_info.song.artist, lm.song_info.song.album);
 
412
                                
 
413
                                //try to save album image locally
 
414
                                if(lm.get_album_location(lm.song_info.song.rowid) == null)
 
415
                                        lm.save_album_locally(lm.song_info.song.rowid, album.url_image.url);
 
416
                                
 
417
                                lm.save_album(album);
 
418
                        }
 
419
                        else {
 
420
                                album = lm.get_album(lm.song_info.song.album + " by " + lm.song_info.song.artist);
 
421
                                
 
422
                                //if no local image saved, save it now
 
423
                                if(lm.get_album_location(lm.song_info.song.rowid) == null)
 
424
                                        lm.save_album_locally(lm.song_info.song.rowid, album.url_image.url);
 
425
                        }
 
426
                }
 
427
                if(lm.song_info.artist.name != lm.song_info.song.artist) {
 
428
                        update_artist = true;
 
429
                        
 
430
                        if(!lm.artist_info_exists(lm.song_info.song.artist)) {
 
431
                                //stdout.printf("Downloading new Artist Info from Last FM\n");
 
432
                                artist = new LastFM.ArtistInfo.with_artist(lm.song_info.song.artist);
 
433
                                
 
434
                                //try to save artist art locally
 
435
                                if(lm.get_album_location(lm.song_info.song.rowid) == null)
 
436
                                        lm.save_artist_image_locally(lm.song_info.song.rowid, artist.url_image.url);
 
437
                                
 
438
                                lm.save_artist(artist);
 
439
                        }
 
440
                        else {
 
441
                                artist = lm.get_artist(lm.song_info.song.artist);
 
442
                                
 
443
                                //if no local image saved, save it now
 
444
                                if(lm.get_artist_image_location(lm.song_info.song.rowid) == null)
 
445
                                        lm.save_artist_image_locally(lm.song_info.song.rowid, artist.url_image.url);
 
446
                        }
 
447
                }
 
448
                if(lm.song_info.track.name != lm.song_info.song.title || lm.song_info.track.artist != lm.song_info.song.artist) {
 
449
                        update_track = true;
 
450
                        
 
451
                        if(!lm.track_info_exists(lm.song_info.song.title + " by " + lm.song_info.song.artist)) {
 
452
                                //stdout.printf("Downloading new Track Info from Last FM\n");
 
453
                                track = new LastFM.TrackInfo.with_info(lm.song_info.song.artist, lm.song_info.song.title);
 
454
                                lm.save_track(track);
 
455
                        }
 
456
                        else
 
457
                                track = lm.get_track(lm.song_info.song.title + " by " + lm.song_info.song.artist);
 
458
                }
 
459
                
 
460
                //test if song info is still what we want or if user has moved on
 
461
                bool update_song_display = false;
 
462
                
 
463
                if(lm.song_info.album.name != album.name && update_album) {
 
464
                        update_song_display = true;
 
465
                        lm.song_info.album = album;
 
466
                }
 
467
                if(lm.song_info.artist.name != artist.name && update_artist) {
 
468
                        update_song_display = true;
 
469
                        lm.song_info.artist = artist;
 
470
                }
 
471
                if(lm.song_info.track.name != track.name && update_track) {
 
472
                        update_song_display = true;
 
473
                        lm.song_info.track = track;
 
474
                }
 
475
                
 
476
                if(update_song_display) {
 
477
                        Idle.add(updateSongInfo);
 
478
                        Idle.add(updateCurrentSong);
 
479
                }
 
480
                
 
481
                return null;
 
482
    }
 
483
    
 
484
    public bool updateSongInfo() {
 
485
                string html_file = lm.song_info.update_file(lm.song_info.artist, lm.song_info.track, lm.song_info.album, lm.song_info.song);
 
486
                songInfo.open(html_file);
 
487
                
 
488
                return false;
 
489
        }
 
490
        
 
491
        public virtual void previousClicked () {
 
492
                lm.getPrevious(true);
 
493
        }
 
494
        
 
495
        public virtual void playClicked () {
 
496
                if(lm.song_info.song == null) {
 
497
                        //set current songs by current view
 
498
                        Widget w = sideTree.getSelectedWidget();
 
499
                        if(w is MusicTreeView) {
 
500
                                ((MusicTreeView)w).setAsCurrentList("0");
 
501
                        }
 
502
                        else {
 
503
                                w = sideTree.getWidget(sideTree.get_library_iter());
 
504
                                ((MusicTreeView)w).setAsCurrentList("0");
 
505
                        }
 
506
                        
 
507
                        lm.playing = true;
 
508
                        playButton.set_stock_id(Gtk.Stock.MEDIA_PAUSE);
 
509
                        player.play_stream();
 
510
                        
 
511
                        lm.getNext(true);
 
512
                }
 
513
                else {
 
514
                        if(lm.playing) {
 
515
                                lm.playing = false;
 
516
                                player.pause_stream();
 
517
                                playButton.set_stock_id(Gtk.Stock.MEDIA_PLAY);
 
518
                        }
 
519
                        else {
 
520
                                lm.playing = true;
 
521
                                player.play_stream();
 
522
                                playButton.set_stock_id(Gtk.Stock.MEDIA_PAUSE);
 
523
                        }
 
524
                }
 
525
        }
 
526
        
 
527
        public virtual void nextClicked() {
 
528
                lm.getNext(true);
 
529
        }
 
530
        
 
531
        public virtual void shuffleClicked() {
 
532
                if(shuffleButton.get_label() == "Shuffle") {
 
533
                        shuffleButton.set_label("Unshuffle");
 
534
                        lm.shuffleMusic();
 
535
                }
 
536
                else {
 
537
                        shuffleButton.set_label("Shuffle");
 
538
                        lm.unShuffleMusic();
 
539
                }
 
540
        }
 
541
        
 
542
        public virtual void loveButtonClicked() {
 
543
                lm.lfm.loveTrack(lm.song_info.song.title, lm.song_info.song.artist);
 
544
        }
 
545
        
 
546
        public virtual void banButtonClicked() {
 
547
                lm.lfm.banTrack(lm.song_info.song.title, lm.song_info.song.artist);
 
548
        }
 
549
        
 
550
        /** implement search in librarymanager?????? **/
 
551
        public virtual void searchFieldChanged() {
 
552
                Timeout.add(350, () => {
 
553
                        //make sure we still want to search
 
554
                        if(searchField.get_text() == timeout_search && searchField.is_searching) {
 
555
                                Collection<int> songs;
 
556
                                MusicTreeView mtv = (MusicTreeView)sideTree.get_current_widget();
 
557
                                        
 
558
                                songs = lm.songs_from_search(searchField.get_text(), mtv.get_songs());
 
559
                                mtv.populateView(songs, true);
 
560
                        }
 
561
                        
 
562
                        return false;
 
563
                });
 
564
        }
 
565
        
 
566
        public virtual void musicTreeViewSearched(string search) {
 
567
                searchField.focus(DirectionType.UP);
 
568
                searchField.set_text(search);
 
569
                searchField.move_cursor(MovementStep.VISUAL_POSITIONS, 1, false);
 
570
        }
 
571
        
 
572
        public virtual void sourcesToSongsHandleSet(Gdk.Rectangle rectangle) {
 
573
                settings.setSidebarWidth(rectangle.width);
 
574
        }
 
575
        
 
576
        public virtual void on_resize() {
 
577
                int width;
 
578
                int height;
 
579
                this.get_size(out width, out height);
 
580
                settings.setWindowWidth(width);
 
581
                settings.setWindowHeight(height);
 
582
        }
 
583
        
 
584
        public virtual void on_quit() {
 
585
                // save the columns
 
586
                var columns = new ArrayList<TreeViewColumn>();
 
587
                
 
588
                Widget w = sideTree.getWidget(sideTree.get_library_iter());
 
589
                if(w is MusicTreeView) {
 
590
                        MusicTreeView view = (MusicTreeView)w;
 
591
                        
 
592
                        foreach(TreeViewColumn tvc in view.get_columns()) {
 
593
                                columns.add(tvc);
 
594
                        }
 
595
                        
 
596
                        lm.save_song_list_columns(columns);
 
597
                }
 
598
                
 
599
                stdout.printf("Stopping playback\n");
 
600
                player.pause_stream();
 
601
                
 
602
                stdout.printf("Saving songs\n");
 
603
                lm.save_songs();
 
604
                
 
605
                stdout.printf("Saving playlists\n");
 
606
                lm.save_playlists();
 
607
                lm.save_smart_playlists();
 
608
                
 
609
                stdout.printf("Saving LastFM Info\n");
 
610
                lm.save_artists();
 
611
                lm.save_albums();
 
612
                lm.save_tracks();
 
613
                
 
614
                stdout.printf("Bye\n");
 
615
        }
 
616
        
 
617
        public virtual void fileSetMusicFolderClick() {
 
618
                string folder = "";
 
619
                var file_chooser = new FileChooserDialog ("Choose Music Folder", this,
 
620
                                      FileChooserAction.SELECT_FOLDER,
 
621
                                      Gtk.Stock.CANCEL, ResponseType.CANCEL,
 
622
                                      Gtk.Stock.OPEN, ResponseType.ACCEPT);
 
623
        if (file_chooser.run () == ResponseType.ACCEPT) {
 
624
            folder = file_chooser.get_filename();
 
625
        }
 
626
        file_chooser.destroy ();
 
627
        
 
628
        if(folder != "") {
 
629
                        //topDisplay.set_label_showing(true);
 
630
                        topDisplay.set_label_text("Importing music from " + folder);
 
631
                        //topDisplay.show_progressbar();
 
632
                        //lm.set_music_folder(folder);
 
633
                }
 
634
                
 
635
        }
 
636
        
 
637
        public virtual void fileRescanMusicFolderClick() {
 
638
                //topDisplay.set_label_showing(true);
 
639
                topDisplay.set_label_text("Rescanning music folder for changes. This may take a while");
 
640
                //topDisplay.show_progressbar();
 
641
                
 
642
                lm.rescan_music_folders();
 
643
        }
 
644
        
 
645
        public virtual void musicAdded(LinkedList<string> not_imported) {
 
646
                int index = 0;
 
647
                
 
648
                sideTree.resetView();
 
649
                //topDisplay.set_label_showing(false);
 
650
                topDisplay.show_scale();
 
651
                topDisplay.set_label_text("");
 
652
                
 
653
                //repopulate collection and playlists and reset queue and already played
 
654
                Widget w = sideTree.getWidget(sideTree.get_library_iter());
 
655
                ((MusicTreeView)w).populateView(lm.song_ids(), false);
 
656
                
 
657
                if(not_imported.size > 0) {
 
658
                        NotImportedWindow nim = new NotImportedWindow(not_imported);
 
659
                        nim.show();
 
660
                }
 
661
                
 
662
                if(lm.song_count() != 0)
 
663
                        searchField.set_sensitive(true);
 
664
                else
 
665
                        searchField.set_sensitive(false);
 
666
        }
 
667
        
 
668
        public virtual void musicRescanned(LinkedList<string> not_imported) {
 
669
                sideTree.resetView();
 
670
                topDisplay.show_scale();
 
671
                topDisplay.set_label_text("");
 
672
                
 
673
                //repopulate collection and playlists and reset queue and already played
 
674
                Widget w = sideTree.getWidget(sideTree.get_library_iter());
 
675
                ((MusicTreeView)w).populateView(lm.song_ids(), false);
 
676
                
 
677
                if(not_imported.size > 0) {
 
678
                        NotImportedWindow nim = new NotImportedWindow(not_imported);
 
679
                        nim.show();
 
680
                }
 
681
                
 
682
                if(lm.song_count() != 0)
 
683
                        searchField.set_sensitive(true);
 
684
                else
 
685
                        searchField.set_sensitive(false);
 
686
        }
 
687
        
 
688
        public virtual void songRemovedFromManager(int id) {
 
689
                if(lm.song_count() != 0)
 
690
                        searchField.set_sensitive(true);
 
691
                else
 
692
                        searchField.set_sensitive(false);
 
693
        }
 
694
        
 
695
        public virtual void helpAboutClick() {
 
696
                AboutDialog ad = new AboutDialog();
 
697
                
 
698
                ad.set_program_name("BeatBox");
 
699
                ad.set_version("0.1");
 
700
                ad.set_website("https://launchpad.net/beat-box");
 
701
                ad.set_website_label("Launchpad");
 
702
                ad.set_authors({"Scott Ringwelski"});
 
703
                
 
704
                ad.response.connect( (response_id) => { 
 
705
                        ad.destroy(); 
 
706
                });
 
707
                
 
708
                ad.show();
 
709
        }
 
710
        
 
711
        public virtual void editPreferencesClick() {
 
712
                PreferencesWindow pw = new PreferencesWindow(lm);
 
713
                
 
714
        }
 
715
        
 
716
        public virtual void end_of_stream(Song s) {
 
717
                nextClicked();
 
718
        }
 
719
        
 
720
        public virtual void current_position_update(int64 position) {
 
721
                double sec = 0.0;
 
722
                if(lm.song_info.song != null) {
 
723
                        sec = ((double)position/1000000000);
 
724
                        
 
725
                        // at about 5 seconds, update last fm. we wait to avoid excessive querying last.fm for info
 
726
                        if(position > 5000000000 && !queriedlastfm) {
 
727
                                queriedlastfm = true;
 
728
                                try {
 
729
                                        Thread.create<void*>(lastfm_thread_function, false);
 
730
                                }
 
731
                                catch(GLib.ThreadError err) {
 
732
                                        stdout.printf("ERROR: Could not create last fm thread: %s \n", err.message);
 
733
                                }
 
734
                        }
 
735
                        
 
736
                        //at 30 seconds in, we consider the song as played
 
737
                        if(position > 30000000000 && !song_considered_played) {
 
738
                                song_considered_played = true;
 
739
                                
 
740
                                lm.song_info.song.last_played = (int)time_t();
 
741
                                lm.update_song(lm.song_info.song);
 
742
                                
 
743
                                // add to the already played list
 
744
                                lm.add_already_played(lm.song_info.song.rowid);
 
745
                                sideTree.updateAlreadyPlayed();
 
746
                        }
 
747
                        
 
748
                        // at 90% done with song, add 1 to play count
 
749
                        if((sec/(double)lm.song_info.song.length) > 0.90 && !added_to_play_count) {
 
750
                                added_to_play_count = true;
 
751
                                lm.song_info.song.play_count++;
 
752
                                updateCurrentSong();
 
753
                        }
 
754
                        
 
755
                }
 
756
                else {
 
757
                        
 
758
                }
 
759
        }
 
760
        
 
761
        public virtual void topDisplaySliderMoved(ScrollType scroll, double val) {
 
762
                //temporarily disable updates
 
763
                player.current_position_update.disconnect(current_position_update);
 
764
                
 
765
                player.seek_position((int64)(val * 1000000000));
 
766
                
 
767
                //re-enable streamplayer's updates
 
768
                this.player.current_position_update.connect(current_position_update);
 
769
        }
 
770
}