Merge lp:~victored/beat-box/threads into lp:beat-box

Proposed by Victor Martinez
Status: Merged
Merged at revision: 654
Proposed branch: lp:~victored/beat-box/threads
Merge into: lp:beat-box
Diff against target: 3303 lines (+751/-811) (has conflicts)
31 files modified
src/BeatBox.vala (+9/-9)
src/CMakeLists.txt (+2/-2)
src/Core/FileOperator.vala (+36/-27)
src/Core/LibraryManager.vala (+340/-211)
src/Core/LibraryWindow.vala (+15/-15)
src/Core/PodcastManager.vala (+17/-17)
src/DataBase/DataBaseUpdater.vala (+69/-84)
src/Devices/CDRomDevice.vala (+3/-3)
src/Devices/DeviceManager.vala (+20/-14)
src/Devices/iPodDevice.vala (+15/-15)
src/Lastfm/LastFM.vala (+116/-133)
src/Lastfm/SimilarMedia.vala (+5/-7)
src/Lastfm/TopArtistAlbums.vala (+12/-10)
src/Lastfm/TopArtistSongs.vala (+8/-10)
src/Lists/GenericList.vala (+3/-3)
src/Media/LyricFetcher.vala (+7/-7)
src/Store/Widgets/AlbumView.vala (+12/-11)
src/Store/Widgets/ArtistView.vala (+9/-9)
src/Store/Widgets/HomeView.vala (+15/-13)
src/Store/Widgets/StoreView.vala (+8/-8)
src/Views/SimilarMediaView.vala (+5/-5)
src/Widgets/EmbeddedAlert.vala (+3/-9)
src/Widgets/SearchSuggester.vala (+3/-3)
src/Widgets/StatusBar.vala (+1/-66)
src/Widgets/StyledWidgets/StyledArtistImages.vala (+5/-6)
src/Widgets/WarningLabel.vala (+0/-99)
src/Windows/AddPodcastWindow.vala (+3/-3)
src/Windows/RemoveDuplicatesDialog.vala (+3/-3)
src/Wrappers/PodcastViewWrapper.vala (+4/-4)
src/Wrappers/StationViewWrapper.vala (+3/-3)
src/Wrappers/ViewWrapper.vala (+0/-2)
Text conflict in src/Devices/DeviceManager.vala
Text conflict in src/Lastfm/TopArtistAlbums.vala
To merge this branch: bzr merge lp:~victored/beat-box/threads
Reviewer Review Type Date Requested Status
Scott Ringwelski Approve
Review via email: mp+113161@code.launchpad.net

Description of the change

Port to GLib 2.32 thread API

To post a comment you must log in.
Revision history for this message
Scott Ringwelski (sgringwe) wrote :

I haven't actually tested it yet, but I went through the whole diff and looks great. I did find a few locks that were missing, but maybe they just didn't show up in the diff.

Agree with your comments for the most part.

There was one thing I disagreed with - in lyrics fetcher - but that is no showstopper. Will merge when I get home or you can if you are ok with me skipping testing.

Awesome work!

review: Approve
lp:~victored/beat-box/threads updated
642. By Victor Martinez

Don't use compact class for AZLyrics fetcher and make LibraryManager::recheck_files_not_found_async() actually async

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/BeatBox.vala'
--- src/BeatBox.vala 2012-06-19 22:50:13 +0000
+++ src/BeatBox.vala 2012-07-03 06:49:24 +0000
@@ -46,13 +46,7 @@
46 warning ("Error parsing arguments: %s\n", err.message);46 warning ("Error parsing arguments: %s\n", err.message);
47 }47 }
4848
49 Gdk.threads_init();
50 Gdk.threads_enter();
51 Gtk.init(ref args);49 Gtk.init(ref args);
52 Gdk.threads_leave();
53
54 Notify.init("beatbox");
55 GLib.Environment.set_prgname("beatbox");
5650
57 try {51 try {
58 Gst.init_check (ref args);52 Gst.init_check (ref args);
@@ -146,7 +140,7 @@
146 }140 }
147 } 141 }
148142
149 //library_manager.play_files (to_play);143 //library_manager.play_files (to_play);
150 }144 }
151145
152 protected override void activate () {146 protected override void activate () {
@@ -171,10 +165,16 @@
171 //plugins.hook_new_window (library_window);165 //plugins.hook_new_window (library_window);
172 }166 }
173167
168 // FIXME: mounting the music folder and accessing the files shold
169 // not be done on separate threads. recheck_files_not_found() should
170 // be called using an Idle.add (Priority.LOW, ...) instead. Same for
171 // podcast checking and album art download.
172
174 // In 10 seconds, check for missing songs. This gives enought time173 // In 10 seconds, check for missing songs. This gives enought time
175 // to automount the music folder174 // to automount the music folder
176 Timeout.add(10000, () => {175 // FIXME: This code is race-condition-prone
177 library_manager.recheck_files_not_found();176 Timeout.add(10000, () => {
177 library_manager.recheck_files_not_found_async ();
178 178
179 return false;179 return false;
180 });180 });
181181
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2012-07-02 01:40:25 +0000
+++ src/CMakeLists.txt 2012-07-03 06:49:24 +0000
@@ -52,7 +52,6 @@
52 Playlists/SmartQuery.vala52 Playlists/SmartQuery.vala
53 Playlists/SmartPlaylist.vala53 Playlists/SmartPlaylist.vala
54 Widgets/TopDisplay.vala54 Widgets/TopDisplay.vala
55 Widgets/WarningLabel.vala
56 Widgets/SimpleOptionChooser.vala55 Widgets/SimpleOptionChooser.vala
57 Widgets/PresetList.vala56 Widgets/PresetList.vala
58 Widgets/SideBar.vala57 Widgets/SideBar.vala
@@ -61,7 +60,7 @@
61 Widgets/StatusBar.vala60 Widgets/StatusBar.vala
62 Widgets/SearchSuggester.vala61 Widgets/SearchSuggester.vala
63 Widgets/TaggingArea.vala62 Widgets/TaggingArea.vala
64 Widgets/InfoPanel.vala63 # Widgets/InfoPanel.vala
65 Widgets/VolumeWidget.vala64 Widgets/VolumeWidget.vala
66 Widgets/NavigationArrows.vala65 Widgets/NavigationArrows.vala
67 Widgets/EmbeddedAlert.vala66 Widgets/EmbeddedAlert.vala
@@ -177,6 +176,7 @@
177OPTIONS176OPTIONS
178 --vapidir=${CMAKE_SOURCE_DIR}/vapi177 --vapidir=${CMAKE_SOURCE_DIR}/vapi
179 --vapidir=${CMAKE_BINARY_DIR}/core/178 --vapidir=${CMAKE_BINARY_DIR}/core/
179 --target-glib=2.32
180 ${ADD_OPTIONS}180 ${ADD_OPTIONS}
181GENERATE_VAPI181GENERATE_VAPI
182 beatbox182 beatbox
183183
=== modified file 'src/Core/FileOperator.vala'
--- src/Core/FileOperator.vala 2012-06-13 23:54:06 +0000
+++ src/Core/FileOperator.vala 2012-07-03 06:49:24 +0000
@@ -86,7 +86,7 @@
86 album_art_folder.make_directory_with_parents(null);86 album_art_folder.make_directory_with_parents(null);
87 }87 }
88 catch(GLib.Error err) {88 catch(GLib.Error err) {
89 warning ("Could not create folder in cache directory: %s\n", err.message);89 warning ("Could not create folder in cache directory: %s", err.message);
90 }90 }
91 } 91 }
92 }92 }
@@ -133,14 +133,23 @@
133 }133 }
134 }134 }
135 catch(GLib.Error err) {135 catch(GLib.Error err) {
136 warning("Could not pre-scan music folder. Progress percentage may be off: %s\n", err.message);136 warning("Could not pre-scan music folder. Progress percentage may be off: %s", err.message);
137 }137 }
138 138
139 return index;139 return index;
140 }140 }
141 141
142 public void* queue_music_files_bootstrap_thread() {142 public async void queue_music_files_bootstrap_async () {
143 queue_music_files(import_file);143 try {
144 new Thread<void*>.try (null, queue_music_files_bootstrap_thread);
145 }
146 catch (Error err) {
147 warning ("Could not create thread for queue_music_files_bootstrap: %s", err.message);
148 }
149 }
150
151 private void* queue_music_files_bootstrap_thread () {
152 queue_music_files (import_file);
144 153
145 return null;154 return null;
146 }155 }
@@ -163,7 +172,7 @@
163 }172 }
164 }173 }
165 catch(GLib.Error err) {174 catch(GLib.Error err) {
166 warning("Could not pre-scan music folder. Progress percentage may be off: %s\n", err.message);175 warning("Could not pre-scan music folder. Progress percentage may be off: %s", err.message);
167 }176 }
168 177
169 // Let it be known that all files are queued and may now finish import178 // Let it be known that all files are queued and may now finish import
@@ -254,7 +263,7 @@
254 if(success) {263 if(success) {
255 foreach(int i in lm.media_ids()) {264 foreach(int i in lm.media_ids()) {
256 if(lm.media_from_id(i).album_artist == m.album_artist && lm.media_from_id(i).album == m.album) {265 if(lm.media_from_id(i).album_artist == m.album_artist && lm.media_from_id(i).album == m.album) {
257 debug("setting album art for %s by %s\n", lm.media_from_id(i).title, lm.media_from_id(i).artist);266 debug("setting album art for %s by %s", lm.media_from_id(i).title, lm.media_from_id(i).artist);
258 lm.media_from_id(i).setAlbumArtPath(uri);267 lm.media_from_id(i).setAlbumArtPath(uri);
259 }268 }
260 }269 }
@@ -294,10 +303,10 @@
294 if(!inThread && lm.lw.initializationFinished) {303 if(!inThread && lm.lw.initializationFinished) {
295 try {304 try {
296 inThread = true;305 inThread = true;
297 Thread.create<void*>(save_media_thread, false);306 new Thread<void*>.try (null, save_media_thread);
298 }307 }
299 catch(GLib.Error err) {308 catch (Error err) {
300 warning ("Could not create thread to rescan music folder: %s\n", err.message);309 warning ("Could not create thread to rescan music folder: %s", err.message);
301 }310 }
302 }311 }
303 }312 }
@@ -332,7 +341,7 @@
332 }341 }
333 }342 }
334 else {343 else {
335 debug ("Could not save %s.\n", s.uri);344 debug ("Could not save %s.", s.uri);
336 }345 }
337 }346 }
338 347
@@ -357,7 +366,7 @@
357 dest = GLib.File.new_for_path(Path.build_path("/", settings.getMusicFolder(), s.artist.replace("/", "_"), s.album.replace("/", "_"), s.track.to_string() + " " + s.title.replace("/", "_") + ext));366 dest = GLib.File.new_for_path(Path.build_path("/", settings.getMusicFolder(), s.artist.replace("/", "_"), s.album.replace("/", "_"), s.track.to_string() + " " + s.title.replace("/", "_") + ext));
358 367
359 if(original.get_path() == dest.get_path()) {368 if(original.get_path() == dest.get_path()) {
360 debug("File is already in correct location\n");369 debug("File is already in correct location");
361 return null;370 return null;
362 }371 }
363 372
@@ -371,7 +380,7 @@
371 dest.get_parent().make_directory_with_parents(null);380 dest.get_parent().make_directory_with_parents(null);
372 }381 }
373 catch(GLib.Error err) {382 catch(GLib.Error err) {
374 debug("Could not find new destination!: %s\n", err.message);383 debug("Could not find new destination!: %s", err.message);
375 }384 }
376 385
377 return dest;386 return dest;
@@ -389,17 +398,17 @@
389 398
390 /* copy the file over */399 /* copy the file over */
391 if(!delete_old) {400 if(!delete_old) {
392 debug("Copying %s to %s\n", s.uri, dest.get_uri());401 debug("Copying %s to %s", s.uri, dest.get_uri());
393 success = original.copy(dest, FileCopyFlags.NONE, null, null);402 success = original.copy(dest, FileCopyFlags.NONE, null, null);
394 }403 }
395 else {404 else {
396 debug("Moving %s to %s\n", s.uri, dest.get_uri());405 debug("Moving %s to %s", s.uri, dest.get_uri());
397 success = original.move(dest, FileCopyFlags.NONE, null, null);406 success = original.move(dest, FileCopyFlags.NONE, null, null);
398 }407 }
399 408
400 if(success || dest.query_exists()) {409 if(success || dest.query_exists()) {
401 success = true;410 success = true;
402 debug("success copying file\n");411 debug("success copying file");
403 s.uri = dest.get_uri();412 s.uri = dest.get_uri();
404 413
405 // Save the uri change in the database414 // Save the uri change in the database
@@ -415,13 +424,13 @@
415 424
416 if(!GLib.File.new_for_path(albumArtDest).query_exists() && mediaFile.query_exists() &&425 if(!GLib.File.new_for_path(albumArtDest).query_exists() && mediaFile.query_exists() &&
417 mediaFile.copy(GLib.File.new_for_path(albumArtDest), FileCopyFlags.NONE, null, null)) {426 mediaFile.copy(GLib.File.new_for_path(albumArtDest), FileCopyFlags.NONE, null, null)) {
418 debug("Copying album art to %s\n", albumArtDest);427 debug("Copying album art to %s", albumArtDest);
419 s.setAlbumArtPath(albumArtDest);428 s.setAlbumArtPath(albumArtDest);
420 }429 }
421 }430 }
422 }431 }
423 else432 else
424 warning("Failure: Could not copy imported media %s to media folder %s\n", s.uri, dest.get_path());433 warning("Failure: Could not copy imported media %s to media folder %s", s.uri, dest.get_path());
425 434
426 /* if we are supposed to delete the old, make sure there are no items left in folder if we do */435 /* if we are supposed to delete the old, make sure there are no items left in folder if we do */
427 if(delete_old) {436 if(delete_old) {
@@ -430,13 +439,13 @@
430 // must check for .jpg's as well.439 // must check for .jpg's as well.
431 440
432 if(old_folder_items == 0) {441 if(old_folder_items == 0) {
433 debug("going to delete %s because no files are in it\n", original.get_parent().get_path());442 debug("going to delete %s because no files are in it", original.get_parent().get_path());
434 original.get_parent().delete();443 original.get_parent().delete();
435 }444 }
436 }445 }
437 }446 }
438 catch(GLib.Error err) {447 catch(GLib.Error err) {
439 warning("Could not copy imported media %s to media folder: %s\n", s.uri, err.message);448 warning("Could not copy imported media %s to media folder: %s", s.uri, err.message);
440 }449 }
441 450
442 return success;451 return success;
@@ -453,18 +462,18 @@
453 462
454 //TODO: COPY ALBUM AND IMAGE ARTWORK463 //TODO: COPY ALBUM AND IMAGE ARTWORK
455 if(old_folder_items == 0) {464 if(old_folder_items == 0) {
456 debug("going to delete %s because no files are in it\n", file.get_parent().get_path());465 debug("going to delete %s because no files are in it", file.get_parent().get_path());
457 //original.get_parent().delete();466 //original.get_parent().delete();
458 467
459 var old_folder_parent_items = count_music_files(file.get_parent().get_parent(), ref dummy_list);468 var old_folder_parent_items = count_music_files(file.get_parent().get_parent(), ref dummy_list);
460 469
461 if(old_folder_parent_items == 0) {470 if(old_folder_parent_items == 0) {
462 debug("going to delete %s because no files are in it\n", file.get_parent().get_parent().get_path());471 debug("going to delete %s because no files are in it", file.get_parent().get_parent().get_path());
463 }472 }
464 }473 }
465 }474 }
466 catch(GLib.Error err) {475 catch(GLib.Error err) {
467 warning("Could not move file %s to trash: %s (you could be using a file system which is not supported)\n", s, err.message);476 warning("Could not move file %s to trash: %s (you could be using a file system which is not supported)", s, err.message);
468 477
469 //tell the user the file could not be moved and ask if they'd like to delete permanently instead.478 //tell the user the file could not be moved and ask if they'd like to delete permanently instead.
470 //Gtk.MessageDialog md = new Gtk.MessageDialog(lm.lw, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Could not trash file %s, would you like to permanently delete it? You cannot undo these changes.", s);479 //Gtk.MessageDialog md = new Gtk.MessageDialog(lm.lw, Gtk.DialogFlags.MODAL, Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, "Could not trash file %s, would you like to permanently delete it? You cannot undo these changes.", s);
@@ -491,7 +500,7 @@
491 }500 }
492 }501 }
493 catch(GLib.Error err) {502 catch(GLib.Error err) {
494 message("Could not guess content types: %s\n", err.message);503 message("Could not guess content types: %s", err.message);
495 }504 }
496 }*/505 }*/
497 506
@@ -608,10 +617,10 @@
608 fo_progress(_("<b>Copying</b> files to <b>Music Folder</b>..."), 0.0);617 fo_progress(_("<b>Copying</b> files to <b>Music Folder</b>..."), 0.0);
609 618
610 try {619 try {
611 Thread.create<void*>(copy_imports_thread, false);620 new Thread<void*>.try (null, copy_imports_thread);
612 }621 }
613 catch(GLib.Error err) {622 catch (Error err) {
614 warning("Could not create thread to rescan music folder: %s\n", err.message);623 warning ("Could not create thread to rescan music folder: %s", err.message);
615 }624 }
616 }625 }
617 else {626 else {
618627
=== modified file 'src/Core/LibraryManager.vala'
--- src/Core/LibraryManager.vala 2012-07-02 23:17:27 +0000
+++ src/Core/LibraryManager.vala 2012-07-03 06:49:24 +0000
@@ -29,7 +29,15 @@
29 */29 */
30public class BeatBox.LibraryManager : /*BeatBox.LibraryModel,*/ GLib.Object {30public class BeatBox.LibraryManager : /*BeatBox.LibraryModel,*/ GLib.Object {
31 public static const int PREVIEW_MEDIA_ID = -2;31 public static const int PREVIEW_MEDIA_ID = -2;
32 public BeatBox.LibraryWindow lw;32
33 // FIXME (BeatBox 0.7+)
34 // At this point, a signal should be emmited
35 // to let LibraryWindow know what's happening
36 // under the hood.
37 // UI code doesn't belong here.
38 public BeatBox.LibraryWindow lw; // Drop this reference
39
40
33 public BeatBox.Settings settings;41 public BeatBox.Settings settings;
34 public BeatBox.DataBaseManager dbm;42 public BeatBox.DataBaseManager dbm;
35 public BeatBox.DataBaseUpdater dbu;43 public BeatBox.DataBaseUpdater dbu;
@@ -38,13 +46,6 @@
38 public BeatBox.DeviceManager device_manager;46 public BeatBox.DeviceManager device_manager;
39 public BeatBox.PodcastManager pm;47 public BeatBox.PodcastManager pm;
40 48
41 Mutex _media_lock; // lock for _media. use this around _media, _songs
42 Mutex _songs_lock;
43 Mutex _podcasts_lock;
44 Mutex _audiobooks_lock;
45 Mutex _stations_lock;
46 Mutex _playlists_lock; // lock for _playlists
47 Mutex _smart_playlists_lock; // lock for _smart_playlists
48 HashMap<int, SmartPlaylist> _smart_playlists; // rowid, smart playlist49 HashMap<int, SmartPlaylist> _smart_playlists; // rowid, smart playlist
49 HashMap<int, Playlist> _playlists; // rowid, playlist of all playlists50 HashMap<int, Playlist> _playlists; // rowid, playlist of all playlists
50 HashMap<int, Media> _media; // rowid, media of all medias51 HashMap<int, Media> _media; // rowid, media of all medias
@@ -126,9 +127,12 @@
126 public signal void media_queued(Media m);127 public signal void media_queued(Media m);
127 public signal void media_played(Media id, Media? old_id);128 public signal void media_played(Media id, Media? old_id);
128 public signal void playback_stopped(int was_playing);129 public signal void playback_stopped(int was_playing);
129 130
131 // FIXME (BeatBox 0.7+)
132 // Drop reference to LibraryWindow
130 public LibraryManager(BeatBox.Settings sett, BeatBox.LibraryWindow lww) {133 public LibraryManager(BeatBox.Settings sett, BeatBox.LibraryWindow lww) {
131 this.lw = lww;134 this.lw = lww;
135
132 this.settings = sett;136 this.settings = sett;
133 this.player = new Streamer(this, lw);137 this.player = new Streamer(this, lw);
134 138
@@ -139,14 +143,7 @@
139 143
140 fo.fo_progress.connect(dbProgress);144 fo.fo_progress.connect(dbProgress);
141 dbm.db_progress.connect(dbProgress);145 dbm.db_progress.connect(dbProgress);
142 146
143 _smart_playlists_lock = new Mutex();
144 _playlists_lock = new Mutex();
145 _media_lock = new Mutex();
146 _songs_lock = new Mutex();
147 _podcasts_lock = new Mutex();
148 _audiobooks_lock = new Mutex();
149 _stations_lock = new Mutex();
150 147
151 _smart_playlists = new HashMap<int, SmartPlaylist>();148 _smart_playlists = new HashMap<int, SmartPlaylist>();
152 _playlists = new HashMap<int, Playlist>();149 _playlists = new HashMap<int, Playlist>();
@@ -195,51 +192,73 @@
195 album_list_setup = new TreeViewSetup(MusicList.MusicColumn.TRACK, Gtk.SortType.ASCENDING, ViewWrapper.Hint.ALBUM_LIST);192 album_list_setup = new TreeViewSetup(MusicList.MusicColumn.TRACK, Gtk.SortType.ASCENDING, ViewWrapper.Hint.ALBUM_LIST);
196 193
197 //load all medias from db194 //load all medias from db
198 _media_lock.lock ();
199 foreach(Media s in dbm.load_medias()) {195 foreach(Media s in dbm.load_medias()) {
200 _media.set(s.rowid, s);196 lock (_media) {
197 _media.set (s.rowid, s);
198 }
201 199
202 if(s.mediatype == MediaType.SONG)200 if (s.mediatype == MediaType.SONG) {
203 _songs.set(s.rowid, s);201 lock (_songs) {
204 else if(s.mediatype == MediaType.PODCAST)202 _songs.set(s.rowid, s);
205 _podcasts.set(s.rowid, s);203 }
206 else if(s.mediatype == MediaType.AUDIOBOOK)204 }
207 _audiobooks.set(s.rowid, s);205 else if (s.mediatype == MediaType.PODCAST) {
208 else if(s.mediatype == MediaType.STATION)206 lock (_podcasts) {
209 _stations.set(s.rowid, s);207 _podcasts.set(s.rowid, s);
210 }208 }
211 _media_lock.unlock();209 }
212 210 else if (s.mediatype == MediaType.AUDIOBOOK) {
213 _smart_playlists_lock.lock();211 lock (_audiobooks) {
214 foreach(SmartPlaylist p in dbm.load_smart_playlists()) {212 _audiobooks.set(s.rowid, s);
215 _smart_playlists.set(p.get_rowid(), p);213 }
216 }214 }
217 _smart_playlists_lock.unlock();215 else if(s.mediatype == MediaType.STATION) {
218 216 lock (_stations) {
217 _stations.set(s.rowid, s);
218 }
219 }
220 }
221
222 lock (_smart_playlists) {
223 foreach (SmartPlaylist p in dbm.load_smart_playlists()) {
224 _smart_playlists.set (p.get_rowid(), p);
225 }
226 }
227
219 //load all playlists from db228 //load all playlists from db
220 _playlists_lock.lock();
221 var playlists_added = new LinkedList<string>();229 var playlists_added = new LinkedList<string>();
222 foreach(Playlist p in dbm.load_playlists()) {230 foreach(Playlist p in dbm.load_playlists()) {
223 if(!playlists_added.contains(p.get_name())) { // sometimes we get duplicates. don't add duplicates231 if(!playlists_added.contains(p.get_name())) { // sometimes we get duplicates. don't add duplicates
224 _playlists.set(p.get_rowid(), p);232 lock (_playlists) {
233 _playlists.set(p.get_rowid(), p);
234 }
225 235
226 if(p.get_name() == "autosaved_music") {236 if(p.get_name() == "autosaved_music") {
227 music_setup = p.tvs;237 music_setup = p.tvs;
228 music_setup.set_hint(ViewWrapper.Hint.MUSIC);238 music_setup.set_hint(ViewWrapper.Hint.MUSIC);
229 _playlists.unset(p.get_rowid());239
240 lock (_playlists) {
241 _playlists.unset (p.get_rowid());
242 }
230 }243 }
231 else if(p.get_name() == "autosaved_podcast") {244 else if(p.get_name() == "autosaved_podcast") {
232 podcast_setup = p.tvs;245 podcast_setup = p.tvs;
233 _playlists.unset(p.get_rowid());246 lock (_playlists) {
247 _playlists.unset (p.get_rowid());
248 }
234 }249 }
235 else if(p.get_name() == "autosaved_station") {250 else if(p.get_name() == "autosaved_station") {
236 station_setup = p.tvs;251 station_setup = p.tvs;
237 _playlists.unset(p.get_rowid());252 lock (_playlists) {
253 _playlists.unset (p.get_rowid());
254 }
238 }255 }
239 else if(p.get_name() == "autosaved_similar") {256 else if(p.get_name() == "autosaved_similar") {
240 similar_setup = p.tvs;257 similar_setup = p.tvs;
241 similar_setup.set_hint(ViewWrapper.Hint.SIMILAR);258 similar_setup.set_hint(ViewWrapper.Hint.SIMILAR);
242 _playlists.unset(p.get_rowid()); 259 lock (_playlists) {
260 _playlists.unset (p.get_rowid());
261 }
243 }262 }
244 else if(p.get_name() == "autosaved_queue") {263 else if(p.get_name() == "autosaved_queue") {
245 foreach(var m in medias_from_playlist(p.get_rowid())) {264 foreach(var m in medias_from_playlist(p.get_rowid())) {
@@ -248,27 +267,26 @@
248 267
249 queue_setup = p.tvs;268 queue_setup = p.tvs;
250 queue_setup.set_hint(ViewWrapper.Hint.QUEUE);269 queue_setup.set_hint(ViewWrapper.Hint.QUEUE);
251 _playlists.unset(p.get_rowid());270 lock (_playlists) {
271 _playlists.unset (p.get_rowid());
272 }
252 }273 }
253 else if(p.get_name() == "autosaved_history") {274 else if(p.get_name() == "autosaved_history") {
254 history_setup = p.tvs;275 history_setup = p.tvs;
255 history_setup.set_hint(ViewWrapper.Hint.HISTORY);276 history_setup.set_hint(ViewWrapper.Hint.HISTORY);
256 _playlists.unset(p.get_rowid());277 lock (_playlists) {
278 _playlists.unset (p.get_rowid());
279 }
257 }280 }
258 281
259 playlists_added.add(p.get_name());282 playlists_added.add(p.get_name());
260 }283 }
261 }284 }
262 _playlists_lock.unlock();
263 285
264 device_manager = new DeviceManager(this);286 device_manager = new DeviceManager(this);
265 287
266 // start thread to load all the medias pixbuf's288 // start thread to load all the medias pixbuf's
267 try {289 fetch_image_cache_async ();
268 Thread.create<void*>(fetch_thread_function, false);
269 } catch(GLib.ThreadError err) {
270 warning("Could not create thread to load media pixbuf's: %s \n", err.message);
271 }
272 }290 }
273 291
274 /*****************************************292 /*****************************************
@@ -289,6 +307,12 @@
289 307
290 public bool doProgressNotificationWithTimeout() {308 public bool doProgressNotificationWithTimeout() {
291 if(_doing_file_operations) {309 if(_doing_file_operations) {
310
311 // FIXME (BeatBox 0.7+)
312 // At this point, a signal should be emmited
313 // to let LibraryWindow know what's happening
314 // under the hood.
315 // UI code doesn't belong here.
292 Gdk.threads_enter();316 Gdk.threads_enter();
293 progress_notification(null, (double)((double)fo.index)/((double)fo.item_count));317 progress_notification(null, (double)((double)fo.index)/((double)fo.item_count));
294 Gdk.threads_leave();318 Gdk.threads_leave();
@@ -303,13 +327,24 @@
303 327
304 public void set_music_folder(string folder) {328 public void set_music_folder(string folder) {
305 if(start_file_operations(_("Importing music from %s...").printf("<b>" + Markup.escape_text(folder) + "</b>"))) {329 if(start_file_operations(_("Importing music from %s...").printf("<b>" + Markup.escape_text(folder) + "</b>"))) {
330
331 // FIXME (BeatBox 0.7+)
332 // At this point, a signal should be emmited
333 // to let LibraryWindow know what's happening
334 // under the hood.
335 // UI code doesn't belong here.
306 lw.resetSideTree(true);336 lw.resetSideTree(true);
307 lw.sideTree.removeAllStaticPlaylists();337 lw.sideTree.removeAllStaticPlaylists();
308 338
309 clear_medias();339 clear_medias();
310 _queue.clear();340 _queue.clear();
311 _already_played.clear();341 _already_played.clear();
312 342
343 // FIXME (BeatBox 0.7+)
344 // At this point, a signal should be emmited
345 // to let LibraryWindow know what's happening
346 // under the hood.
347 // UI code doesn't belong here.
313 lw.resetSideTree(false);348 lw.resetSideTree(false);
314 lw.update_sensitivities();349 lw.update_sensitivities();
315 stopPlayback();350 stopPlayback();
@@ -317,49 +352,58 @@
317 settings.setMusicMountName("");352 settings.setMusicMountName("");
318 settings.setMusicFolder(folder);353 settings.setMusicFolder(folder);
319 354
320 try {355 set_music_folder_async ();
321 Thread.create<void*>(set_music_thread_function, false);356 }
322 }357 }
323 catch(GLib.Error err) {358
324 warning("Could not create thread to set music folder: %s\n", err.message);359 public async void set_music_folder_async () {
325 }360 try {
361 new Thread<void*>.try (null, set_music_thread_function);
362 }
363 catch(Error err) {
364 warning("Could not create thread to set music folder: %s", err.message);
326 }365 }
327 }366 }
328 367
329 public void* set_music_thread_function () {368 private void* set_music_thread_function () {
330 var music_folder = GLib.File.new_for_path(settings.getMusicFolder());369 var music_folder = GLib.File.new_for_path(settings.getMusicFolder());
331 370
332 fo.resetProgress(0);371 fo.resetProgress(0);
333 fo.start_import(FileOperator.ImportType.SET);372 fo.start_import(FileOperator.ImportType.SET);
334 fo.import_file = music_folder;373 fo.import_file = music_folder;
335 Thread.create<void*>(fo.queue_music_files_bootstrap_thread, false);374
375 fo.queue_music_files_bootstrap_async ();
376
336 Timeout.add(100, doProgressNotificationWithTimeout);377 Timeout.add(100, doProgressNotificationWithTimeout);
337 378
338 return null;379 return null;
339 }380 }
340 381
341 public void add_files_to_library(LinkedList<string> files) {382 public async void add_files_to_library_async (LinkedList<string> files) {
342 if(start_file_operations(_("Adding files to library...")) && files.size > 0) {383 if(start_file_operations(_("Adding files to library...")) && files.size > 0) {
343 temp_add_files = files;384 temp_add_files = files;
344 385
345 try {386 try {
346 Thread.create<void*>(add_files_to_library_thread, false);387 new Thread<void*>.try (null, add_files_to_library_thread);
347 }388 }
348 catch(GLib.Error err) {389 catch (Error err) {
349 warning ("Could not create thread to add music files: %s\n", err.message);390 warning ("Could not create thread to add music files: %s", err.message);
350 }391 }
351 }392 }
352 }393 }
353 394
354 public void* add_files_to_library_thread () {395 private void* add_files_to_library_thread () {
396 // FIXME: we need a better API for doing this kind of stuff.
397 // FileOperator could emit some signals, and we could
398 // track them here.
355 fo.resetProgress(temp_add_files.size - 1);399 fo.resetProgress(temp_add_files.size - 1);
356 Timeout.add(100, doProgressNotificationWithTimeout);400 Timeout.add(100, doProgressNotificationWithTimeout);
357 fo.import_files(temp_add_files, FileOperator.ImportType.IMPORT);401 fo.import_files(temp_add_files, FileOperator.ImportType.IMPORT);
358 402
359 return null;403 return null;
360 }404 }
361 405
362 public void add_folder_to_library(LinkedList<File> folders) {406 public async void add_folder_to_library_async (LinkedList<File> folders) {
363 string oper = "";407 string oper = "";
364 if(folders.size == 1) {408 if(folders.size == 1) {
365 oper = _("Adding music from %s to library...").printf("<b>" + Markup.escape_text(folders.get(0).get_path()) + "</b>");409 oper = _("Adding music from %s to library...").printf("<b>" + Markup.escape_text(folders.get(0).get_path()) + "</b>");
@@ -372,15 +416,15 @@
372 temp_add_folders = folders;416 temp_add_folders = folders;
373 417
374 try {418 try {
375 Thread.create<void*>(add_folder_to_library_thread, false);419 new Thread<void*>.try (null, add_folder_to_library_thread);
376 }420 }
377 catch(GLib.Error err) {421 catch (Error err) {
378 warning ("Could not create thread to add music folder: %s\n", err.message);422 warning ("Could not create thread to add music folder: %s", err.message);
379 }423 }
380 }424 }
381 }425 }
382 426
383 public void* add_folder_to_library_thread () {427 private void* add_folder_to_library_thread () {
384 var files = new LinkedList<string>();428 var files = new LinkedList<string>();
385 int items = 0;429 int items = 0;
386 430
@@ -395,18 +439,18 @@
395 return null;439 return null;
396 }440 }
397 441
398 public void rescan_music_folder() {442 public async void rescan_music_folder_async () {
399 if(start_file_operations(_("Rescanning music folder for changes..."))) {443 if(start_file_operations(_("Rescanning music folder for changes..."))) {
400 try {444 try {
401 Thread.create<void*>(rescan_music_thread_function, false);445 new Thread<void*>.try (null, rescan_music_thread_function);
402 }446 }
403 catch(GLib.Error err) {447 catch (Error err) {
404 warning ("Could not create thread to rescan music folder: %s\n", err.message);448 warning ("Could not create thread to rescan music folder: %s", err.message);
405 }449 }
406 }450 }
407 }451 }
408 452
409 public void* rescan_music_thread_function () {453 private void* rescan_music_thread_function () {
410 HashMap<string, Media> paths = new HashMap<string, Media>();454 HashMap<string, Media> paths = new HashMap<string, Media>();
411 LinkedList<Media> to_remove = new LinkedList<Media>();455 LinkedList<Media> to_remove = new LinkedList<Media>();
412 LinkedList<string> to_import = new LinkedList<string>();456 LinkedList<string> to_import = new LinkedList<string>();
@@ -456,30 +500,35 @@
456 return null;500 return null;
457 }501 }
458 502
459 public void recheck_files_not_found() {503 public void recheck_files_not_found_async () {
460 try {504 try {
461 Thread.create<void*>(recheck_files_not_found_thread, false);505 new Thread<void*>.try (null, recheck_files_not_found_thread);
462 }506 }
463 catch(GLib.Error err) {507 catch (Error err) {
464 warning ("Could not create thread to check file locations: %s\n", err.message);508 warning ("Could not create thread to check file locations: %s", err.message);
465 }509 }
466 }510 }
467 511
468 public void* recheck_files_not_found_thread () {512 private void* recheck_files_not_found_thread () {
469 Media[] cache_media;513 Media[] cache_media;
470 var not_found = new LinkedList<Media>();514 var not_found = new LinkedList<Media>();
471 var found = new LinkedList<Media>(); // files that location were unknown but now are found515 var found = new LinkedList<Media>(); // files that location were unknown but now are found
516
517 // FIXME (BeatBox 0.7+)
518 // At this point, a signal should be emmited
519 // to let LibraryWindow know what's happening
520 // under the hood.
521 // UI code doesn't belong here.
472 var not_found_pix = Icons.PROCESS_ERROR.render(IconSize.MENU, ((ViewWrapper)lw.sideTree.getWidget(lw.sideTree.library_music_iter)).list_view.get_style_context());522 var not_found_pix = Icons.PROCESS_ERROR.render(IconSize.MENU, ((ViewWrapper)lw.sideTree.getWidget(lw.sideTree.library_music_iter)).list_view.get_style_context());
473 523
474 _media_lock.lock();
475 cache_media = _media.values.to_array();524 cache_media = _media.values.to_array();
476 _media_lock.unlock();
477 525
478 for(int i = 0; i < cache_media.length; ++i) {526 for(int i = 0; i < cache_media.length; ++i) {
479 var m = cache_media[i];527 var m = cache_media[i];
480 if(m.mediatype == MediaType.STATION || 528 if(m.mediatype == MediaType.STATION ||
481 (m.mediatype == MediaType.PODCAST && m.uri.has_prefix("http:/"))) {529 (m.mediatype == MediaType.PODCAST && m.uri.has_prefix("http:/"))) {
482 // don't try to find this530 // don't try to find this
531 warning ("Found station or podcast with uri prefix 'http:/'");
483 }532 }
484 else {533 else {
485 if(File.new_for_uri(m.uri).query_exists() && m.location_unknown) {534 if(File.new_for_uri(m.uri).query_exists() && m.location_unknown) {
@@ -499,6 +548,12 @@
499 if(not_found.size > 0) {548 if(not_found.size > 0) {
500 warning("Some media files could not be found and are being marked as such.\n");549 warning("Some media files could not be found and are being marked as such.\n");
501 update_medias(not_found, false, false, true);550 update_medias(not_found, false, false, true);
551
552 // FIXME (BeatBox 0.7+)
553 // At this point, a signal should be emmited
554 // to let LibraryWindow know what's happening
555 // under the hood.
556 // UI code doesn't belong here.
502 foreach(var m in not_found) {557 foreach(var m in not_found) {
503 lw.media_not_found(m.rowid);558 lw.media_not_found(m.rowid);
504 }559 }
@@ -506,6 +561,12 @@
506 if(found.size > 0) {561 if(found.size > 0) {
507 warning("Some media files whose location were unknown were found.\n");562 warning("Some media files whose location were unknown were found.\n");
508 update_medias(found, false, false, true);563 update_medias(found, false, false, true);
564
565 // FIXME (BeatBox 0.7+)
566 // At this point, a signal should be emmited
567 // to let LibraryWindow know what's happening
568 // under the hood.
569 // UI code doesn't belong here.
509 foreach(var m in found) {570 foreach(var m in found) {
510 lw.media_found(m.rowid);571 lw.media_found(m.rowid);
511 }572 }
@@ -536,15 +597,13 @@
536 597
537 public Playlist? playlist_from_name(string name) {598 public Playlist? playlist_from_name(string name) {
538 Playlist? rv = null;599 Playlist? rv = null;
539 600
540 _playlists_lock.lock();
541 foreach(var p in _playlists.values) {601 foreach(var p in _playlists.values) {
542 if(p.get_name() == name) {602 if(p.get_name() == name) {
543 rv = p;603 rv = p;
544 break;604 break;
545 }605 }
546 }606 }
547 _playlists_lock.unlock();
548 607
549 return rv;608 return rv;
550 }609 }
@@ -556,10 +615,10 @@
556 top_index = i;615 top_index = i;
557 }616 }
558 617
559 _playlists_lock.lock();618 lock (_playlists) {
560 p.set_rowid(top_index + 1);619 p.set_rowid(top_index + 1);
561 _playlists.set(p.get_rowid(), p);620 _playlists.set(p.get_rowid(), p);
562 _playlists_lock.unlock();621 }
563 622
564 playlist_added(p);623 playlist_added(p);
565 dbm.add_playlist(p);624 dbm.add_playlist(p);
@@ -570,9 +629,9 @@
570 public void remove_playlist(int id) {629 public void remove_playlist(int id) {
571 Playlist removed;630 Playlist removed;
572 631
573 _playlists_lock.lock();632 lock (_playlists) {
574 _playlists.unset(id, out removed);633 _playlists.unset(id, out removed);
575 _playlists_lock.unlock();634 }
576 635
577 playlist_removed(removed);636 playlist_removed(removed);
578 dbu.removeItem(removed);637 dbu.removeItem(removed);
@@ -598,29 +657,29 @@
598 public SmartPlaylist? smart_playlist_from_name(string name) {657 public SmartPlaylist? smart_playlist_from_name(string name) {
599 SmartPlaylist? rv = null;658 SmartPlaylist? rv = null;
600 659
601 _smart_playlists_lock.lock();660 lock (_smart_playlists) {
602 foreach(var p in _smart_playlists.values) {661 foreach(var p in _smart_playlists.values) {
603 if(p.get_name() == name) {662 if(p.get_name() == name) {
604 rv = p;663 rv = p;
605 break;664 break;
606 } 665 }
666 }
607 }667 }
608 _smart_playlists_lock.unlock();668
609
610 return rv;669 return rv;
611 }670 }
612 671
613 public void save_smart_playlists() {672 public void save_smart_playlists() {
614 try {673 try {
615 Thread.create<void*>( () => { 674 new Thread<void*>.try (null, () => {
616 _smart_playlists_lock.lock();675 lock (_smart_playlists) {
617 dbm.save_smart_playlists(_smart_playlists.values);676 dbm.save_smart_playlists(_smart_playlists.values);
618 _smart_playlists_lock.unlock();677 }
619 678
620 return null; 679 return null;
621 }, false);680 });
622 }681 }
623 catch(GLib.Error err) {682 catch(Error err) {
624 warning ("Could not create thread to save smart playlists: %s\n", err.message);683 warning ("Could not create thread to save smart playlists: %s\n", err.message);
625 }684 }
626 }685 }
@@ -632,10 +691,10 @@
632 top_index = i;691 top_index = i;
633 }692 }
634 693
635 _smart_playlists_lock.lock();694 lock (_smart_playlists) {
636 p.set_rowid(top_index + 1);// + 1 for 1-based db695 p.set_rowid(top_index + 1);// + 1 for 1-based db
637 _smart_playlists.set(p.get_rowid(), p);696 _smart_playlists.set(p.get_rowid(), p);
638 _smart_playlists_lock.unlock();697 }
639 698
640 playlist_added(p);699 playlist_added(p);
641 save_smart_playlists();700 save_smart_playlists();
@@ -646,9 +705,9 @@
646 public void remove_smart_playlist(int id) {705 public void remove_smart_playlist(int id) {
647 SmartPlaylist removed;706 SmartPlaylist removed;
648 707
649 _smart_playlists_lock.lock();708 lock (_smart_playlists) {
650 _smart_playlists.unset(id, out removed);709 _smart_playlists.unset(id, out removed);
651 _smart_playlists_lock.unlock();710 }
652 711
653 playlist_removed(removed);712 playlist_removed(removed);
654 dbu.removeItem(removed);713 dbu.removeItem(removed);
@@ -660,7 +719,6 @@
660 719
661 // We really only want to clear the songs that are permanent and on the file system720 // We really only want to clear the songs that are permanent and on the file system
662 // Dont clear podcasts that link to a url, device media, temporary media, previews, songs721 // Dont clear podcasts that link to a url, device media, temporary media, previews, songs
663 _media_lock.lock();
664 var unset = new LinkedList<Media>();//HashMap<int, Media>();722 var unset = new LinkedList<Media>();//HashMap<int, Media>();
665 var unset_ids = new LinkedList<int>();723 var unset_ids = new LinkedList<int>();
666 foreach(int i in _media.keys) {724 foreach(int i in _media.keys) {
@@ -676,26 +734,39 @@
676 }734 }
677 }735 }
678 }736 }
679 737
680 foreach(Media s in unset) {738 lock (_media) {
681 _media.unset(s.rowid);739 foreach(Media s in unset) {
682 740 _media.unset(s.rowid);
683 if(s.mediatype == MediaType.SONG)741
684 _songs.unset(s.rowid);742 if(s.mediatype == MediaType.SONG) {
685 else if(s.mediatype == MediaType.PODCAST)743 lock (_songs) {
686 _podcasts.unset(s.rowid);744 _songs.unset (s.rowid);
687 else if(s.mediatype == MediaType.AUDIOBOOK)745 }
688 _audiobooks.unset(s.rowid);746 }
689 else if(s.mediatype == MediaType.STATION)747 else if(s.mediatype == MediaType.PODCAST) {
690 _stations.unset(s.rowid);748 lock (_podcasts) {
691 }749 _podcasts.unset (s.rowid);
692 _media_lock.unlock();750 }
693 751 }
694 _playlists_lock.lock();752 else if(s.mediatype == MediaType.AUDIOBOOK) {
695 foreach(var p in _playlists.values) {753 lock (_audiobooks) {
696 p.removeMedias(unset_ids);754 _audiobooks.unset(s.rowid);
697 }755 }
698 _playlists_lock.unlock();756 }
757 else if(s.mediatype == MediaType.STATION) {
758 lock (_stations) {
759 _stations.unset(s.rowid);
760 }
761 }
762 }
763 }
764
765 lock (_playlists) {
766 foreach(var p in _playlists.values) {
767 p.removeMedias(unset_ids);
768 }
769 }
699 770
700 dbm.clear_medias();771 dbm.clear_medias();
701 dbm.add_medias(_media.values);772 dbm.add_medias(_media.values);
@@ -790,17 +861,17 @@
790 dbu.update_medias(updates);861 dbu.update_medias(updates);
791 }862 }
792863
793 public void save_media() {864 public async void save_media_async () {
794 try {865 try {
795 Thread.create<void*>( () => { 866 new Thread<void*>.try (null, () => {
796 _media_lock.lock();867 lock (_media) {
797 dbm.update_medias(_media.values);868 dbm.update_medias (_media.values);
798 _media_lock.unlock();869 }
799 870
800 return null; 871 return null;
801 }, false);872 });
802 }873 }
803 catch(GLib.Error err) {874 catch(Error err) {
804 warning ("Could not create thread to save media: %s\n", err.message);875 warning ("Could not create thread to save media: %s\n", err.message);
805 }876 }
806 }877 }
@@ -816,13 +887,13 @@
816 public Media? match_media_to_list(Media m, Collection<Media> to_match) {887 public Media? match_media_to_list(Media m, Collection<Media> to_match) {
817 Media? rv = null;888 Media? rv = null;
818 889
819 _media_lock.lock();890 lock (_media) {
820 foreach(var test in to_match) {891 foreach(var test in to_match) {
821 if(!test.isTemporary && test != m && test.title.down() == m.title.down() && test.artist.down() == m.artist.down()) {892 if(!test.isTemporary && test != m && test.title.down() == m.title.down() && test.artist.down() == m.artist.down()) {
822 rv = test;893 rv = test;
894 }
823 }895 }
824 }896 }
825 _media_lock.unlock();
826 897
827 return rv;898 return rv;
828 }899 }
@@ -832,10 +903,8 @@
832 rv.title = title;903 rv.title = title;
833 rv.artist = artist;904 rv.artist = artist;
834 Media[] searchable;905 Media[] searchable;
835 906
836 _media_lock.lock();
837 searchable = _media.values.to_array();907 searchable = _media.values.to_array();
838 _media_lock.unlock();
839 908
840 for(int i = 0; i < searchable.length; ++i) {909 for(int i = 0; i < searchable.length; ++i) {
841 Media s = searchable[i];910 Media s = searchable[i];
@@ -848,10 +917,8 @@
848 917
849 public void medias_from_name(Collection<Media> tests, ref LinkedList<int> found, ref LinkedList<Media> not_found) {918 public void medias_from_name(Collection<Media> tests, ref LinkedList<int> found, ref LinkedList<Media> not_found) {
850 Media[] searchable;919 Media[] searchable;
851 920
852 _media_lock.lock();
853 searchable = _media.values.to_array();921 searchable = _media.values.to_array();
854 _media_lock.unlock();
855 922
856 foreach(Media test in tests) {923 foreach(Media test in tests) {
857 bool found_match = false;924 bool found_match = false;
@@ -872,15 +939,13 @@
872 public Media? media_from_file(string uri) {939 public Media? media_from_file(string uri) {
873 Media? rv = null;940 Media? rv = null;
874 941
875 _media_lock.lock();
876 foreach(Media s in _media.values) {942 foreach(Media s in _media.values) {
877 if(s.uri == uri) {943 if(s.uri == uri) {
878 rv = s;944 rv = s;
879 break;945 break;
880 }946 }
881 }947 }
882 _media_lock.unlock();948
883
884 return rv;949 return rv;
885 }950 }
886951
@@ -997,31 +1062,44 @@
997 return;1062 return;
998 1063
999 int top_index = 0;1064 int top_index = 0;
1000 _media_lock.lock();1065
1001 foreach(int i in _media.keys) {1066 foreach(int i in _media.keys) {
1002 if(i > top_index)1067 if(i > top_index)
1003 top_index = i;1068 top_index = i;
1004 }1069 }
1005 1070
1006 var added = new LinkedList<int>();1071 var added = new LinkedList<int>();
1007 foreach(var s in new_media) {1072 lock (_media) {
1008 if(s.rowid == 0)1073 foreach(var s in new_media) {
1009 s.rowid = ++top_index;1074 if(s.rowid == 0)
1010 1075 s.rowid = ++top_index;
1011 added.add(s.rowid);1076
1012 1077 added.add(s.rowid);
1013 _media.set(s.rowid, s);1078
1014 1079 _media.set(s.rowid, s);
1015 if(s.mediatype == MediaType.SONG)1080
1016 _songs.set(s.rowid, s);1081 if(s.mediatype == MediaType.SONG) {
1017 else if(s.mediatype == MediaType.PODCAST)1082 lock (_songs) {
1018 _podcasts.set(s.rowid, s);1083 _audiobooks.set (s.rowid, s);
1019 else if(s.mediatype == MediaType.AUDIOBOOK)1084 }
1020 _audiobooks.set(s.rowid, s);1085 }
1021 else if(s.mediatype == MediaType.STATION)1086 else if(s.mediatype == MediaType.PODCAST) {
1022 _stations.set(s.rowid, s);1087 lock (_podcasts) {
1088 _podcasts.set (s.rowid, s);
1089 }
1090 }
1091 else if(s.mediatype == MediaType.AUDIOBOOK) {
1092 lock (_audiobooks) {
1093 _audiobooks.set (s.rowid, s);
1094 }
1095 }
1096 else if(s.mediatype == MediaType.STATION) {
1097 lock (_stations) {
1098 _stations.set (s.rowid, s);
1099 }
1100 }
1101 }
1023 }1102 }
1024 _media_lock.unlock();
1025 1103
1026 if(new_media.size > 0) {1104 if(new_media.size > 0) {
1027 dbm.add_medias(new_media);1105 dbm.add_medias(new_media);
@@ -1055,30 +1133,45 @@
1055 // call now so that lm.media_from_id() still works1133 // call now so that lm.media_from_id() still works
1056 medias_removed(removedIds);1134 medias_removed(removedIds);
1057 1135
1058 _media_lock.lock();1136 lock (_media) {
1059 foreach(Media s in toRemove) {1137 foreach(Media s in toRemove) {
1060 _media.unset(s.rowid);1138 _media.unset(s.rowid);
1061 1139
1062 if(s.mediatype == MediaType.SONG)1140 if(s.mediatype == MediaType.SONG) {
1063 _songs.unset(s.rowid);1141 lock (_songs) {
1064 else if(s.mediatype == MediaType.PODCAST)1142 _songs.unset (s.rowid);
1065 _podcasts.unset(s.rowid);1143 }
1066 else if(s.mediatype == MediaType.AUDIOBOOK)1144 }
1067 _audiobooks.unset(s.rowid);1145 else if(s.mediatype == MediaType.PODCAST) {
1068 else if(s.mediatype == MediaType.STATION)1146 lock (_podcasts) {
1069 _stations.unset(s.rowid);1147 _podcasts.unset (s.rowid);
1148 }
1149 }
1150 else if(s.mediatype == MediaType.AUDIOBOOK) {
1151 lock (_audiobooks) {
1152 _audiobooks.unset(s.rowid);
1153 }
1154 }
1155 else if(s.mediatype == MediaType.STATION) {
1156 lock (_stations) {
1157 _stations.unset(s.rowid);
1158 }
1159 }
1160 }
1070 }1161 }
1071 _media_lock.unlock();1162
1072
1073 _playlists_lock.lock();
1074 foreach(var p in _playlists.values) {1163 foreach(var p in _playlists.values) {
1075 p.removeMedias(toRemove);1164 p.removeMedias(toRemove);
1076 }1165 }
1077 _playlists_lock.unlock();
1078 1166
1079 if(_media.size == 0)1167 if(_media.size == 0)
1080 settings.setMusicFolder(Environment.get_user_special_dir(UserDirectory.MUSIC));1168 settings.setMusicFolder(Environment.get_user_special_dir(UserDirectory.MUSIC));
1081 1169
1170 // FIXME (BeatBox 0.7+)
1171 // At this point, a signal should be emmited
1172 // to let LibraryWindow know what's happening
1173 // under the hood.
1174 // UI code doesn't belong here.
1082 lw.update_sensitivities();1175 lw.update_sensitivities();
1083 }1176 }
1084 1177
@@ -1340,6 +1433,12 @@
1340 if(File.new_for_uri(m.uri).query_exists()) { // we did not know location, but it has re-appearred1433 if(File.new_for_uri(m.uri).query_exists()) { // we did not know location, but it has re-appearred
1341 m.location_unknown = false;1434 m.location_unknown = false;
1342 m.unique_status_image = null;1435 m.unique_status_image = null;
1436
1437 // FIXME (BeatBox 0.7+)
1438 // At this point, a signal should be emmited
1439 // to let LibraryWindow know what's happening
1440 // under the hood.
1441 // UI code doesn't belong here.
1343 lw.media_found(m.rowid);1442 lw.media_found(m.rowid);
1344 }1443 }
1345 else { // to avoid infinite loop with repeat on, don't try to play next again1444 else { // to avoid infinite loop with repeat on, don't try to play next again
@@ -1351,9 +1450,16 @@
1351 // check that the file exists1450 // check that the file exists
1352 var music_folder_uri = File.new_for_path(settings.getMusicFolder()).get_uri();1451 var music_folder_uri = File.new_for_path(settings.getMusicFolder()).get_uri();
1353 if((settings.getMusicFolder() != "" && m.uri.has_prefix(music_folder_uri) && !GLib.File.new_for_uri(m.uri).query_exists())) {1452 if((settings.getMusicFolder() != "" && m.uri.has_prefix(music_folder_uri) && !GLib.File.new_for_uri(m.uri).query_exists())) {
1453
1454 // FIXME (BeatBox 0.7+)
1455 // At this point, a signal should be emmited
1456 // to let LibraryWindow know what's happening
1457 // under the hood.
1458 // UI code doesn't belong here.
1354 m.unique_status_image = Icons.PROCESS_ERROR.render(IconSize.MENU, ((ViewWrapper)lw.sideTree.getWidget(lw.sideTree.library_music_iter)).list_view.get_style_context());1459 m.unique_status_image = Icons.PROCESS_ERROR.render(IconSize.MENU, ((ViewWrapper)lw.sideTree.getWidget(lw.sideTree.library_music_iter)).list_view.get_style_context());
1355 m.location_unknown = true;1460 m.location_unknown = true;
1356 lw.media_not_found(id);1461 lw.media_not_found(id);
1462
1357 getNext(true);1463 getNext(true);
1358 return;1464 return;
1359 }1465 }
@@ -1392,10 +1498,11 @@
1392 */1498 */
1393 Timeout.add(1000, () => {1499 Timeout.add(1000, () => {
1394 if(media_info.media == m) {1500 if(media_info.media == m) {
1501 // FIXME (BeatBox 0.7+) : Move to playback manager
1395 try {1502 try {
1396 Thread.create<void*>(change_gains_thread, false);1503 new Thread<void*>.try (null, change_gains_thread);
1397 }1504 }
1398 catch(GLib.Error err) {1505 catch(Error err) {
1399 warning("Could not create thread to change gains: %s\n", err.message);1506 warning("Could not create thread to change gains: %s\n", err.message);
1400 }1507 }
1401 1508
@@ -1417,6 +1524,9 @@
1417 }1524 }
1418 1525
1419 // FIXME: Slow. Don't read eq. presets from settings.1526 // FIXME: Slow. Don't read eq. presets from settings.
1527 // FIXME (BeatBox 0.7+)
1528 // Deprecate in favor of PlaybackManager. Currently, this is public
1529 // because EqualizerWindow needs it
1420 public void* change_gains_thread () {1530 public void* change_gains_thread () {
1421 if(settings.getEqualizerEnabled()) {1531 if(settings.getEqualizerEnabled()) {
1422 bool automatic_enabled = settings.getAutoSwitchPreset();1532 bool automatic_enabled = settings.getAutoSwitchPreset();
@@ -1479,7 +1589,12 @@
1479 temps.add(s);1589 temps.add(s);
1480 1590
1481 playMedia(s, false);1591 playMedia(s, false);
1482 1592
1593 // FIXME (BeatBox 0.7+)
1594 // At this point, a signal should be emmited
1595 // to let LibraryWindow know what's happening
1596 // under the hood.
1597 // UI code doesn't belong here.
1483 if(!playing) {1598 if(!playing) {
1484 lw.playClicked();1599 lw.playClicked();
1485 }1600 }
@@ -1526,19 +1641,26 @@
1526 set_album_art(_media.get(id), pix, emit);1641 set_album_art(_media.get(id), pix, emit);
1527 }1642 }
1528 }1643 }
1529 1644
1645 public async void fetch_image_cache_async () {
1646 try {
1647 new Thread<void*>.try (null, fetch_image_thread_function);
1648 } catch(Error err) {
1649 warning ("Could not create thread to load media pixbuf's: %s \n", err.message);
1650 }
1651 }
1652
1530 /* at the start, load all the pixbufs */1653 /* at the start, load all the pixbufs */
1531 public void* fetch_thread_function () {1654 private void* fetch_image_thread_function () {
1532 if(in_fetch_thread)1655 if(in_fetch_thread)
1533 return null;1656 return null;
1534 1657
1535 in_fetch_thread = true;1658 in_fetch_thread = true;
1536 //GStreamerTagger tagger = new GStreamerTagger(this);1659 //GStreamerTagger tagger = new GStreamerTagger(this);
1537 LinkedList<Media> medias = new LinkedList<Media>();1660 LinkedList<Media> medias = new LinkedList<Media>();
1538 _media_lock.lock();1661
1539 foreach(var m in _media.values)1662 foreach(var m in _media.values)
1540 medias.add(m);1663 medias.add(m);
1541 _media_lock.unlock();
1542 1664
1543 // first get from file1665 // first get from file
1544 foreach(var s in medias) {1666 foreach(var s in medias) {
@@ -1658,13 +1780,12 @@
1658 if(emit) {1780 if(emit) {
1659 Gee.LinkedList<Media> updated_medias = new Gee.LinkedList<Media>();1781 Gee.LinkedList<Media> updated_medias = new Gee.LinkedList<Media>();
1660 1782
1661 _media_lock.lock();1783
1662 foreach(int i in media_ids()) {1784 foreach(int i in media_ids()) {
1663 if(media_from_id(i).album_artist == s.album_artist && media_from_id(i).album == s.album) {1785 if(media_from_id(i).album_artist == s.album_artist && media_from_id(i).album == s.album) {
1664 updated_medias.add(media_from_id(i));1786 updated_medias.add(media_from_id(i));
1665 }1787 }
1666 }1788 }
1667 _media_lock.unlock();
1668 1789
1669 update_medias(updated_medias, false, false, true);1790 update_medias(updated_medias, false, false, true);
1670 }1791 }
@@ -1677,7 +1798,14 @@
1677 1798
1678 progress_notification(message, 0.0);1799 progress_notification(message, 0.0);
1679 _doing_file_operations = true;1800 _doing_file_operations = true;
1801
1802 // FIXME (BeatBox 0.7+)
1803 // At this point, a signal should be emmited
1804 // to let LibraryWindow know what's happening
1805 // under the hood.
1806 // UI code doesn't belong here.
1680 lw.update_sensitivities();1807 lw.update_sensitivities();
1808
1681 file_operations_started();1809 file_operations_started();
1682 return true;1810 return true;
1683 }1811 }
@@ -1694,15 +1822,16 @@
1694 pm.find_new_podcasts();1822 pm.find_new_podcasts();
1695 }1823 }
1696 else {1824 else {
1697 try {1825 fetch_image_cache_async ();
1698 Thread.create<void*>(fetch_thread_function, false);1826
1699 }1827 // FIXME (BeatBox 0.7+)
1700 catch(GLib.ThreadError err) {1828 // At this point, a signal should be emmited
1701 warning("Could not create thread to load media pixbuf's: %s \n", err.message);1829 // to let LibraryWindow know what's happening
1702 }1830 // under the hood.
1703 1831 // UI code doesn't belong here.
1704 lw.update_sensitivities();1832 lw.update_sensitivities();
1705 lw.updateInfoLabel();1833 lw.updateInfoLabel();
1834
1706 file_operations_done();1835 file_operations_done();
1707 }1836 }
1708 }1837 }
17091838
=== modified file 'src/Core/LibraryWindow.vala'
--- src/Core/LibraryWindow.vala 2012-06-30 20:55:57 +0000
+++ src/Core/LibraryWindow.vala 2012-07-03 06:49:24 +0000
@@ -219,8 +219,8 @@
219 this.window_position = Gtk.WindowPosition.CENTER;219 this.window_position = Gtk.WindowPosition.CENTER;
220220
221 // set the size based on saved settings221 // set the size based on saved settings
222 this.set_default_size (lm.settings.getWindowWidth(), lm.settings.getWindowHeight());222 this.set_default_size (settings.getWindowWidth(), settings.getWindowHeight());
223 if(lm.settings.getWindowMaximized()) {223 if(settings.getWindowMaximized()) {
224 window_maximized = true;224 window_maximized = true;
225 this.maximize();225 this.maximize();
226 }226 }
@@ -282,7 +282,7 @@
282 viewSelector.append(Icons.VIEW_DETAILS.render_image (IconSize.MENU));282 viewSelector.append(Icons.VIEW_DETAILS.render_image (IconSize.MENU));
283 viewSelector.append(Icons.VIEW_ICONS.render_image (IconSize.MENU));283 viewSelector.append(Icons.VIEW_ICONS.render_image (IconSize.MENU));
284 viewSelector.valign = showSongInfo.valign = Gtk.Align.CENTER;284 viewSelector.valign = showSongInfo.valign = Gtk.Align.CENTER;
285 viewSelector.selected = lm.settings.getViewMode();285 viewSelector.selected = settings.getViewMode();
286 286
287 viewSelectorBin.margin_left = 12;287 viewSelectorBin.margin_left = 12;
288 viewSelectorBin.margin_right = 12;288 viewSelectorBin.margin_right = 12;
@@ -363,12 +363,12 @@
363 repeatChooser.appendItem(_("Album"));363 repeatChooser.appendItem(_("Album"));
364 repeatChooser.appendItem(_("Artist"));364 repeatChooser.appendItem(_("Artist"));
365 repeatChooser.appendItem(_("All"));365 repeatChooser.appendItem(_("All"));
366 repeatChooser.setOption(lm.settings.getRepeatMode());366 repeatChooser.setOption(settings.getRepeatMode());
367 repeatChooser.setTooltip (_("Disable Repeat"), _("Enable Repeat"));367 repeatChooser.setTooltip (_("Disable Repeat"), _("Enable Repeat"));
368368
369 shuffleChooser.appendItem(_("Off"));369 shuffleChooser.appendItem(_("Off"));
370 shuffleChooser.appendItem(_("All"));370 shuffleChooser.appendItem(_("All"));
371 shuffleChooser.setOption(lm.settings.getShuffleMode());371 shuffleChooser.setOption(settings.getShuffleMode());
372 shuffleChooser.setTooltip (_("Turn off Shuffle"), _("Turn on Shuffle"));372 shuffleChooser.setTooltip (_("Turn off Shuffle"), _("Turn on Shuffle"));
373 373
374 newPlaylistMenu = new Gtk.Menu();374 newPlaylistMenu = new Gtk.Menu();
@@ -445,7 +445,7 @@
445 445
446 show_all();446 show_all();
447 infoBar.hide();447 infoBar.hide();
448 searchField.set_text(lm.settings.getSearchString());448 searchField.set_text(settings.getSearchString());
449 update_sensitivities();449 update_sensitivities();
450 hide_video_mode();450 hide_video_mode();
451 }451 }
@@ -713,7 +713,7 @@
713 if(!initializationFinished)713 if(!initializationFinished)
714 return;714 return;
715715
716 bool folderSet = (lm.settings.getMusicFolder() != "");716 bool folderSet = (settings.getMusicFolder() != "");
717 bool haveMedias = lm.media_count() > 0;717 bool haveMedias = lm.media_count() > 0;
718 bool doingOps = lm.doing_file_operations();718 bool doingOps = lm.doing_file_operations();
719 bool mediaActive = lm.media_active;719 bool mediaActive = lm.media_active;
@@ -811,7 +811,7 @@
811 811
812 var label = "";812 var label = "";
813 if(lm.fo.import_type == FileOperator.ImportType.SET)813 if(lm.fo.import_type == FileOperator.ImportType.SET)
814 label = _("Importing music from") + " <b>" + Markup.escape_text(lm.settings.getMusicFolder()) + "</b>...";814 label = _("Importing music from") + " <b>" + Markup.escape_text(settings.getMusicFolder()) + "</b>...";
815 else if(lm.fo.import_type == FileOperator.ImportType.RESCAN)815 else if(lm.fo.import_type == FileOperator.ImportType.RESCAN)
816 label = _("Rescanning music folder for changes...");816 label = _("Rescanning music folder for changes...");
817 else if(lm.fo.import_type == FileOperator.ImportType.IMPORT || 817 else if(lm.fo.import_type == FileOperator.ImportType.IMPORT ||
@@ -1005,7 +1005,7 @@
1005 void on_quit() {1005 void on_quit() {
1006 // Stop listening to window state changes1006 // Stop listening to window state changes
1007 this.window_state_event.disconnect(window_state_changed);1007 this.window_state_event.disconnect(window_state_changed);
1008 lm.settings.setLastMediaPosition((int)((double)lm.player.getPosition()/1000000000));1008 settings.setLastMediaPosition((int)((double)lm.player.getPosition()/1000000000));
1009 if(lm.media_active) {1009 if(lm.media_active) {
1010 lm.media_info.media.resume_pos = (int)((double)lm.player.getPosition()/1000000000);1010 lm.media_info.media.resume_pos = (int)((double)lm.player.getPosition()/1000000000);
1011 lm.update_media(lm.media_info.media, false, false, false);1011 lm.update_media(lm.media_info.media, false, false, false);
@@ -1055,13 +1055,13 @@
1055 }1055 }
1056 }1056 }
1057 1057
1058 if(final_folders.size > 0 && GLib.File.new_for_path(lm.settings.getMusicFolder()).query_exists()) {1058 if(final_folders.size > 0 && GLib.File.new_for_path(settings.getMusicFolder()).query_exists()) {
1059 topDisplay.show_progressbar();1059 topDisplay.show_progressbar();
10601060
1061 lm.add_folder_to_library(final_folders);1061 lm.add_folder_to_library_async (final_folders);
1062 update_sensitivities();1062 update_sensitivities();
1063 }1063 }
1064 else if(!GLib.File.new_for_path(lm.settings.getMusicFolder()).query_exists()) {1064 else if(!GLib.File.new_for_path(settings.getMusicFolder()).query_exists()) {
1065 doAlert(_("Import Failed"), _("Your library's music folder could not be found. Please make sure your music folder is mounted before importing."));1065 doAlert(_("Import Failed"), _("Your library's music folder could not be found. Please make sure your music folder is mounted before importing."));
1066 }1066 }
1067 }1067 }
@@ -1080,7 +1080,7 @@
1080 topDisplay.set_label_markup("<b>" + _("Rescanning music folder for changes") + "</b>");1080 topDisplay.set_label_markup("<b>" + _("Rescanning music folder for changes") + "</b>");
1081 topDisplay.show_progressbar();1081 topDisplay.show_progressbar();
10821082
1083 lm.rescan_music_folder();1083 lm.rescan_music_folder_async ();
1084 update_sensitivities();1084 update_sensitivities();
1085 }1085 }
1086 else {1086 else {
@@ -1136,7 +1136,7 @@
1136 //searchField.set_text("up");1136 //searchField.set_text("up");
11371137
1138 if(not_imported.size > 0) {1138 if(not_imported.size > 0) {
1139 NotImportedDialog nim = new NotImportedDialog(this, not_imported, lm.settings.getMusicFolder());1139 NotImportedDialog nim = new NotImportedDialog(this, not_imported, settings.getMusicFolder());
1140 nim.show();1140 nim.show();
1141 }1141 }
11421142
@@ -1388,7 +1388,7 @@
1388 files_dragged.add(File.new_for_uri(uri).get_path());1388 files_dragged.add(File.new_for_uri(uri).get_path());
1389 }1389 }
13901390
1391 lm.add_files_to_library(files_dragged);1391 lm.add_files_to_library_async (files_dragged);
1392 }1392 }
13931393
1394 public void doAlert(string title, string message) {1394 public void doAlert(string title, string message) {
13951395
=== modified file 'src/Core/PodcastManager.vala'
--- src/Core/PodcastManager.vala 2012-06-13 23:54:06 +0000
+++ src/Core/PodcastManager.vala 2012-07-03 06:49:24 +0000
@@ -66,16 +66,16 @@
66 66
67 lm.start_file_operations(FETCHING_NEW);67 lm.start_file_operations(FETCHING_NEW);
68 try {68 try {
69 Thread.create<void*>(find_new_podcasts_thread, false);69 new Thread<void*>.try (null, find_new_podcasts_thread);
70 }70 }
71 catch(GLib.ThreadError err) {71 catch (Error err) {
72 stdout.printf("ERROR: Could not create thread to fetch new podcasts: %s \n", err.message);72 warning ("Could not create thread to fetch new podcasts: %s", err.message);
73 }73 }
74 74
75 lm.have_fetched_new_podcasts = true;75 lm.have_fetched_new_podcasts = true;
76 }76 }
77 77
78 public void* find_new_podcasts_thread () {78 private void* find_new_podcasts_thread () {
79 HashSet<string> rss_urls = new HashSet<string>();79 HashSet<string> rss_urls = new HashSet<string>();
80 HashSet<string> mp3_urls = new HashSet<string>();80 HashSet<string> mp3_urls = new HashSet<string>();
81 HashMap<string, string> rss_names = new HashMap<string, string>();81 HashMap<string, string> rss_names = new HashMap<string, string>();
@@ -174,7 +174,7 @@
174 //current_operation = FETCHING_FROM_RSS.printf("<b>" + Markup.escape_text(rss) + "</b>");174 //current_operation = FETCHING_FROM_RSS.printf("<b>" + Markup.escape_text(rss) + "</b>");
175 Timeout.add(500, doProgressNotificationWithTimeout);175 Timeout.add(500, doProgressNotificationWithTimeout);
176 176
177 debug("podcast_rss: %s\n", rss);177 debug("podcast_rss: %s", rss);
178 178
179 // create an HTTP session to twitter179 // create an HTTP session to twitter
180 var session = new Soup.SessionSync();180 var session = new Soup.SessionSync();
@@ -218,7 +218,7 @@
218 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);218 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);
219 if(doc == null)219 if(doc == null)
220 return null;220 return null;
221 //stdout.printf("%s\n", (string)message.response_body.data);221 //stdout.printf("%s", (string)message.response_body.data);
222 Xml.Node* root = doc->get_root_element ();222 Xml.Node* root = doc->get_root_element ();
223 if (root == null) {223 if (root == null) {
224 delete doc;224 delete doc;
@@ -279,7 +279,7 @@
279 Media new_p = new Media("");279 Media new_p = new Media("");
280 280
281 for (Xml.Node* item_iter = iter->children; item_iter != null; item_iter = item_iter->next) {281 for (Xml.Node* item_iter = iter->children; item_iter != null; item_iter = item_iter->next) {
282 //stdout.printf("name is %s\n", item_iter->name);282 //stdout.printf("name is %s", item_iter->name);
283 if(item_iter->name == "title")283 if(item_iter->name == "title")
284 new_p.title = item_iter->get_content();284 new_p.title = item_iter->get_content();
285 else if(name == "author") {285 else if(name == "author") {
@@ -365,14 +365,14 @@
365 save_locally_ids = ids;365 save_locally_ids = ids;
366 366
367 try {367 try {
368 Thread.create<void*>(save_episodes_locally_thread, false);368 new Thread<void*>.try (null, save_episodes_locally_thread);
369 }369 }
370 catch(GLib.ThreadError err) {370 catch (Error err) {
371 stdout.printf("ERROR: Could not create thread to save episodes locally: %s \n", err.message);371 warning ("Could not create thread to save episodes locally: %s", err.message);
372 }372 }
373 }373 }
374 374
375 public void* save_episodes_locally_thread () {375 private void* save_episodes_locally_thread () {
376 if(save_locally_ids == null || save_locally_ids.size == 0)376 if(save_locally_ids == null || save_locally_ids.size == 0)
377 return null;377 return null;
378 378
@@ -397,7 +397,7 @@
397 online_size = online_file.query_info("*", FileQueryInfoFlags.NONE).get_size();397 online_size = online_file.query_info("*", FileQueryInfoFlags.NONE).get_size();
398 }398 }
399 catch(Error err) {399 catch(Error err) {
400 stdout.printf("Could not read online podcast file's size for progress notification: %s\n", err.message);400 stdout.printf("Could not read online podcast file's size for progress notification: %s", err.message);
401 }401 }
402 402
403 new_dest = lm.fo.get_new_destination(s);403 new_dest = lm.fo.get_new_destination(s);
@@ -408,7 +408,7 @@
408 file_size = (int)(new_dest.query_info("*", FileQueryInfoFlags.NONE).get_size() / 1000000);408 file_size = (int)(new_dest.query_info("*", FileQueryInfoFlags.NONE).get_size() / 1000000);
409 }409 }
410 catch(Error err) {410 catch(Error err) {
411 stdout.printf("Could not calculate downloaded podcast's file size: %s\n", err.message);411 stdout.printf("Could not calculate downloaded podcast's file size: %s", err.message);
412 }412 }
413 413
414 s.file_size = file_size;414 s.file_size = file_size;
@@ -442,7 +442,7 @@
442 GLib.File original = GLib.File.new_for_uri(s.uri);442 GLib.File original = GLib.File.new_for_uri(s.uri);
443 443
444 /* copy the file over */444 /* copy the file over */
445 debug("Copying %s to %s\n", s.uri, dest.get_uri());445 debug("Copying %s to %s", s.uri, dest.get_uri());
446 success = original.copy(dest, FileCopyFlags.NONE, canceller, null);446 success = original.copy(dest, FileCopyFlags.NONE, canceller, null);
447 447
448 if(success || dest.query_exists()) {448 if(success || dest.query_exists()) {
@@ -456,10 +456,10 @@
456 });456 });
457 }457 }
458 else458 else
459 warning("Failure: Could not copy imported media %s to media folder %s\n", s.uri, dest.get_path());459 warning("Failure: Could not copy imported media %s to media folder %s", s.uri, dest.get_path());
460 }460 }
461 catch(GLib.Error err) {461 catch(GLib.Error err) {
462 warning("Could not copy imported media %s to media folder: %s\n", s.uri, err.message);462 warning("Could not copy imported media %s to media folder: %s", s.uri, err.message);
463 }463 }
464 464
465 return success;465 return success;
@@ -483,7 +483,7 @@
483 current_local_size = new_dest.query_info("*", FileQueryInfoFlags.NONE).get_size();483 current_local_size = new_dest.query_info("*", FileQueryInfoFlags.NONE).get_size();
484 }484 }
485 catch(Error err) {485 catch(Error err) {
486 stdout.printf("Error reading current size of downloaded podcast: %s\n", err.message);486 stdout.printf("Error reading current size of downloaded podcast: %s", err.message);
487 }487 }
488 }488 }
489 489
490490
=== modified file 'src/DataBase/DataBaseUpdater.vala'
--- src/DataBase/DataBaseUpdater.vala 2012-06-01 22:48:28 +0000
+++ src/DataBase/DataBaseUpdater.vala 2012-07-03 06:49:24 +0000
@@ -23,34 +23,27 @@
23/* Merely a place holder for multiple pieces of information regarding23/* Merely a place holder for multiple pieces of information regarding
24 * the current media playing. Mostly here because of dependence. */24 * the current media playing. Mostly here because of dependence. */
2525
26using Gee;
2726
28public class BeatBox.DataBaseUpdater : GLib.Object {27public class BeatBox.DataBaseUpdater : Object {
29 private LibraryManager lm;28 private LibraryManager lm;
30 private BeatBox.DataBaseManager dbm;29 private BeatBox.DataBaseManager dbm;
31 30
32 LinkedList<Media> media_updates;31 Gee.LinkedList<Media> media_updates;
33 32
34 Mutex update_mutex;33 Gee.LinkedList<Object> toUpdate; // a queue of things to update
35 Mutex remove_mutex;34 Gee.LinkedList<Object> toRemove;
36
37 LinkedList<GLib.Object> toUpdate; // a queue of things to update
38 LinkedList<GLib.Object> toRemove;
39 bool inThread;35 bool inThread;
40 36
41 public DataBaseUpdater(LibraryManager lm, BeatBox.DataBaseManager databm) {37 public DataBaseUpdater(LibraryManager lm, BeatBox.DataBaseManager databm) {
42 this.lm = lm;38 this.lm = lm;
43 dbm = databm;39 dbm = databm;
44 40
45 update_mutex = new Mutex();41 media_updates = new Gee.LinkedList<Media>();
46 remove_mutex = new Mutex();42 toUpdate = new Gee.LinkedList<Object>();
47 43 toRemove = new Gee.LinkedList<Object>();
48 media_updates = new LinkedList<Media>();
49 toUpdate = new LinkedList<GLib.Object>();
50 toRemove = new LinkedList<GLib.Object>();
51 inThread = false;44 inThread = false;
52 45
53 tree_view_setups = new GLib.List<TreeViewSetup>();46 tree_view_setups = new List<TreeViewSetup>();
54 47
55 Timeout.add(10000, periodic_save);48 Timeout.add(10000, periodic_save);
56 }49 }
@@ -61,76 +54,71 @@
61 return true;54 return true;
62 }55 }
63 56
64 public void update_item(GLib.Object item) {57 public void update_item(Object item) {
65 if(!(toUpdate.contains(item)))58 if(!(toUpdate.contains(item)))
66 toUpdate.offer(item);59 toUpdate.offer(item);
67 60
68 if(!inThread && lm.lw.initializationFinished) {61 update_database_async ();
69 try {62 }
70 inThread = true;63
71 Thread.create<void*>(update_db_thread_function, false);64 public void update_medias(Gee.Collection<Media> updates) {
72 }65 lock (media_updates) {
73 catch(GLib.ThreadError err) {66 foreach (var s in updates)
74 stdout.printf("Could not create thread to update database: %s \n", err.message);67 media_updates.offer (s);
75 }68 }
76 }69
77 }70 update_database_async ();
78 71 }
79 public void update_medias(Collection<Media> updates) {72
80 update_mutex.lock();73 public void removeItem (Object item) {
81 foreach(var s in updates)74 lock (toRemove) {
82 media_updates.offer(s);75 if (!(toRemove.contains(item)))
83 update_mutex.unlock();76 toRemove.offer (item);
84 77 }
85 if(!inThread && lm.lw.initializationFinished) {78
86 try {79 update_database_async ();
87 inThread = true;80 }
88 Thread.create<void*>(update_db_thread_function, false);81
89 }82 private async void update_database_async () {
90 catch(GLib.ThreadError err) {83 if(!inThread && lm.lw.initializationFinished) {
91 stdout.printf("Could not create thread to update database: %s \n", err.message);84 try {
92 }85 inThread = true;
93 }86 new Thread<void*>.try (null, update_db_thread_function);
94 }87 }
95 88 catch (Error err) {
96 public void removeItem(GLib.Object item) {89 warning ("Could not create thread to update database: %s", err.message);
97 remove_mutex.lock();90 inThread = false;
98 if(!(toRemove.contains(item)))91 }
99 toRemove.offer(item);92 }
100 remove_mutex.unlock();93 }
101 94
102 if(!inThread && lm.lw.initializationFinished) {95
103 try {96 Mutex update_db_lock;
104 inThread = true;97
105 Thread.create<void*>(update_db_thread_function, false);98 private void* update_db_thread_function () {
106 }99 update_db_lock.lock ();
107 catch(GLib.ThreadError err) {100
108 stdout.printf("Could not create thread to update database: %s \n", err.message);101 while (true) {
109 }102 Object? next = null;
110 }103
111 }104 if (media_updates.size > 0) {
112 105 dbm.update_medias (media_updates);
113 public void* update_db_thread_function () {106 media_updates.clear ();
114 while(true) {107 }
115 GLib.Object next;108 else if ((next = toUpdate.poll()) != null) {
116 109 // FIXME: NOTHING TO DO
117 update_mutex.lock();
118 remove_mutex.lock();
119 if(media_updates.size > 0) {
120 dbm.update_medias(media_updates);
121 media_updates.clear();
122 }
123 else if((next = toUpdate.poll()) != null) {
124 if(next is Playlist) {110 if(next is Playlist) {
111 warning ("update_db_thread_function: %next is Playlist. HANDLE IT!");
125 //dbm.update_playlist((Playlist)next);112 //dbm.update_playlist((Playlist)next);
126 }113 }
127 else if(next is SmartPlaylist) {114 else if(next is SmartPlaylist) {
115 warning ("update_db_thread_function: %next is SmartPlaylist. HANDLE IT!");
128 //dbm.update_smart_playlist((SmartPlaylist)next);116 //dbm.update_smart_playlist((SmartPlaylist)next);
129 }117 }
130 }118 }
131 else if((next = toRemove.poll()) != null) {119 else if((next = toRemove.poll()) != null) {
132 if(next is LinkedList) {120 if(next is Gee.LinkedList) {
133 dbm.remove_medias((LinkedList<string>)next);121 dbm.remove_medias((Gee.LinkedList<string>)next);
134 }122 }
135 else if(next is Playlist) {123 else if(next is Playlist) {
136 dbm.remove_playlist((Playlist)next);124 dbm.remove_playlist((Playlist)next);
@@ -141,18 +129,15 @@
141 }129 }
142 else {130 else {
143 inThread = false;131 inThread = false;
144 update_mutex.unlock();132 break;
145 remove_mutex.unlock();
146 return null;
147 }133 }
148
149 update_mutex.unlock();
150 remove_mutex.unlock();
151 }134 }
152135
136 update_db_lock.unlock ();
137 return null;
153 }138 }
154 139
155 GLib.List<TreeViewSetup> tree_view_setups;140 List<TreeViewSetup> tree_view_setups;
156 141
157 public void register_autosaved_column (string name, TreeViewSetup setup) {142 public void register_autosaved_column (string name, TreeViewSetup setup) {
158 setup.set_data<string>("name", name);143 setup.set_data<string>("name", name);
@@ -160,7 +145,7 @@
160 }145 }
161 146
162 void save_others() {147 void save_others() {
163 var playlists_and_queue = new LinkedList<Playlist>();148 var playlists_and_queue = new Gee.LinkedList<Playlist>();
164 playlists_and_queue.add_all(lm.playlists());149 playlists_and_queue.add_all(lm.playlists());
165 150
166 Playlist p_queue = new Playlist();151 Playlist p_queue = new Playlist();
@@ -195,7 +180,7 @@
195 playlists_and_queue.add(p_podcast);180 playlists_and_queue.add(p_podcast);
196 playlists_and_queue.add(p_station);181 playlists_and_queue.add(p_station);
197 182
198 debug("Doing periodic save\n");183 debug("Doing periodic save");
199 184
200 dbm.save_playlists(playlists_and_queue);185 dbm.save_playlists(playlists_and_queue);
201 dbm.save_smart_playlists(lm.smart_playlists());186 dbm.save_smart_playlists(lm.smart_playlists());
202187
=== modified file 'src/Devices/CDRomDevice.vala'
--- src/Devices/CDRomDevice.vala 2012-06-01 22:48:28 +0000
+++ src/Devices/CDRomDevice.vala 2012-07-03 06:49:24 +0000
@@ -69,10 +69,10 @@
69 lm.progress_cancel_clicked.connect(cancel_transfer);69 lm.progress_cancel_clicked.connect(cancel_transfer);
70 70
71 try {71 try {
72 Thread.create<void*>(finish_initialization_thread, false);72 new Thread<void*>.try (null, finish_initialization_thread);
73 }73 }
74 catch(GLib.ThreadError err) {74 catch (Error err) {
75 stdout.printf("ERROR: Could not create thread to finish ipod initialization: %s \n", err.message);75 warning ("Could not create thread to finish ipod initialization: %s", err.message);
76 }76 }
77 }77 }
78 78
7979
=== modified file 'src/Devices/DeviceManager.vala'
--- src/Devices/DeviceManager.vala 2012-07-02 23:17:27 +0000
+++ src/Devices/DeviceManager.vala 2012-07-03 06:49:24 +0000
@@ -27,7 +27,6 @@
27 VolumeMonitor vm;27 VolumeMonitor vm;
28 LinkedList<Device> devices;28 LinkedList<Device> devices;
29 29
30 Mutex _pref_lock;
31 HashTable<string, DevicePreferences> _device_preferences;30 HashTable<string, DevicePreferences> _device_preferences;
32 31
33 public signal void device_added(Device d);32 public signal void device_added(Device d);
@@ -38,15 +37,14 @@
38 vm = VolumeMonitor.get();37 vm = VolumeMonitor.get();
39 devices = new LinkedList<Device>();38 devices = new LinkedList<Device>();
40 39
41 _pref_lock = new Mutex();
42 _device_preferences = new HashTable<string, DevicePreferences>(null, null);40 _device_preferences = new HashTable<string, DevicePreferences>(null, null);
43 41
44 // pre-load devices and their preferences42 // pre-load devices and their preferences
45 _pref_lock.lock();43 lock (_device_preferences) {
46 foreach(DevicePreferences dp in lm.dbm.load_devices()) {44 foreach(DevicePreferences dp in lm.dbm.load_devices()) {
47 _device_preferences.set(dp.id, dp);45 _device_preferences.set(dp.id, dp);
46 }
48 }47 }
49 _pref_lock.unlock();
50 48
51 vm.mount_added.connect(mount_added);49 vm.mount_added.connect(mount_added);
52 vm.mount_changed.connect(mount_changed);50 vm.mount_changed.connect(mount_changed);
@@ -59,10 +57,15 @@
59 57
60 // this can take time if we have to rev up the cd drive58 // this can take time if we have to rev up the cd drive
61 try {59 try {
62 Thread.create<void*>(get_pre_existing_mounts, false);60 new Thread<void*>.try (null, get_pre_existing_mounts);
63 }61 }
62<<<<<<< TREE
64 catch(GLib.ThreadError err) {63 catch(GLib.ThreadError err) {
65 warning("ERROR: could not create mount getter thread: %s \n", err.message);64 warning("ERROR: could not create mount getter thread: %s \n", err.message);
65=======
66 catch (Error err) {
67 warning ("Could not create mount getter thread: %s", err.message);
68>>>>>>> MERGE-SOURCE
66 }69 }
67 }70 }
68 71
@@ -126,6 +129,7 @@
126 else if(lm.settings.getMusicFolder().contains(mount.get_default_location().get_path())) {129 else if(lm.settings.getMusicFolder().contains(mount.get_default_location().get_path())) {
127 // user mounted music folder, rescan for images130 // user mounted music folder, rescan for images
128 lm.settings.setMusicMountName(mount.get_volume().get_name());131 lm.settings.setMusicMountName(mount.get_volume().get_name());
132<<<<<<< TREE
129 lm.recheck_files_not_found();133 lm.recheck_files_not_found();
130 134
131 try {135 try {
@@ -134,6 +138,10 @@
134 catch(GLib.ThreadError err) {138 catch(GLib.ThreadError err) {
135 message("Could not create thread to load media pixbuf's: %s \n", err.message);139 message("Could not create thread to load media pixbuf's: %s \n", err.message);
136 }140 }
141=======
142 lm.recheck_files_not_found_async ();
143 lm.fetch_image_cache_async ();
144>>>>>>> MERGE-SOURCE
137 145
138 return;146 return;
139 }147 }
@@ -190,11 +198,9 @@
190 public GLib.List<DevicePreferences> device_preferences() {198 public GLib.List<DevicePreferences> device_preferences() {
191 var rv = new GLib.List<DevicePreferences>();199 var rv = new GLib.List<DevicePreferences>();
192 200
193 _pref_lock.lock();201 foreach (var pref in _device_preferences.get_values()) {
194 foreach(var pref in _device_preferences.get_values()) {202 rv.append (pref);
195 rv.append(pref);
196 }203 }
197 _pref_lock.unlock();
198 204
199 return rv;205 return rv;
200 }206 }
@@ -204,8 +210,8 @@
204 }210 }
205 211
206 public void add_device_preferences(DevicePreferences dp) {212 public void add_device_preferences(DevicePreferences dp) {
207 _pref_lock.lock();213 lock (_device_preferences) {
208 _device_preferences.set(dp.id, dp);214 _device_preferences.set(dp.id, dp);
209 _pref_lock.unlock();215 }
210 }216 }
211}217}
212218
=== modified file 'src/Devices/iPodDevice.vala'
--- src/Devices/iPodDevice.vala 2012-07-02 22:57:45 +0000
+++ src/Devices/iPodDevice.vala 2012-07-03 06:49:24 +0000
@@ -98,10 +98,10 @@
98 });98 });
99 99
100 try {100 try {
101 Thread.create<void*>(finish_initialization_thread, false);101 new Thread<void*>.try (null, finish_initialization_thread);
102 }102 }
103 catch(GLib.ThreadError err) {103 catch(Error err) {
104 stdout.printf("ERROR: Could not create thread to finish ipod initialization: %s \n", err.message);104 warning ("Could not create thread to finish ipod initialization: %s", err.message);
105 }105 }
106 }106 }
107 107
@@ -325,10 +325,10 @@
325 this.list = list;325 this.list = list;
326 326
327 try {327 try {
328 Thread.create<void*>(sync_medias_thread, false);328 new Thread<void*>.try (null, sync_medias_thread);
329 }329 }
330 catch(GLib.ThreadError err) {330 catch (Error err) {
331 stdout.printf("ERROR: Could not create thread to sync medias: %s \n", err.message);331 warning ("Could not create thread to sync medias: %s", err.message);
332 return false;332 return false;
333 }333 }
334 334
@@ -542,10 +542,10 @@
542 this.list = list;542 this.list = list;
543 543
544 try {544 try {
545 Thread.create<void*>(add_medias_thread, false);545 new Thread<void*>.try (null, add_medias_thread);
546 }546 }
547 catch(GLib.ThreadError err) {547 catch (Error err) {
548 stdout.printf("ERROR: Could not create thread to add medias: %s \n", err.message);548 warning ("Could not create thread to add medias: %s", err.message);
549 return false;549 return false;
550 }550 }
551 551
@@ -698,10 +698,10 @@
698 this.list = list;698 this.list = list;
699 699
700 try {700 try {
701 Thread.create<void*>(remove_medias_thread, false);701 new Thread<void*>.try (null, remove_medias_thread);
702 }702 }
703 catch(GLib.ThreadError err) {703 catch (Error err) {
704 stdout.printf("ERROR: Could not create thread to remove medias: %s \n", err.message);704 warning ("Could not create thread to remove medias: %s", err.message);
705 return false;705 return false;
706 }706 }
707 707
@@ -931,10 +931,10 @@
931 current_operation = _("Importing") + " <b>" + ((list.size > 1) ? list.size.to_string() : (list.get(0)).title) + "</b> " + _("items to library...");931 current_operation = _("Importing") + " <b>" + ((list.size > 1) ? list.size.to_string() : (list.get(0)).title) + "</b> " + _("items to library...");
932 932
933 try {933 try {
934 Thread.create<void*>(transfer_medias_thread, false);934 new Thread<void*>.try (null, transfer_medias_thread);
935 }935 }
936 catch(GLib.ThreadError err) {936 catch(Error err) {
937 stdout.printf("ERROR: Could not create thread to transfer medias: %s \n", err.message);937 warning ("Could not create thread to transfer media: %s", err.message);
938 return false;938 return false;
939 }939 }
940 940
941941
=== modified file 'src/Lastfm/LastFM.vala'
--- src/Lastfm/LastFM.vala 2012-06-06 02:59:17 +0000
+++ src/Lastfm/LastFM.vala 2012-07-03 06:49:24 +0000
@@ -20,10 +20,6 @@
20 * Boston, MA 02111-1307, USA.20 * Boston, MA 02111-1307, USA.
21 */21 */
2222
23using Xml;
24using Soup;
25using Gee;
26
27public class LastFM.Core : Object {23public class LastFM.Core : Object {
28 BeatBox.LibraryManager lm;24 BeatBox.LibraryManager lm;
29 25
@@ -36,7 +32,7 @@
36 public string session_key;32 public string session_key;
37 33
38 public signal void logged_in();34 public signal void logged_in();
39 public signal void similar_retrieved(LinkedList<int> similarIDs, LinkedList<BeatBox.Media> similarDont);35 public signal void similar_retrieved(Gee.LinkedList<int> similarIDs, Gee.LinkedList<BeatBox.Media> similarDont);
40 public signal void top_artist_songs_retrieved(HashTable<int, BeatBox.Media> songs);36 public signal void top_artist_songs_retrieved(HashTable<int, BeatBox.Media> songs);
41 public signal void top_artist_albums_retrieved(HashTable<int, BeatBox.ExternalAlbum> albums);37 public signal void top_artist_albums_retrieved(HashTable<int, BeatBox.ExternalAlbum> albums);
42 public signal void track_fetched();38 public signal void track_fetched();
@@ -46,13 +42,10 @@
46 LastFM.SimilarMedias similarMedias;42 LastFM.SimilarMedias similarMedias;
47 LastFM.TopArtistSongs topArtistSongs;43 LastFM.TopArtistSongs topArtistSongs;
48 LastFM.TopArtistAlbums topArtistAlbums;44 LastFM.TopArtistAlbums topArtistAlbums;
49 45
50 Mutex _artists_lock;46 Gee.HashMap<string, LastFM.ArtistInfo> _artists;//key:artist
51 Mutex _albums_lock;47 Gee.HashMap<string, LastFM.AlbumInfo> _albums;//key:artist<sep>album
52 Mutex _tracks_lock;48 Gee.HashMap<string, LastFM.TrackInfo> _tracks;//key:artist<sep>album<sep>track
53 HashMap<string, LastFM.ArtistInfo> _artists;//key:artist
54 HashMap<string, LastFM.AlbumInfo> _albums;//key:artist<sep>album
55 HashMap<string, LastFM.TrackInfo> _tracks;//key:artist<sep>album<sep>track
56 49
57 public Core(BeatBox.LibraryManager lmm) {50 public Core(BeatBox.LibraryManager lmm) {
58 lm = lmm;51 lm = lmm;
@@ -61,32 +54,28 @@
61 similarMedias = new LastFM.SimilarMedias(lm);54 similarMedias = new LastFM.SimilarMedias(lm);
62 topArtistSongs = new LastFM.TopArtistSongs(lm);55 topArtistSongs = new LastFM.TopArtistSongs(lm);
63 topArtistAlbums = new LastFM.TopArtistAlbums(lm);56 topArtistAlbums = new LastFM.TopArtistAlbums(lm);
64 57
65 _artists_lock = new Mutex();58 _artists = new Gee.HashMap<string, LastFM.ArtistInfo>();
66 _albums_lock = new Mutex();59 _albums = new Gee.HashMap<string, LastFM.AlbumInfo>();
67 _tracks_lock = new Mutex();60 _tracks = new Gee.HashMap<string, LastFM.TrackInfo>();
68 61
69 _artists = new HashMap<string, LastFM.ArtistInfo>();62 lock (_artists) {
70 _albums = new HashMap<string, LastFM.AlbumInfo>();63 foreach (LastFM.ArtistInfo a in lm.dbm.load_artists()) {
71 _tracks = new HashMap<string, LastFM.TrackInfo>();64 _artists.set (a.name.down(), a);
72 65 }
73 _artists_lock.lock();66 }
74 foreach(LastFM.ArtistInfo a in lm.dbm.load_artists()) {67
75 _artists.set(a.name.down(), a);68 lock (_albums) {
76 }69 foreach (LastFM.AlbumInfo a in lm.dbm.load_albums()) {
77 _artists_lock.unlock();70 _albums.set (a.name.down() + " by " + a.artist.down(), a);
78 71 }
79 _albums_lock.lock();72 }
80 foreach(LastFM.AlbumInfo a in lm.dbm.load_albums()) {73
81 _albums.set(a.name.down() + " by " + a.artist.down(), a);74 lock (_tracks) {
82 }75 foreach (LastFM.TrackInfo t in lm.dbm.load_tracks()) {
83 _albums_lock.unlock();76 _tracks.set (t.name.down() + " by " + t.artist.down(), t);
84 77 }
85 _tracks_lock.lock();78 }
86 foreach(LastFM.TrackInfo t in lm.dbm.load_tracks()) {
87 _tracks.set(t.name.down() + " by " + t.artist.down(), t);
88 }
89 _tracks_lock.unlock();
90 79
91 similarMedias.similar_retrieved.connect(similar_retrieved_signal);80 similarMedias.similar_retrieved.connect(similar_retrieved_signal);
92 topArtistSongs.top_artist_songs_retrieved.connect(top_artist_songs_retrieved_signal);81 topArtistSongs.top_artist_songs_retrieved.connect(top_artist_songs_retrieved_signal);
@@ -94,42 +83,40 @@
94 }83 }
95 84
96 /************* Last FM Artist Stuff ************/85 /************* Last FM Artist Stuff ************/
97 public GLib.List<LastFM.ArtistInfo> artists() {86 public List<LastFM.ArtistInfo> artists () {
98 var rv = new GLib.List<LastFM.ArtistInfo>();87 var rv = new List<LastFM.ArtistInfo>();
99 foreach(var artist in _artists.values)88 foreach(var artist in _artists.values)
100 rv.append(artist);89 rv.append(artist);
101 90
102 return rv;91 return rv;
103 }92 }
104 93
105 public void save_artist(LastFM.ArtistInfo artist) {94 public void save_artist (LastFM.ArtistInfo artist) {
106 _artists_lock.lock();95 lock (_artists) {
107 _artists.set(artist.name.down(), artist);96 _artists.set (artist.name.down(), artist);
108 _artists_lock.unlock();97 }
109 }98 }
110 99
111 public bool artist_info_exists(string artist_key) {100 public bool artist_info_exists (string artist_key) {
112 return _artists.get(artist_key.down()) != null;101 return _artists.has_key (artist_key.down());
113 }102 }
114 103
115 public LastFM.ArtistInfo? get_artist_from_media(BeatBox.Media m) {104 public LastFM.ArtistInfo? get_artist_from_media (BeatBox.Media m) {
116 return get_artist(m.album_artist.down());105 return get_artist (m.album_artist);
117 }106 }
118 107
119 public LastFM.ArtistInfo? get_artist(string artist_key) {108 public LastFM.ArtistInfo? get_artist (string artist_key) {
120 LastFM.ArtistInfo? rv = null;109 LastFM.ArtistInfo? rv = null;
121 110
122 _artists_lock.lock();111 if (artist_info_exists (artist_key))
123 if(artist_info_exists(artist_key.down())) 112 rv = _artists.get (artist_key.down());
124 rv = _artists.get(artist_key.down());113
125 _artists_lock.unlock();
126
127 return rv;114 return rv;
128 }115 }
129 116
130 /************** LastFM Album stuff **************/117 /************** LastFM Album stuff **************/
131 public GLib.List<LastFM.AlbumInfo> albums() {118 public List<LastFM.AlbumInfo> albums() {
132 var rv = new GLib.List<LastFM.AlbumInfo>();119 var rv = new List<LastFM.AlbumInfo>();
133 foreach(var album in _albums.values)120 foreach(var album in _albums.values)
134 rv.append(album);121 rv.append(album);
135 122
@@ -137,33 +124,31 @@
137 }124 }
138 125
139 public void save_album(LastFM.AlbumInfo album) {126 public void save_album(LastFM.AlbumInfo album) {
140 _albums_lock.lock();127 lock (_albums) {
141 _albums.set(album.name.down() + " by " + album.artist.down(), album);128 _albums.set(album.name.down() + " by " + album.artist.down(), album);
142 _albums_lock.unlock();129 }
143 }130 }
144 131
145 public bool album_info_exists(string album_key) {132 public bool album_info_exists(string album_key) {
146 return _albums.get(album_key) != null;133 return _albums.has_key (album_key.down());
147 }134 }
148 135
149 public LastFM.AlbumInfo? get_album_from_media(BeatBox.Media m) {136 public LastFM.AlbumInfo? get_album_from_media (BeatBox.Media m) {
150 return get_album(m.album.down() + " by " + m.album_artist.down());137 return get_album (m.album.down() + " by " + m.album_artist.down());
151 }138 }
152 139
153 public LastFM.AlbumInfo? get_album(string album_key) {140 public LastFM.AlbumInfo? get_album(string album_key) {
154 LastFM.AlbumInfo? rv = null;141 LastFM.AlbumInfo? rv = null;
155 142
156 _albums_lock.lock();143 if(album_info_exists (album_key))
157 if(album_info_exists(album_key.down())) 144 rv = _albums.get (album_key.down());
158 rv = _albums.get(album_key.down());145
159 _albums_lock.unlock();
160
161 return rv;146 return rv;
162 }147 }
163 148
164 /************** Last FM Track Stuff ***************/149 /************** Last FM Track Stuff ***************/
165 public GLib.List<LastFM.TrackInfo> tracks() {150 public List<LastFM.TrackInfo> tracks() {
166 var rv = new GLib.List<LastFM.TrackInfo>();151 var rv = new List<LastFM.TrackInfo>();
167 foreach(var track in _tracks.values)152 foreach(var track in _tracks.values)
168 rv.append(track);153 rv.append(track);
169 154
@@ -171,37 +156,35 @@
171 }156 }
172 157
173 public void save_track(LastFM.TrackInfo track) {158 public void save_track(LastFM.TrackInfo track) {
174 _tracks_lock.lock();159 lock (_tracks) {
175 _tracks.set(track.name.down() + " by " + track.artist.down(), track);160 _tracks.set (track.name.down() + " by " + track.artist.down(), track);
176 _tracks_lock.unlock();161 }
177 }162 }
178 163
179 public bool track_info_exists(string track_key) {164 public bool track_info_exists(string track_key) {
180 return _tracks.get(track_key.down()) != null;165 return _tracks.has_key (track_key.down());
181 }166 }
182 167
183 public LastFM.TrackInfo? get_track_from_media(BeatBox.Media m) {168 public LastFM.TrackInfo? get_track_from_media (BeatBox.Media m) {
184 return get_track(m.title.down() + " by " + m.album_artist.down());169 return get_track (m.title.down() + " by " + m.album_artist.down());
185 }170 }
186 171
187 public LastFM.TrackInfo? get_track(string track_key) {172 public LastFM.TrackInfo? get_track (string track_key) {
188 LastFM.TrackInfo? rv = null;173 LastFM.TrackInfo? rv = null;
189 174
190 _tracks_lock.lock();175 if (track_info_exists (track_key.down()))
191 if(track_info_exists(track_key.down()))176 rv = _tracks.get (track_key.down());
192 rv = _tracks.get(track_key.down());
193 _tracks_lock.unlock();
194 177
195 return rv;178 return rv;
196 }179 }
197 180
198 /** Last.FM Api functions **/181 /** Last.FM Api functions **/
199 public static string fix_for_url(string fix) {182 public static string fix_for_url (string fix) {
200 return GLib.Uri.escape_string(fix, null, false);183 return Uri.escape_string (fix, "", false);
201 }184 }
202 185
203 public string generate_md5(string text) {186 public string generate_md5(string text) {
204 return GLib.Checksum.compute_for_string(ChecksumType.MD5, text, text.length);187 return Checksum.compute_for_string(ChecksumType.MD5, text, text.length);
205 }188 }
206 189
207 public string generate_getsession_signature(string token) {190 public string generate_getsession_signature(string token) {
@@ -227,9 +210,9 @@
227 public string? getToken() {210 public string? getToken() {
228 var url = "http://ws.audioscrobbler.com/2.0/?method=auth.gettoken&api_key=" + api;211 var url = "http://ws.audioscrobbler.com/2.0/?method=auth.gettoken&api_key=" + api;
229 212
230 Xml.Doc* doc = Parser.parse_file (url);213 Xml.Doc* doc = Xml.Parser.parse_file (url);
231 if(doc == null) return null;214 if(doc == null) return null;
232 215
233 Xml.Node* root = doc->get_root_element();216 Xml.Node* root = doc->get_root_element();
234 if(root == null) return null;217 if(root == null) return null;
235 218
@@ -246,9 +229,9 @@
246 var sig = generate_getsession_signature(token);229 var sig = generate_getsession_signature(token);
247 var url = "http://ws.audioscrobbler.com/2.0/?method=auth.getSession&api_key=" + api + "&api_sig=" + sig + "&token=" + token;230 var url = "http://ws.audioscrobbler.com/2.0/?method=auth.getSession&api_key=" + api + "&api_sig=" + sig + "&token=" + token;
248 231
249 message("url: %s\n", url);232 message ("url: %s", url);
250 233
251 Xml.Doc* doc = Parser.parse_file (url);234 Xml.Doc* doc = Xml.Parser.parse_file (url);
252 if(doc == null) return null;235 if(doc == null) return null;
253 236
254 Xml.Node* root = doc->get_root_element();237 Xml.Node* root = doc->get_root_element();
@@ -268,7 +251,7 @@
268 251
269 public bool loveTrack(string title, string artist) {252 public bool loveTrack(string title, string artist) {
270 if(session_key == null || session_key == "") {253 if(session_key == null || session_key == "") {
271 debug("User tried to ban a track, but is not logged into Last FM\n");254 debug("User tried to ban a track, but is not logged into Last FM");
272 return false;255 return false;
273 }256 }
274 257
@@ -277,7 +260,7 @@
277 Soup.SessionSync session = new Soup.SessionSync();260 Soup.SessionSync session = new Soup.SessionSync();
278 Soup.Message message = new Soup.Message ("POST", uri);261 Soup.Message message = new Soup.Message ("POST", uri);
279 262
280 var headers = new Soup.MessageHeaders(MessageHeadersType.REQUEST);263 var headers = new Soup.MessageHeaders(Soup.MessageHeadersType.REQUEST);
281 headers.append("api_key", api);264 headers.append("api_key", api);
282 headers.append("api_sig", generate_tracklove_signature(artist, title));265 headers.append("api_sig", generate_tracklove_signature(artist, title));
283 headers.append("artist", artist);266 headers.append("artist", artist);
@@ -298,7 +281,7 @@
298 281
299 public bool banTrack(string title, string artist) {282 public bool banTrack(string title, string artist) {
300 if(session_key == null || session_key == "") {283 if(session_key == null || session_key == "") {
301 debug("User tried to ban a track, but is not logged into Last FM\n");284 debug("User tried to ban a track, but is not logged into Last FM");
302 return false;285 return false;
303 }286 }
304 287
@@ -307,7 +290,7 @@
307 Soup.SessionSync session = new Soup.SessionSync();290 Soup.SessionSync session = new Soup.SessionSync();
308 Soup.Message message = new Soup.Message ("POST", uri);291 Soup.Message message = new Soup.Message ("POST", uri);
309 292
310 var headers = new Soup.MessageHeaders(MessageHeadersType.REQUEST);293 var headers = new Soup.MessageHeaders(Soup.MessageHeadersType.REQUEST);
311 headers.append("api_key", api);294 headers.append("api_key", api);
312 headers.append("api_sig", generate_trackban_signature(artist, title));295 headers.append("api_sig", generate_trackban_signature(artist, title));
313 headers.append("artist", artist);296 headers.append("artist", artist);
@@ -330,13 +313,13 @@
330 */313 */
331 public void fetchCurrentTrackInfo() {314 public void fetchCurrentTrackInfo() {
332 try {315 try {
333 Thread.create<void*>(track_thread_function, false);316 new Thread<void*>.try (null, track_thread_function);
334 } catch(GLib.ThreadError err) {317 } catch (Error err) {
335 warning ("ERROR: Could not create last fm thread: %s \n", err.message);318 warning ("Could not create last fm thread: %s", err.message);
336 }319 }
337 }320 }
338 321
339 void* track_thread_function () {322 private void* track_thread_function () {
340 LastFM.TrackInfo track = new LastFM.TrackInfo.basic();323 LastFM.TrackInfo track = new LastFM.TrackInfo.basic();
341324
342 string album_artist_s = lm.media_info.media.album_artist;325 string album_artist_s = lm.media_info.media.album_artist;
@@ -364,13 +347,13 @@
364 347
365 public void fetchCurrentAlbumInfo() {348 public void fetchCurrentAlbumInfo() {
366 try {349 try {
367 Thread.create<void*>(album_thread_function, false);350 new Thread<void*>.try (null, album_thread_function);
368 } catch(GLib.ThreadError err) {351 } catch (Error err) {
369 warning ("ERROR: Could not create last fm thread: %s \n", err.message);352 warning ("Could not create last fm thread: %s", err.message);
370 }353 }
371 }354 }
372 355
373 void* album_thread_function () {356 private void* album_thread_function () {
374 LastFM.AlbumInfo album = new LastFM.AlbumInfo.basic();357 LastFM.AlbumInfo album = new LastFM.AlbumInfo.basic();
375 358
376 string album_artist_s = lm.media_info.media.album_artist;359 string album_artist_s = lm.media_info.media.album_artist;
@@ -391,12 +374,12 @@
391 374
392 /* If we found an album art, and we don't have one yet, save it to file **/375 /* If we found an album art, and we don't have one yet, save it to file **/
393 if(album.url_image.url != null && lm.get_cover_album_art_from_key(album_artist_s, album_s) == null) {376 if(album.url_image.url != null && lm.get_cover_album_art_from_key(album_artist_s, album_s) == null) {
394 debug("Saving album image locally for %s by %s\n", album_s, album_artist_s);377 debug("Saving album image locally for %s by %s", album_s, album_artist_s);
395 lm.save_album_locally(lm.media_info.media.rowid, album.url_image.url, false);378 lm.save_album_locally(lm.media_info.media.rowid, album.url_image.url, false);
396 }379 }
397 380
398 // Fix up the track # on any songs in our library381 // Fix up the track # on any songs in our library
399 var updates = new LinkedList<BeatBox.Media>();382 var updates = new Gee.LinkedList<BeatBox.Media>();
400 foreach(var m in album.tracks()) {383 foreach(var m in album.tracks()) {
401 var in_lib = lm.media_from_name(m.title, m.artist);384 var in_lib = lm.media_from_name(m.title, m.artist);
402 if(in_lib != null && in_lib.track != m.track) {385 if(in_lib != null && in_lib.track != m.track) {
@@ -418,13 +401,13 @@
418 */401 */
419 public void fetchCurrentArtistInfo() {402 public void fetchCurrentArtistInfo() {
420 try {403 try {
421 Thread.create<void*>(artist_thread_function, false);404 new Thread<void*>.try (null, artist_thread_function);
422 } catch(GLib.ThreadError err) {405 } catch (Error err) {
423 warning ("ERROR: Could not create last fm thread: %s \n", err.message);406 warning ("Could not create last fm thread: %s", err.message);
424 }407 }
425 }408 }
426 409
427 void* artist_thread_function () {410 private void* artist_thread_function () {
428 LastFM.ArtistInfo artist = new LastFM.ArtistInfo.basic();411 LastFM.ArtistInfo artist = new LastFM.ArtistInfo.basic();
429412
430 string album_artist_s = lm.media_info.media.album_artist;413 string album_artist_s = lm.media_info.media.album_artist;
@@ -456,15 +439,15 @@
456 */439 */
457 public void postNowPlaying() {440 public void postNowPlaying() {
458 try {441 try {
459 Thread.create<void*>(update_nowplaying_thread_function, false);442 new Thread<void*>.try (null, update_nowplaying_thread_function);
460 } catch(GLib.ThreadError err) {443 } catch (Error err) {
461 warning ("ERROR: Could not create last fm thread: %s \n", err.message);444 warning ("Could not create last fm thread: %s", err.message);
462 }445 }
463 }446 }
464 447
465 void* update_nowplaying_thread_function() {448 void* update_nowplaying_thread_function() {
466 if(session_key == null || session_key == "") {449 if(session_key == null || session_key == "") {
467 debug("Last.FM user not logged in\n");450 debug("Last.FM user not logged in");
468 return null;451 return null;
469 }452 }
470 if(!lm.media_active)453 if(!lm.media_active)
@@ -477,7 +460,7 @@
477 Soup.SessionSync session = new Soup.SessionSync();460 Soup.SessionSync session = new Soup.SessionSync();
478 Soup.Message message = new Soup.Message ("POST", uri);461 Soup.Message message = new Soup.Message ("POST", uri);
479 462
480 var headers = new Soup.MessageHeaders(MessageHeadersType.REQUEST);463 var headers = new Soup.MessageHeaders(Soup.MessageHeadersType.REQUEST);
481 headers.append("api_key", api);464 headers.append("api_key", api);
482 headers.append("api_sig", generate_trackupdatenowplaying_signature(artist, title));465 headers.append("api_sig", generate_trackupdatenowplaying_signature(artist, title));
483 headers.append("artist", artist);466 headers.append("artist", artist);
@@ -501,15 +484,15 @@
501 */484 */
502 public void postScrobbleTrack() {485 public void postScrobbleTrack() {
503 try {486 try {
504 Thread.create<void*>(scrobble_thread_function, false);487 new Thread<void*>.try (null, scrobble_thread_function);
505 } catch(GLib.ThreadError err) {488 } catch (Error err) {
506 warning ("ERROR: Could not create last fm thread: %s \n", err.message);489 warning ("Could not create last fm thread: %s", err.message);
507 }490 }
508 }491 }
509 492
510 void* scrobble_thread_function () {493 void* scrobble_thread_function () {
511 if(session_key == null || session_key == "") {494 if(session_key == null || session_key == "") {
512 debug("Last.FM user not logged in\n");495 debug("Last.FM user not logged in");
513 return null;496 return null;
514 }497 }
515 if(!lm.media_active)498 if(!lm.media_active)
@@ -523,7 +506,7 @@
523 Soup.SessionSync session = new Soup.SessionSync();506 Soup.SessionSync session = new Soup.SessionSync();
524 Soup.Message message = new Soup.Message ("POST", uri);507 Soup.Message message = new Soup.Message ("POST", uri);
525 508
526 var headers = new Soup.MessageHeaders(MessageHeadersType.REQUEST);509 var headers = new Soup.MessageHeaders(Soup.MessageHeadersType.REQUEST);
527 headers.append("api_key", api);510 headers.append("api_key", api);
528 headers.append("api_sig", generate_trackscrobble_signature(artist, title, timestamp));511 headers.append("api_sig", generate_trackscrobble_signature(artist, title, timestamp));
529 headers.append("artist", artist);512 headers.append("artist", artist);
@@ -547,7 +530,7 @@
547 similarMedias.queryForSimilar(lm.media_info.media);530 similarMedias.queryForSimilar(lm.media_info.media);
548 }531 }
549 532
550 void similar_retrieved_signal(LinkedList<int> similarIDs, LinkedList<BeatBox.Media> similarDont) {533 void similar_retrieved_signal(Gee.LinkedList<int> similarIDs, Gee.LinkedList<BeatBox.Media> similarDont) {
551 similar_retrieved(similarIDs, similarDont);534 similar_retrieved(similarIDs, similarDont);
552 }535 }
553 536
@@ -569,19 +552,19 @@
569 552
570 public void fetch_remaining_album_art() {553 public void fetch_remaining_album_art() {
571 try {554 try {
572 Thread.create<void*>(fetch_remaining_album_art_thread, false);555 new Thread<void*>.try (null, fetch_remaining_album_art_thread);
573 } catch(GLib.ThreadError err) {556 } catch (Error err) {
574 warning ("ERROR: Could not create last fm thread: %s \n", err.message);557 warning ("Could not create last fm thread: %s", err.message);
575 }558 }
576 }559 }
577 560
578 public void* fetch_remaining_album_art_thread() {561 public void* fetch_remaining_album_art_thread() {
579 var all_media = lm.medias();562 var all_media = lm.medias();
580 var remaining = new HashMap<string, BeatBox.Album>(); // hashmap of albums with no art563 var remaining = new Gee.HashMap<string, BeatBox.Album>(); // hashmap of albums with no art
581 foreach(var m in all_media) {564 foreach(var m in all_media) {
582 string key = lm.album_key(m);565 string key = lm.album_key(m);
583 566
584 if(remaining.get(key) != null) // already known567 if (remaining.has_key (key)) // already known
585 continue;568 continue;
586 569
587 if(lm.get_cover_album_art(m.rowid) == null) {570 if(lm.get_cover_album_art(m.rowid) == null) {
@@ -603,12 +586,12 @@
603 586
604 /* If we found an album art, save it to file **/587 /* If we found an album art, save it to file **/
605 if(album_info != null && album_info.url_image.url != null && album_info.url_image.url != "") {588 if(album_info != null && album_info.url_image.url != null && album_info.url_image.url != "") {
606 debug("Saving album image locally for %s by %s\n", album_s, album_artist_s);589 debug("Saving album image locally for %s by %s", album_s, album_artist_s);
607 lm.save_album_locally(m.rowid, album_info.url_image.url, false);590 lm.save_album_locally(m.rowid, album_info.url_image.url, false);
608 }591 }
609 }592 }
610 593
611 message("All remaining art fetched\n");594 message("All remaining art fetched");
612 595
613 return null;596 return null;
614 }597 }
615598
=== modified file 'src/Lastfm/SimilarMedia.vala'
--- src/Lastfm/SimilarMedia.vala 2012-06-02 19:34:06 +0000
+++ src/Lastfm/SimilarMedia.vala 2012-07-03 06:49:24 +0000
@@ -20,8 +20,6 @@
20 * Boston, MA 02111-1307, USA.20 * Boston, MA 02111-1307, USA.
21 */21 */
2222
23using Xml;
24
25public class LastFM.SimilarMedias : Object {23public class LastFM.SimilarMedias : Object {
26 BeatBox.LibraryManager _lm;24 BeatBox.LibraryManager _lm;
27 BeatBox.Media _base;25 BeatBox.Media _base;
@@ -29,7 +27,7 @@
29 27
30 Gee.LinkedList<BeatBox.Media> similar;28 Gee.LinkedList<BeatBox.Media> similar;
31 29
32 public signal void similar_retrieved( Gee.LinkedList<int> similarIDs, Gee.LinkedList<BeatBox.Media> similarDont);30 public signal void similar_retrieved (Gee.LinkedList<int> similarIDs, Gee.LinkedList<BeatBox.Media> similarDont);
33 31
34 public class SimilarMedias(BeatBox.LibraryManager lm) {32 public class SimilarMedias(BeatBox.LibraryManager lm) {
35 _lm = lm;33 _lm = lm;
@@ -43,10 +41,10 @@
43 working = true;41 working = true;
44 42
45 try {43 try {
46 Thread.create<void*>(similar_thread_function, false);44 new Thread<void*>.try (null, similar_thread_function);
47 }45 }
48 catch(GLib.ThreadError err) {46 catch (Error err) {
49 warning("ERROR: Could not create similar thread: %s \n", err.message);47 warning ("Could not create similar thread: %s", err.message);
50 }48 }
51 }49 }
52 }50 }
@@ -107,7 +105,7 @@
107 Xml.Node* iter;105 Xml.Node* iter;
108 for (iter = node->children; iter != null; iter = iter->next) {106 for (iter = node->children; iter != null; iter = iter->next) {
109 107
110 if (iter->type != ElementType.ELEMENT_NODE) {108 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
111 continue;109 continue;
112 }110 }
113111
114112
=== modified file 'src/Lastfm/TopArtistAlbums.vala'
--- src/Lastfm/TopArtistAlbums.vala 2012-07-02 23:17:27 +0000
+++ src/Lastfm/TopArtistAlbums.vala 2012-07-03 06:49:24 +0000
@@ -20,8 +20,6 @@
20 * Boston, MA 02111-1307, USA.20 * Boston, MA 02111-1307, USA.
21 */21 */
2222
23using Xml;
24
25public class LastFM.TopArtistAlbums : Object {23public class LastFM.TopArtistAlbums : Object {
26 static const int MAX_RESULTS = 5;24 static const int MAX_RESULTS = 5;
27 BeatBox.LibraryManager _lm;25 BeatBox.LibraryManager _lm;
@@ -46,10 +44,10 @@
46 working = true;44 working = true;
47 45
48 try {46 try {
49 Thread.create<void*>(top_artist_albums_thread_function, false);47 new Thread<void*>.try (null, top_artist_albums_thread_function);
50 }48 }
51 catch(GLib.ThreadError err) {49 catch (Error err) {
52 warning("ERROR: Could not create top artist albums thread: %s \n", err.message);50 warning ("ERROR: Could not create top artist albums thread: %s", err.message);
53 }51 }
54 }52 }
55 }53 }
@@ -79,7 +77,7 @@
79 async void uri_to_pixbuf(BeatBox.ExternalAlbum album) {77 async void uri_to_pixbuf(BeatBox.ExternalAlbum album) {
80 GLib.File file = GLib.File.new_for_uri(album.pixbuf_url);78 GLib.File file = GLib.File.new_for_uri(album.pixbuf_url);
81 if(file == null) {79 if(file == null) {
82 stdout.printf("Could not read image_uri as file\n");80 message ("Could not read image_uri as file");
83 return;81 return;
84 }82 }
85 83
@@ -90,7 +88,11 @@
90 filestream = yield file.read_async();88 filestream = yield file.read_async();
91 pix = yield Gdk.Pixbuf.new_from_stream_at_scale_async(filestream, -1, Icons.ALBUM_VIEW_IMAGE_SIZE, true);89 pix = yield Gdk.Pixbuf.new_from_stream_at_scale_async(filestream, -1, Icons.ALBUM_VIEW_IMAGE_SIZE, true);
92 } catch(GLib.Error err) {90 } catch(GLib.Error err) {
91<<<<<<< TREE
93 debug("Failed to save load art locally from %s: %s\n", album.pixbuf_url, err.message);92 debug("Failed to save load art locally from %s: %s\n", album.pixbuf_url, err.message);
93=======
94 warning("Failed to save album art locally from %s: %s", album.pixbuf_url, err.message);
95>>>>>>> MERGE-SOURCE
94 }96 }
95 97
96 if(pix != null) {98 if(pix != null) {
@@ -113,11 +115,11 @@
113 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);115 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);
114 116
115 if(doc == null)117 if(doc == null)
116 GLib.message("Could not load top artist albums information for %s\n", artist);118 GLib.message("Could not load top artist albums information for %s", artist);
117 else if(doc->get_root_element() == null)119 else if(doc->get_root_element() == null)
118 GLib.message("Oddly, top artist albums information was invalid\n");120 GLib.message("Oddly, top artist albums information was invalid");
119 else {121 else {
120 //GLib.message("Getting top artist albums with %s... \n", url);122 //GLib.message("Getting top artist albums with %s...", url);
121 toAdd = null;123 toAdd = null;
122 124
123 parse_top_artist_albums_nodes(doc->get_root_element(), "");125 parse_top_artist_albums_nodes(doc->get_root_element(), "");
@@ -132,7 +134,7 @@
132 134
133 Xml.Node* iter;135 Xml.Node* iter;
134 for (iter = node->children; iter != null; iter = iter->next) {136 for (iter = node->children; iter != null; iter = iter->next) {
135 if (iter->type != ElementType.ELEMENT_NODE) {137 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
136 continue;138 continue;
137 }139 }
138140
139141
=== modified file 'src/Lastfm/TopArtistSongs.vala'
--- src/Lastfm/TopArtistSongs.vala 2012-06-02 19:34:06 +0000
+++ src/Lastfm/TopArtistSongs.vala 2012-07-03 06:49:24 +0000
@@ -20,8 +20,6 @@
20 * Boston, MA 02111-1307, USA.20 * Boston, MA 02111-1307, USA.
21 */21 */
2222
23using Xml;
24
25public class LastFM.TopArtistSongs : Object {23public class LastFM.TopArtistSongs : Object {
26 static const int MAX_RESULTS = 15;24 static const int MAX_RESULTS = 15;
27 BeatBox.LibraryManager _lm;25 BeatBox.LibraryManager _lm;
@@ -46,15 +44,15 @@
46 working = true;44 working = true;
47 45
48 try {46 try {
49 Thread.create<void*>(top_artist_songs_thread_function, false);47 new Thread<void*>.try (null, top_artist_songs_thread_function);
50 }48 }
51 catch(GLib.ThreadError err) {49 catch (Error err) {
52 warning("ERROR: Could not create similar thread: %s \n", err.message);50 warning("ERROR: Could not create similar thread: %s", err.message);
53 }51 }
54 }52 }
55 }53 }
56 54
57 void* top_artist_songs_thread_function () { 55 private void* top_artist_songs_thread_function () {
58 songs = new HashTable<int, BeatBox.Media>(null, null);56 songs = new HashTable<int, BeatBox.Media>(null, null);
59 57
60 getTopArtistTracks(_base.artist);58 getTopArtistTracks(_base.artist);
@@ -96,11 +94,11 @@
96 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);94 Xml.Doc* doc = Xml.Parser.parse_memory((string)message.response_body.data, (int)message.response_body.length);
97 95
98 if(doc == null)96 if(doc == null)
99 GLib.message("Could not load top artist songs information for %s\n", artist);97 GLib.message("Could not load top artist songs information for %s", artist);
100 else if(doc->get_root_element() == null)98 else if(doc->get_root_element() == null)
101 GLib.message("Oddly, similar artist information was invalid\n");99 GLib.message("Oddly, similar artist information was invalid");
102 else {100 else {
103 //message("Getting similar tracks with %s... \n", url);101 //message("Getting similar tracks with %s...", url);
104 toAdd = null;102 toAdd = null;
105 103
106 parse_top_artist_tracks_nodes(doc->get_root_element(), "");104 parse_top_artist_tracks_nodes(doc->get_root_element(), "");
@@ -115,7 +113,7 @@
115 113
116 Xml.Node* iter;114 Xml.Node* iter;
117 for (iter = node->children; iter != null; iter = iter->next) {115 for (iter = node->children; iter != null; iter = iter->next) {
118 if (iter->type != ElementType.ELEMENT_NODE) {116 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
119 continue;117 continue;
120 }118 }
121119
122120
=== modified file 'src/Lists/GenericList.vala'
--- src/Lists/GenericList.vala 2012-06-28 02:26:50 +0000
+++ src/Lists/GenericList.vala 2012-07-03 06:49:24 +0000
@@ -278,10 +278,10 @@
278 // For songs with no attached uri, try opening its lastfm url278 // For songs with no attached uri, try opening its lastfm url
279 if(m.uri == "") {279 if(m.uri == "") {
280 try {280 try {
281 Thread.create<void*>(take_action, false);281 new Thread<void*>.try (null, take_action);
282 }282 }
283 catch(GLib.ThreadError err) {283 catch (Error err) {
284 stdout.printf("ERROR: Could not create thread to have fun: %s \n", err.message);284 warning ("Could not create thread to have fun: %s", err.message);
285 }285 }
286 }286 }
287 else {287 else {
288288
=== modified file 'src/Media/LyricFetcher.vala'
--- src/Media/LyricFetcher.vala 2012-06-01 22:48:28 +0000
+++ src/Media/LyricFetcher.vala 2012-07-03 06:49:24 +0000
@@ -42,10 +42,10 @@
42 this.title = title;42 this.title = title;
43 43
44 try {44 try {
45 Thread.create<void*> (fetch_lyrics_thread, false);45 new Thread<void*>.try (null, fetch_lyrics_thread);
46 }46 }
47 catch(GLib.ThreadError err) {47 catch(GLib.Error err) {
48 stderr.printf ("ERROR: Could not create lyrics thread: %s \n", err.message);48 warning ("ERROR: Could not create lyrics thread: %s \n", err.message);
49 }49 }
50 }50 }
51 51
@@ -87,7 +87,7 @@
8787
88/** LYRIC SOURCES **/88/** LYRIC SOURCES **/
8989
90private class AZLyricsFetcher : Object {90private class AZLyricsFetcher {
9191
92 private const string URL_FORMAT = "http://www.azlyrics.com/lyrics/%s/%s.html";92 private const string URL_FORMAT = "http://www.azlyrics.com/lyrics/%s/%s.html";
9393
@@ -108,7 +108,7 @@
108 rv.artist = artist;108 rv.artist = artist;
109 }109 }
110 catch (Error err) {110 catch (Error err) {
111 //stderr.printf("Could not load contents of %s : %s\n", url, err.message);111 //warning("Could not load contents of %s : %s\n", url, err.message);
112 load_successful = false;112 load_successful = false;
113 }113 }
114114
@@ -122,13 +122,13 @@
122 load_successful = true;122 load_successful = true;
123 }123 }
124 catch (Error err) {124 catch (Error err) {
125 //stderr.printf ("Could not load contents of %s : %s\n", url, err.message);125 //warning ("Could not load contents of %s : %s\n", url, err.message);
126 load_successful = false;126 load_successful = false;
127 }127 }
128 }128 }
129 129
130 if (load_successful)130 if (load_successful)
131 rv.content = parse_lyrics (uintcontent) + "\n";131 rv.content = "\n" + rv.title + "\n" + rv.artist + "\n\n\n" + parse_lyrics (uintcontent) + "\n";
132 else132 else
133 throw new FetchingError.LYRICS_NOT_FOUND (@"Lyrics not found for $title"); 133 throw new FetchingError.LYRICS_NOT_FOUND (@"Lyrics not found for $title");
134134
135135
=== modified file 'src/Store/Widgets/AlbumView.vala'
--- src/Store/Widgets/AlbumView.vala 2012-06-01 22:48:28 +0000
+++ src/Store/Widgets/AlbumView.vala 2012-07-03 06:49:24 +0000
@@ -174,20 +174,21 @@
174 174
175 public void populate() {175 public void populate() {
176 try {176 try {
177 Thread.create<void*>(setalbum_thread_function, false);177 new Thread<void*>.try (null, setalbum_thread_function);
178 Thread.create<void*>(gettracks_thread_function, false);178 new Thread<void*>.try (null, gettracks_thread_function);
179 Thread.create<void*>(getsimilarreleases_thread_function, false);179 new Thread<void*>.try (null, getsimilarreleases_thread_function);
180 Thread.create<void*>(getalbuminfo_thread_function, false);180 new Thread<void*>.try (null, getalbuminfo_thread_function);
181
181 storeView.max = 5;182 storeView.max = 5;
182 storeView.index = 0;183 storeView.index = 0;
183 storeView.progressNotification();184 storeView.progressNotification();
184 }185 }
185 catch(GLib.ThreadError err) {186 catch (Error err) {
186 stdout.printf("ERROR: Could not create thread to get populate ArtistView: %s \n", err.message);187 warning ("Could not create thread to get populate ArtistView: %s", err.message);
187 }188 }
188 }189 }
189 190
190 public void* setalbum_thread_function () {191 private void* setalbum_thread_function () {
191 Store.Release r = store.getRelease(release.releaseID, 200);192 Store.Release r = store.getRelease(release.releaseID, 200);
192 r.image = Store.store.getPixbuf(r.imagePath, 200, 200);193 r.image = Store.store.getPixbuf(r.imagePath, 200, 200);
193 194
@@ -198,7 +199,7 @@
198 ++storeView.index;199 ++storeView.index;
199 200
200 try {201 try {
201 Thread.create<void*>(gettaglabels_thread_function, false);202 new Thread<void*>.try (null, gettaglabels_thread_function);
202 }203 }
203 catch (Error e) {204 catch (Error e) {
204 critical ("Couldn't get tags: %s", e.message);205 critical ("Couldn't get tags: %s", e.message);
@@ -227,7 +228,7 @@
227 return null;228 return null;
228 }229 }
229 230
230 public void* getsimilarreleases_thread_function () {231 private void* getsimilarreleases_thread_function () {
231 foreach(var rel in release.getSimilar(1)) {232 foreach(var rel in release.getSimilar(1)) {
232 rel.image = Store.store.getPixbuf(rel.imagePath, 100, 100);233 rel.image = Store.store.getPixbuf(rel.imagePath, 100, 100);
233 similarReleasesList.add(rel);234 similarReleasesList.add(rel);
@@ -246,7 +247,7 @@
246 return null;247 return null;
247 }248 }
248 249
249 public void* gettaglabels_thread_function () {250 private void* gettaglabels_thread_function () {
250 var labels = new LinkedList<Store.TagLabel>();251 var labels = new LinkedList<Store.TagLabel>();
251 252
252 foreach(var format in release.formats) {253 foreach(var format in release.formats) {
@@ -289,7 +290,7 @@
289 return null;290 return null;
290 }291 }
291 292
292 public void* getalbuminfo_thread_function () {293 private void* getalbuminfo_thread_function () {
293 /* first get album description */294 /* first get album description */
294 LastFM.AlbumInfo album = new LastFM.AlbumInfo.basic();295 LastFM.AlbumInfo album = new LastFM.AlbumInfo.basic();
295 296
296297
=== modified file 'src/Store/Widgets/ArtistView.vala'
--- src/Store/Widgets/ArtistView.vala 2012-02-04 00:01:35 +0000
+++ src/Store/Widgets/ArtistView.vala 2012-07-03 06:49:24 +0000
@@ -58,7 +58,7 @@
58 setArtist(artist);58 setArtist(artist);
59 }59 }
60 60
61 public void buildUI() {61 private void buildUI() {
62 VBox allDetails = new VBox(false, 0);62 VBox allDetails = new VBox(false, 0);
63 HBox topRow = new HBox(false, 0);63 HBox topRow = new HBox(false, 0);
64 VBox topInfo = new VBox(false, 0);64 VBox topInfo = new VBox(false, 0);
@@ -110,19 +110,19 @@
110 110
111 public void populate() {111 public void populate() {
112 try {112 try {
113 Thread.create<void*>(setartist_thread_function, false);113 new Thread<void*>.try (null, setartist_thread_function);
114 Thread.create<void*>(gettracks_thread_function, false);114 new Thread<void*>.try (null, gettracks_thread_function);
115 Thread.create<void*>(getreleases_thread_function, false);115 new Thread<void*>.try (null, getreleases_thread_function);
116 storeView.index = 0;116 storeView.index = 0;
117 storeView.max = 5; // must get to 6 for progress bar to turn off117 storeView.max = 5; // must get to 6 for progress bar to turn off
118 storeView.progressNotification();118 storeView.progressNotification();
119 }119 }
120 catch(GLib.ThreadError err) {120 catch (Error err) {
121 stdout.printf("ERROR: Could not create thread to get populate ArtistView: %s \n", err.message);121 warning ("Could not create thread to get populate ArtistView: %s", err.message);
122 }122 }
123 }123 }
124 124
125 public void* setartist_thread_function () {125 private void* setartist_thread_function () {
126 Store.Artist a = store.getArtist(artist.artistID);126 Store.Artist a = store.getArtist(artist.artistID);
127 ++storeView.index;127 ++storeView.index;
128 Idle.add( () => { 128 Idle.add( () => {
@@ -134,7 +134,7 @@
134 return null;134 return null;
135 }135 }
136 136
137 public void* gettracks_thread_function () {137 private void* gettracks_thread_function () {
138 foreach(var track in artist.getTopTracks(1, 25))138 foreach(var track in artist.getTopTracks(1, 25))
139 topTracksList.add(track);139 topTracksList.add(track);
140 ++storeView.index;140 ++storeView.index;
@@ -149,7 +149,7 @@
149 return null;149 return null;
150 }150 }
151 151
152 public void* getreleases_thread_function () {152 private void* getreleases_thread_function () {
153 foreach(var rel in artist.getReleases("album", 1)) {153 foreach(var rel in artist.getReleases("album", 1)) {
154 rel.image = Store.store.getPixbuf(rel.imagePath, 100, 100);154 rel.image = Store.store.getPixbuf(rel.imagePath, 100, 100);
155 releasesList.add(rel);155 releasesList.add(rel);
156156
=== modified file 'src/Store/Widgets/HomeView.vala'
--- src/Store/Widgets/HomeView.vala 2012-02-04 00:01:35 +0000
+++ src/Store/Widgets/HomeView.vala 2012-07-03 06:49:24 +0000
@@ -41,7 +41,7 @@
41 buildUI();41 buildUI();
42 }42 }
43 43
44 public void buildUI() {44 private void buildUI() {
45 allItems = new HBox(false, 0);45 allItems = new HBox(false, 0);
46 VBox leftItems = new VBox(false, 0);46 VBox leftItems = new VBox(false, 0);
47 VBox centerItems = new VBox(false, 0);47 VBox centerItems = new VBox(false, 0);
@@ -98,6 +98,7 @@
98 98
99 }99 }
100 100
101 // TODO: Move to utils namespace!!
101 public static Gtk.Alignment wrap_alignment (Gtk.Widget widget, int top, int right, int bottom, int left) {102 public static Gtk.Alignment wrap_alignment (Gtk.Widget widget, int top, int right, int bottom, int left) {
102 var alignment = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 1.0f);103 var alignment = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 1.0f);
103 alignment.top_padding = top;104 alignment.top_padding = top;
@@ -111,21 +112,22 @@
111 112
112 public void populate() {113 public void populate() {
113 try {114 try {
114 Thread.create<void*>(getartists_thread_function, false);115 new Thread<void*>.try (null, getartists_thread_function);
115 Thread.create<void*>(getreleases_thread_function, false);116 new Thread<void*>.try (null, getreleases_thread_function);
116 Thread.create<void*>(gettracks_thread_function, false);117 new Thread<void*>.try (null, gettracks_thread_function);
117 Thread.create<void*>(gettoprock_thread_function, false);118 new Thread<void*>.try (null, gettoprock_thread_function);
118 Thread.create<void*>(getgenres_thread_function, false);119 new Thread<void*>.try (null, getgenres_thread_function);
120
119 storeView.max = 6;121 storeView.max = 6;
120 storeView.index = 0;122 storeView.index = 0;
121 storeView.progressNotification();123 storeView.progressNotification();
122 }124 }
123 catch(GLib.ThreadError err) {125 catch (Error err) {
124 stdout.printf("ERROR: Could not create thread to get populate ArtistView: %s \n", err.message);126 warning ("Could not create thread to get populate ArtistView: %s", err.message);
125 }127 }
126 }128 }
127 129
128 public void* getartists_thread_function () {130 private void* getartists_thread_function () {
129 var tops = new LinkedList<Artist>();131 var tops = new LinkedList<Artist>();
130 132
131 foreach(var art in store.topArtists("week", null, null, 1))133 foreach(var art in store.topArtists("week", null, null, 1))
@@ -144,7 +146,7 @@
144 return null;146 return null;
145 }147 }
146 148
147 public void* getreleases_thread_function () {149 private void* getreleases_thread_function () {
148 var tops = new LinkedList<Release>();150 var tops = new LinkedList<Release>();
149 151
150 foreach(var rel in store.topReleases("week", null, null, 1)) {152 foreach(var rel in store.topReleases("week", null, null, 1)) {
@@ -163,7 +165,7 @@
163 return null;165 return null;
164 }166 }
165 167
166 public void* gettracks_thread_function () {168 private void* gettracks_thread_function () {
167 var tops = new LinkedList<Track>();169 var tops = new LinkedList<Track>();
168 170
169 foreach(var track in store.topTracks("week", null, 1))171 foreach(var track in store.topTracks("week", null, 1))
@@ -182,7 +184,7 @@
182 return null;184 return null;
183 }185 }
184 186
185 public void* gettoprock_thread_function () {187 private void* gettoprock_thread_function () {
186 var rock = new LinkedList<Release>();188 var rock = new LinkedList<Release>();
187 189
188 foreach(var rel in store.topReleases("week", null, "rock", 1)) {190 foreach(var rel in store.topReleases("week", null, "rock", 1)) {
@@ -203,7 +205,7 @@
203 return null;205 return null;
204 }206 }
205 207
206 public void* getgenres_thread_function () {208 private void* getgenres_thread_function () {
207 var gens = new LinkedList<Tag>();209 var gens = new LinkedList<Tag>();
208 210
209 gens.add( new Tag.with_values("pop", "Pop", "") );211 gens.add( new Tag.with_values("pop", "Pop", "") );
210212
=== modified file 'src/Store/Widgets/StoreView.vala'
--- src/Store/Widgets/StoreView.vala 2012-03-16 05:21:31 +0000
+++ src/Store/Widgets/StoreView.vala 2012-07-03 06:49:24 +0000
@@ -94,16 +94,16 @@
94 setView(searchPage);94 setView(searchPage);
95 95
96 try {96 try {
97 Thread.create<void*>(searchtracks_thread_function, false);97 new Thread<void*>.try (null, searchtracks_thread_function);
98 Thread.create<void*>(searchartists_thread_function, false);98 new Thread<void*>.try (null, searchartists_thread_function);
99 Thread.create<void*>(searchreleases_thread_function, false);99 new Thread<void*>.try (null, searchreleases_thread_function);
100 }100 }
101 catch(GLib.ThreadError err) {101 catch (Error err) {
102 stdout.printf("ERROR: Could not create thread to get populate ArtistView: %s \n", err.message);102 warning ("Could not create thread to get populate ArtistView: %s", err.message);
103 }103 }
104 }104 }
105 105
106 public void* searchtracks_thread_function () {106 private void* searchtracks_thread_function () {
107 var search = new LinkedList<Store.Track>();107 var search = new LinkedList<Store.Track>();
108 108
109 foreach(var track in store.searchTracks(lw.searchField.get_text(), 1))109 foreach(var track in store.searchTracks(lw.searchField.get_text(), 1))
@@ -119,7 +119,7 @@
119 return null;119 return null;
120 }120 }
121 121
122 public void* searchartists_thread_function () {122 private void* searchartists_thread_function () {
123 var search = new LinkedList<Store.Artist>();123 var search = new LinkedList<Store.Artist>();
124 124
125 foreach(var artist in store.searchArtists(lw.searchField.get_text(), null, 1))125 foreach(var artist in store.searchArtists(lw.searchField.get_text(), null, 1))
@@ -135,7 +135,7 @@
135 return null;135 return null;
136 }136 }
137 137
138 public void* searchreleases_thread_function () {138 private void* searchreleases_thread_function () {
139 var search = new LinkedList<Store.Release>();139 var search = new LinkedList<Store.Release>();
140 140
141 foreach(var rel in store.searchReleases(lw.searchField.get_text(), 1))141 foreach(var rel in store.searchReleases(lw.searchField.get_text(), 1))
142142
=== modified file 'src/Views/SimilarMediaView.vala'
--- src/Views/SimilarMediaView.vala 2012-06-19 22:50:13 +0000
+++ src/Views/SimilarMediaView.vala 2012-07-03 06:49:24 +0000
@@ -83,10 +83,10 @@
83 83
84 public virtual void viewDoubleClick(TreePath path, TreeViewColumn column) {84 public virtual void viewDoubleClick(TreePath path, TreeViewColumn column) {
85 try {85 try {
86 Thread.create<void*>(take_action, false);86 new Thread<void*>.try (null, take_action);
87 }87 }
88 catch(GLib.ThreadError err) {88 catch (Error err) {
89 stdout.printf("ERROR: Could not create thread to have fun: %s \n", err.message);89 warning ("Could not create thread to have fun: %s", err.message);
90 }90 }
91 }91 }
92 92
@@ -117,8 +117,8 @@
117 try {117 try {
118 GLib.AppInfo.launch_default_for_uri (s.lastfm_url, null);118 GLib.AppInfo.launch_default_for_uri (s.lastfm_url, null);
119 }119 }
120 catch(Error err) {120 catch (Error err) {
121 stdout.printf("Couldn't open the similar media's last fm page: %s\n", err.message);121 warning ("Couldn't open the similar media's last fm page: %s", err.message);
122 }122 }
123 }123 }
124 124
125125
=== modified file 'src/Widgets/EmbeddedAlert.vala'
--- src/Widgets/EmbeddedAlert.vala 2012-06-25 23:39:54 +0000
+++ src/Widgets/EmbeddedAlert.vala 2012-07-03 06:49:24 +0000
@@ -20,12 +20,6 @@
20 * Authored by: Victor Eduardo <victoreduardm@gmail.com>20 * Authored by: Victor Eduardo <victoreduardm@gmail.com>
21 */21 */
2222
23/**
24 * An alert compliant with elementary's HIG
25 *
26 * TODO: Add description and examples
27 */
28
29public class BeatBox.EmbeddedAlert : Gtk.EventBox {23public class BeatBox.EmbeddedAlert : Gtk.EventBox {
3024
31 const string ERROR_ICON = "dialog-error";25 const string ERROR_ICON = "dialog-error";
@@ -43,11 +37,11 @@
43 protected Gtk.ButtonBox action_button_box;37 protected Gtk.ButtonBox action_button_box;
4438
45 const int MIN_HORIZONTAL_MARGIN = 84;39 const int MIN_HORIZONTAL_MARGIN = 84;
46 const int MIN_VERTICAL_MARGIN = 48;40 const int MIN_VERTICAL_MARGIN = 6;
4741
48 public EmbeddedAlert () {42 public EmbeddedAlert () {
49 get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);43 get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);
50 //get_style_context ().add_class (Granite.STYLE_CLASS_CONTENT_VIEW); // This variable is not in granite version in universe44 get_style_context ().add_class (Granite.STYLE_CLASS_CONTENT_VIEW);
5145
52 action_button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);46 action_button_box = new Gtk.ButtonBox (Gtk.Orientation.HORIZONTAL);
53 action_button_box.valign = Gtk.Align.START;47 action_button_box.valign = Gtk.Align.START;
@@ -125,7 +119,7 @@
125 bool show_icon = true, Gtk.MessageType type = Gtk.MessageType.WARNING)119 bool show_icon = true, Gtk.MessageType type = Gtk.MessageType.WARNING)
126 {120 {
127 // Reset size request121 // Reset size request
128 set_size_request (1, 1);122 set_size_request (0, 0);
129123
130 if (primary_text == null)124 if (primary_text == null)
131 primary_text = "";125 primary_text = "";
132126
=== modified file 'src/Widgets/SearchSuggester.vala'
--- src/Widgets/SearchSuggester.vala 2012-06-01 22:48:28 +0000
+++ src/Widgets/SearchSuggester.vala 2012-07-03 06:49:24 +0000
@@ -71,9 +71,9 @@
71 //Timeout.add(750, () => {71 //Timeout.add(750, () => {
72 if(new_search == last_search && new_search.length > 2) {72 if(new_search == last_search && new_search.length > 2) {
73 try {73 try {
74 Thread.create<void*>(update_contents, false);74 new Thread<void*>.try (null, update_contents);
75 } catch(GLib.ThreadError err) {75 } catch (Error err) {
76 warning ("ERROR: Could not create search suggester thread: %s \n", err.message);76 warning ("Could not create search suggester thread: %s", err.message);
77 }77 }
78 }78 }
79 else if(new_search.length <= 2) {79 else if(new_search.length <= 2) {
8080
=== modified file 'src/Widgets/StatusBar.vala'
--- src/Widgets/StatusBar.vala 2012-03-04 00:33:20 +0000
+++ src/Widgets/StatusBar.vala 2012-07-03 06:49:24 +0000
@@ -22,81 +22,16 @@
2222
23using Gtk;23using Gtk;
2424
25public class BeatBox.StatusBar : Gtk.Toolbar {25public class BeatBox.StatusBar : Granite.Widgets.StatusBar {
2626
27 public uint total_items {get; private set; default = 0;}27 public uint total_items {get; private set; default = 0;}
28 public uint total_mbs {get; private set; default = 0;}28 public uint total_mbs {get; private set; default = 0;}
29 public uint total_secs {get; private set; default = 0;}29 public uint total_secs {get; private set; default = 0;}
30 public ViewWrapper.Hint media_type {get; private set;}30 public ViewWrapper.Hint media_type {get; private set;}
3131
32 private Label status_label;
33 private Box left_box;
34 private Box right_box;
35
36 private CssProvider style_provider;
37 private StyleContext context;
38
39 private string STATUS_TEXT_FORMAT = _("%s, %s, %s");32 private string STATUS_TEXT_FORMAT = _("%s, %s, %s");
4033
41 private const string STATUSBAR_STYLESHEET = """
42 BeatBoxStatusBar {
43 border-bottom-width: 0;
44 border-right-width: 0;
45 border-left-width: 0;
46
47 -GtkWidget-window-dragging: false;
48 }
49
50 /* This prevents the huge vertical padding */
51 BeatBoxStatusBar .button {
52 padding: 0px;
53 }
54 """;
55
56 public StatusBar () {34 public StatusBar () {
57
58 style_provider = new CssProvider ();
59
60 try {
61 style_provider.load_from_data (STATUSBAR_STYLESHEET, -1);
62 }
63 catch (Error err) {
64 warning (err.message);
65 }
66
67 /* Get rid of the "toolbar" class to avoid inheriting its style,
68 since we want the widget to look more like a normal statusbar. */
69 get_style_context ().remove_class (STYLE_CLASS_TOOLBAR);
70
71 context = new StyleContext ();
72 context.add_provider_for_screen (get_screen (), style_provider, STYLE_PROVIDER_PRIORITY_THEME);
73
74 status_label = new Label ("");
75 status_label.set_justify (Justification.CENTER);
76
77 left_box = new Box (Orientation.HORIZONTAL, 0);
78 right_box = new Box (Orientation.HORIZONTAL, 0);
79
80 var left_item = new ToolItem ();
81 var status_label_item = new ToolItem ();
82 var right_item = new ToolItem ();
83
84 left_item.add (left_box);
85 status_label_item.add (status_label);
86 right_item.add (right_box);
87
88 status_label_item.set_expand (true);
89
90 this.insert (left_item, 0);
91 this.insert (status_label_item, 1);
92 this.insert (right_item, 2);
93 }
94
95 public void insert_widget (Gtk.Widget widget, bool? use_left_side = false) {
96 if (use_left_side)
97 left_box.pack_start (widget, false, false, 3);
98 else
99 right_box.pack_start (widget, false, false, 3);
100 }35 }
10136
102 public void set_files_size (uint total_mbs) {37 public void set_files_size (uint total_mbs) {
10338
=== modified file 'src/Widgets/StyledWidgets/StyledArtistImages.vala'
--- src/Widgets/StyledWidgets/StyledArtistImages.vala 2012-07-02 23:17:27 +0000
+++ src/Widgets/StyledWidgets/StyledArtistImages.vala 2012-07-03 06:49:24 +0000
@@ -22,7 +22,6 @@
2222
23using Gee;23using Gee;
24using Gtk;24using Gtk;
25using Xml;
2625
27public class BeatBox.StyledArtistImages : EventBox {26public class BeatBox.StyledArtistImages : EventBox {
28 const string api = "YOFT4SZFVZLZZ1SVT";27 const string api = "YOFT4SZFVZLZZ1SVT";
@@ -118,13 +117,13 @@
118 images = new LinkedList<Gdk.Pixbuf>();117 images = new LinkedList<Gdk.Pixbuf>();
119 118
120 try {119 try {
121 Thread.create<void*>(fetch_thread_function, false);120 new Thread<void*>.try (null, fetch_thread_function);
122 } catch(GLib.ThreadError err) {121 } catch(Error err) {
123 warning("Could not create thread to load artist pixbuf's: %s \n", err.message);122 warning ("Could not create thread to load artist pixbuf's: %s", err.message);
124 }123 }
125 }124 }
126 125
127 public void* fetch_thread_function () {126 private void* fetch_thread_function () {
128 var url = "http://developer.echonest.com/api/v4/artist/images?api_key=" + api + "&name=" + 127 var url = "http://developer.echonest.com/api/v4/artist/images?api_key=" + api + "&name=" +
129 LastFM.Core.fix_for_url(current_artist) + "&format=xml&start=0&results=15";128 LastFM.Core.fix_for_url(current_artist) + "&format=xml&start=0&results=15";
130 129
@@ -197,7 +196,7 @@
197 // Loop over the passed node's children196 // Loop over the passed node's children
198 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {197 for (Xml.Node* iter = node->children; iter != null; iter = iter->next) {
199 // Spaces between tags are also nodes, discard them198 // Spaces between tags are also nodes, discard them
200 if (iter->type != ElementType.ELEMENT_NODE) {199 if (iter->type != Xml.ElementType.ELEMENT_NODE) {
201 continue;200 continue;
202 }201 }
203 202
204203
=== removed file 'src/Widgets/WarningLabel.vala'
--- src/Widgets/WarningLabel.vala 2012-03-29 08:46:09 +0000
+++ src/Widgets/WarningLabel.vala 1970-01-01 00:00:00 +0000
@@ -1,99 +0,0 @@
1/*-
2 * Copyright (c) 2011-2012 Scott Ringwelski <sgringwe@mtu.edu>
3 *
4 * Originally Written by Scott Ringwelski for BeatBox Music Player
5 * BeatBox Music Player: http://www.launchpad.net/beat-box
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23using Gtk;
24
25public class BeatBox.WarningLabel : EventBox {
26
27 private Label errorLabel; // FIXME: Use Granite.Widgets.WrapLabel
28 private Image warningIcon;
29
30 public bool show_icon {
31 get {
32 return warningIcon.visible;
33 }
34 set {
35 warningIcon.set_no_show_all (!value);
36 warningIcon.set_visible (value);
37 }
38 }
39
40 public WarningLabel(string icon_name = "dialog-warning") {
41 errorLabel = new Label("");
42 warningIcon = Icons.render_image (icon_name, Gtk.IconSize.DIALOG);
43
44 //FIXME: use margins
45 var content = new Box (Orientation.HORIZONTAL, 10);
46 var content_wrapper = new Box (Orientation.HORIZONTAL, 0);
47 var outer_box = new Box (Orientation.VERTICAL, 0);
48 var top_padding = new Box (Orientation.VERTICAL, 0);
49 var bottom_padding = new Box (Orientation.VERTICAL, 0);
50 var left_padding = new Box (Orientation.HORIZONTAL, 0);
51 var right_padding = new Box (Orientation.HORIZONTAL, 0);
52
53 content.pack_start (wrap_alignment(warningIcon, 0, 10, 10, 10), false, false, 0);
54 content.pack_start (errorLabel, false, true, 0);
55
56 content_wrapper.pack_start (left_padding, true, true, 0);
57 content_wrapper.pack_start (content, false, true, 0);
58 content_wrapper.pack_start (right_padding, true, true, 0);
59
60 outer_box.pack_start (top_padding, true, true, 0);
61 outer_box.pack_start (content_wrapper, false, true, 10);
62 outer_box.pack_start (bottom_padding, true, true, 0);
63
64 add(outer_box);
65
66 // Add view-like theming
67 get_style_context ().add_class (Gtk.STYLE_CLASS_VIEW);
68
69 errorLabel.xalign = 0.5f;
70 errorLabel.set_justify(Justification.CENTER);
71 errorLabel.ellipsize = Pango.EllipsizeMode.END;
72 }
73
74 static Gtk.Alignment wrap_alignment (Gtk.Widget widget, int top, int right, int bottom, int left) {
75
76 var alignment = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 1.0f);
77 alignment.top_padding = top;
78 alignment.right_padding = right;
79 alignment.bottom_padding = bottom;
80 alignment.left_padding = left;
81
82 alignment.add(widget);
83 return alignment;
84 }
85
86
87 // We force our HIG here. Whenever show_icon is true, the title has to be left-aligned.
88
89 // FIXME: this should be: set_warning (string primary_text, string secondary_text, bool show_icon = true, ...)
90 public void setWarning(string warning, Gtk.Justification? justification = Gtk.Justification.LEFT) {
91 if (!show_icon)
92 errorLabel.set_justify(Gtk.Justification.CENTER);
93 else
94 errorLabel.set_justify(justification);
95
96 errorLabel.set_markup(warning);
97 }
98}
99
1000
=== modified file 'src/Windows/AddPodcastWindow.vala'
--- src/Windows/AddPodcastWindow.vala 2012-05-03 04:19:07 +0000
+++ src/Windows/AddPodcastWindow.vala 2012-07-03 06:49:24 +0000
@@ -173,10 +173,10 @@
173 next = url;173 next = url;
174 174
175 try {175 try {
176 Thread.create<void*>(test_url_validity, false);176 new Thread<void*>.try (null, test_url_validity);
177 }177 }
178 catch(GLib.ThreadError err) {178 catch (Error err) {
179 stdout.printf("ERROR: Could not create thread to fetch new podcasts: %s \n", err.message);179 warning ("Could not create thread to fetch new podcasts: %s", err.message);
180 }180 }
181 }181 }
182 }182 }
183183
=== modified file 'src/Windows/RemoveDuplicatesDialog.vala'
--- src/Windows/RemoveDuplicatesDialog.vala 2012-06-14 23:08:24 +0000
+++ src/Windows/RemoveDuplicatesDialog.vala 2012-07-03 06:49:24 +0000
@@ -141,10 +141,10 @@
141 is_working.start();141 is_working.start();
142 142
143 try {143 try {
144 Thread.create<void*>(find_duplicates_thread, false);144 new Thread<void*>.try (null, find_duplicates_thread);
145 }145 }
146 catch(GLib.ThreadError err) {146 catch (Error err) {
147 stdout.printf("ERROR: Could not create thread to analyze duplicates: %s \n", err.message);147 warning ("Could not create thread to analyze duplicates: %s", err.message);
148 }148 }
149 }149 }
150 150
151151
=== modified file 'src/Wrappers/PodcastViewWrapper.vala'
--- src/Wrappers/PodcastViewWrapper.vala 2012-06-30 20:55:57 +0000
+++ src/Wrappers/PodcastViewWrapper.vala 2012-07-03 06:49:24 +0000
@@ -61,15 +61,15 @@
61 void welcome_screen_activated(int index) {61 void welcome_screen_activated(int index) {
62 if(index == 0) {62 if(index == 0) {
63 try {63 try {
64 Thread.create<void*>(take_action, false);64 new Thread<void*>.try (null, take_action);
65 }65 }
66 catch(GLib.ThreadError err) {66 catch (Error err) {
67 stdout.printf("ERROR: Could not create thread to have fun: %s \n", err.message);67 warning ("Could not create thread to have fun: %s", err.message);
68 }68 }
69 }69 }
70 }70 }
71 71
72 public void* take_action () {72 private void* take_action () {
73 try {73 try {
74 GLib.AppInfo.launch_default_for_uri ("https://www.miroguide.com/toprated/", null);74 GLib.AppInfo.launch_default_for_uri ("https://www.miroguide.com/toprated/", null);
75 }75 }
7676
=== modified file 'src/Wrappers/StationViewWrapper.vala'
--- src/Wrappers/StationViewWrapper.vala 2012-06-30 20:55:57 +0000
+++ src/Wrappers/StationViewWrapper.vala 2012-07-03 06:49:24 +0000
@@ -61,10 +61,10 @@
61 void welcome_screen_activated(int index) {61 void welcome_screen_activated(int index) {
62 if(index == 0) {62 if(index == 0) {
63 try {63 try {
64 Thread.create<void*>(take_action, false);64 new Thread<void*>.try (null, take_action);
65 }65 }
66 catch(GLib.ThreadError err) {66 catch(Error err) {
67 stdout.printf("ERROR: Could not create thread to have fun: %s \n", err.message);67 warning ("Could not create thread to have fun: %s", err.message);
68 }68 }
69 }69 }
70 }70 }
7171
=== modified file 'src/Wrappers/ViewWrapper.vala'
--- src/Wrappers/ViewWrapper.vala 2012-06-30 20:55:57 +0000
+++ src/Wrappers/ViewWrapper.vala 2012-07-03 06:49:24 +0000
@@ -177,8 +177,6 @@
177 _artist_filter = "";177 _artist_filter = "";
178 _genre_filter = "";178 _genre_filter = "";
179 179
180 in_update = new Mutex();
181
182 set_orientation(Orientation.VERTICAL);180 set_orientation(Orientation.VERTICAL);
183 181
184 // Setup container182 // Setup container

Subscribers

People subscribed via source and target branches