Merge lp:~tintou/noise/noise-gda-zeitgeist into lp:~elementary-apps/noise/trunk
- noise-gda-zeitgeist
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Danielle Foré | ||||
Approved revision: | 1835 | ||||
Merged at revision: | 1827 | ||||
Proposed branch: | lp:~tintou/noise/noise-gda-zeitgeist | ||||
Merge into: | lp:~elementary-apps/noise/trunk | ||||
Diff against target: |
9601 lines (+4689/-2507) 68 files modified
CMakeLists.txt (+4/-20) core/CMakeLists.txt (+0/-1) core/Devices/Device.vala (+4/-5) core/Devices/DeviceManager.vala (+0/-21) core/LibrariesManager.vala (+9/-5) core/Library.vala (+7/-7) core/Media.vala (+1/-1) core/Playlists/Playlist.vala (+3/-3) core/Playlists/SmartPlaylist.vala (+45/-61) core/Playlists/SmartQuery.vala (+2/-3) core/Settings.vala (+2/-2) core/Utils/Search.vala (+10/-6) core/Utils/String.vala (+6/-3) plugins/CMakeLists.txt (+0/-1) plugins/Devices/AudioPlayers/AudioPlayerDevice.vala (+6/-17) plugins/Devices/AudioPlayers/AudioPlayerLibrary.vala (+21/-101) plugins/Devices/CDRom/CDRomDevice.vala (+2/-6) plugins/Devices/CDRom/CDViewWrapper.vala (+1/-1) plugins/Devices/iPod/iPodDevice.vala (+1/-12) plugins/Devices/iPod/iPodLibrary.vala (+32/-179) plugins/Devices/iPod/iPodPlaylistHelper.vala (+47/-69) plugins/LastFM/Core.vala (+83/-82) plugins/LastFM/LastFM.vala (+1/-1) plugins/LastFM/SimilarMedia.vala (+25/-32) plugins/LastFM/SimilarMediaWidget.vala (+1/-3) plugins/LastFM/noise-lastfm.application (+5/-0) plugins/MPRIS/MPRIS.vala (+1/-1) plugins/Zeitgeist/CMakeLists.txt (+0/-34) plugins/Zeitgeist/Zeitgeist.vala (+0/-88) plugins/Zeitgeist/zeitgeist.plugin (+0/-9) schemas/org.pantheon.noise.gschema.xml (+5/-5) src/CMakeLists.txt (+5/-3) src/DataBase.vala (+267/-35) src/DataBase/DataBaseManager.vala (+0/-937) src/DataBase/DataBaseUpdater.vala (+0/-87) src/Dialogs/FileNotFoundDialog.vala (+1/-1) src/Dialogs/MediaEditor.vala (+21/-21) src/Dialogs/SmartPlaylistEditor.vala (+21/-15) src/FileOperator.vala (+1/-1) src/LibraryWindow.vala (+115/-133) src/LocalBackend/DevicePreferences.vala (+161/-20) src/LocalBackend/LocalLibrary.vala (+297/-141) src/LocalBackend/LocalMedia.vala (+111/-64) src/LocalBackend/LocalSmartPlaylist.vala (+268/-0) src/LocalBackend/LocalStaticPlaylist.vala (+90/-0) src/Objects/HistoryPlaylist.vala (+589/-0) src/PlaybackManager.vala (+14/-25) src/Views/ContentView.vala (+1/-1) src/Views/DeviceSummaryWidget.vala (+22/-34) src/Views/DeviceView.vala (+9/-10) src/Views/GridView/GridLayout.vala (+3/-3) src/Views/GridView/GridView.vala (+10/-36) src/Views/GridView/PopupListView.vala (+3/-3) src/Views/ListView/ListView.vala (+9/-10) src/Views/ListView/Lists/CellDataFunctionHelper.vala (+1/-1) src/Views/ListView/Lists/GenericList.vala (+25/-32) src/Views/ListView/Lists/ListColumn.vala (+1/-0) src/Views/ListView/Lists/MusicListView.vala (+20/-47) src/Views/ListView/Lists/TreeViewSetup.vala (+96/-22) src/Views/Wrappers/DeviceViewWrapper.vala (+1/-1) src/Views/Wrappers/MusicViewWrapper.vala (+5/-5) src/Views/Wrappers/PlaylistViewWrapper.vala (+13/-27) src/Views/Wrappers/ViewWrapper.vala (+4/-6) src/Widgets/FastView/FastGrid.vala (+6/-6) src/Widgets/TopDisplay.vala (+1/-1) src/main.vala (+1/-0) vapi/libgda-5.0.deps (+1/-0) vapi/libgda-5.0.vapi (+2172/-0) |
||||
To merge this branch: | bzr merge lp:~tintou/noise/noise-gda-zeitgeist | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
xapantu (community) | Approve | ||
Review via email: mp+269248@code.launchpad.net |
Commit message
Changed SQLHeavy to libGDA. Added Zeitgeist History.
Description of the change
Switched to GDA.
A lot of changes have been made in the structure of the application.
Playlists, Smart Playlists, Media, Device preferences and TreeView Headers are now directly using the database.
We need to provide the right .vapi until the release of libgda 6.0
The History playlist is now using Zeitgeist directly
Overall, big changes and (I hope) more stability.
Danielle Foré (danrabbit) wrote : | # |
- 1833. By Corentin Noël
-
Ensure that History Playlist doesn't contain duplicates.
Viko Adi Rahmawan (vikoadi) wrote : | # |
Searching crash the apps
Is it planned to ditch the whole _medias and _searched_medias? We can use gda query to search that. I think that would be more memory efficient.
- 1834. By Corentin Noël
-
Fixed rating parsing. Searchs now directly with the database.
- 1835. By Corentin Noël
-
Search for rating if the user search with only wildcards.
Corentin Noël (tintou) wrote : | # |
Daniel:
* The history playlist is now deduplicated.
* last-played bug is now fixed in granite
Viko Adi:
* It now uses the Database directly, but _medias and _searched_medias are still required because we need to cache some values once they're retrieved from the database.
Danielle Foré (danrabbit) wrote : | # |
Cody is working on the new granite release including an so name bump. So I guess this branch will need to require the new version of granite before it can be merged.
I can confirm that the history playlist is de-duplicated
I cannot confirm that search crashes the app.
Danielle Foré (danrabbit) wrote : | # |
I can confirm that after the granite update that the last played song is restored.
However, I'm getting this behavior where only the statusbar will show, then the rest of the UI. It's pretty odd. Anyone can reproduce?
Viko Adi Rahmawan (vikoadi) wrote : | # |
@Daniel seems that media loading in initialize_library is too slow in large library, maybe we should run it on async thread, running search in thread seems to be good idea too.
Viko Adi Rahmawan (vikoadi) wrote : | # |
Search works great now
@Daniel seems that media loading in initialize_library is too slow in large library, maybe we should run it on async thread, running search in thread seems to be good idea too.
xapantu (xapantu) wrote : | # |
The code looks fine (but the diff is very long). I have some issues with sorting on Archlinux, but after some discussions, it appears that it could be caused by a newer gtk and a newer gda. Anyway, this should be merged in trunk so as this work can be carried on.
The import is slow, but it was also slow with the trunk, so probably nothing new here.
Danielle Foré (danrabbit) wrote : | # |
Since Lucas marked this as "approve", I'm going to move the status of the MR to "approve" as well
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-04-06 19:13:13 +0000 |
3 | +++ CMakeLists.txt 2015-08-27 10:21:27 +0000 |
4 | @@ -86,11 +86,15 @@ |
5 | set (DEPS_PACKAGES |
6 | ${CORE_LIBRARY_NAME} |
7 | ${CORE_PACKAGES} # this is needed until we provide a ${CORE_LIBRARY_NAME}.deps file |
8 | + libgda-5.0 |
9 | taglib_c |
10 | + zeitgeist-2.0 |
11 | ) |
12 | |
13 | set (DEPS_PKG |
14 | + libgda-5.0 |
15 | taglib_c |
16 | + zeitgeist-2.0 |
17 | ) |
18 | |
19 | find_package (PkgConfig) |
20 | @@ -113,26 +117,6 @@ |
21 | ) |
22 | |
23 | # |
24 | -# SQLHeavy: Use version 0.2 if it is available; otherwise, fall back to 0.1 |
25 | -# |
26 | -pkg_check_modules (SQLHEAVY2 QUIET sqlheavy-0.2) |
27 | -if (SQLHEAVY2_FOUND) |
28 | - message ("-- Will use sqlheavy-0.2") |
29 | - set (DEPS_PACKAGES ${DEPS_PACKAGES} sqlheavy-0.2) |
30 | - set (SQLHEAVY_CFLAGS ${SQLHEAVY2_CFLAGS}) |
31 | - set (SQLHEAVY_LIBRARY_DIRS ${SQLHEAVY2_LIBRARY_DIRS}) |
32 | - set (SQLHEAVY_LIBRARIES ${SQLHEAVY2_LIBRARIES}) |
33 | -else () |
34 | - message ("-- Will use sqlheavy-0.1") |
35 | - pkg_check_modules (SQLHEAVY REQUIRED sqlheavy-0.1) |
36 | - set (DEPS_PACKAGES ${DEPS_PACKAGES} sqlheavy-0.1) |
37 | -endif () |
38 | - |
39 | -set (DEPS_CFLAGS ${DEPS_CFLAGS} ${SQLHEAVY_CFLAGS}) |
40 | -set (DEPS_LIBRARIES ${DEPS_LIBRARIES} ${SQLHEAVY_LIBRARIES}) |
41 | -set (DEPS_LIBRARY_DIRS ${DEPS_LIBRARY_DIRS} ${SQLHEAVY_LIBRARY_DIRS}) |
42 | - |
43 | -# |
44 | # Libnotify |
45 | # |
46 | pkg_check_modules (LIBNOTIFY QUIET libnotify) |
47 | |
48 | === modified file 'core/CMakeLists.txt' |
49 | --- core/CMakeLists.txt 2015-05-24 21:40:48 +0000 |
50 | +++ core/CMakeLists.txt 2015-08-27 10:21:27 +0000 |
51 | @@ -29,7 +29,6 @@ |
52 | Devices/Device.vala |
53 | Devices/NetworkDevice.vala |
54 | Devices/DeviceManager.vala |
55 | - Devices/DevicePreferences.vala |
56 | Playlists/Playlist.vala |
57 | Playlists/StaticPlaylist.vala |
58 | Playlists/SmartPlaylist.vala |
59 | |
60 | === modified file 'core/Devices/Device.vala' |
61 | --- core/Devices/Device.vala 2015-06-12 13:51:08 +0000 |
62 | +++ core/Devices/Device.vala 2015-08-27 10:21:27 +0000 |
63 | @@ -34,8 +34,7 @@ |
64 | public signal void initialized (Device d); |
65 | public signal void device_unmounted (); |
66 | public signal void infobar_message (string message, Gtk.MessageType type); |
67 | - |
68 | - public abstract DevicePreferences get_preferences(); |
69 | + |
70 | public abstract bool start_initialization(); |
71 | public abstract void finish_initialization(); |
72 | public abstract string getContentType(); |
73 | @@ -113,9 +112,9 @@ |
74 | return get_capacity () > (list_size - without_size); |
75 | } |
76 | } |
77 | - |
78 | - public string get_unique_identifier() { |
79 | - Mount? m = get_mount(); |
80 | + |
81 | + public virtual string get_unique_identifier () { |
82 | + Mount? m = get_mount (); |
83 | if (m != null) { |
84 | string uuid = m.get_uuid(); |
85 | File root = m.get_root(); |
86 | |
87 | === modified file 'core/Devices/DeviceManager.vala' |
88 | --- core/Devices/DeviceManager.vala 2015-06-12 13:51:08 +0000 |
89 | +++ core/Devices/DeviceManager.vala 2015-08-27 10:21:27 +0000 |
90 | @@ -39,7 +39,6 @@ |
91 | public signal void mount_added (Mount mount); |
92 | public signal void mount_removed (Mount mount); |
93 | |
94 | - private Gee.TreeSet<DevicePreferences> device_preferences; |
95 | private Gee.TreeSet<unowned Device> initialized_devices; |
96 | private Gee.TreeSet<unowned Mount> mounts_availables; |
97 | private Gee.TreeSet<Playlist> local_playlists; |
98 | @@ -53,7 +52,6 @@ |
99 | } |
100 | |
101 | private DeviceManager () { |
102 | - device_preferences = new Gee.TreeSet<DevicePreferences> (); |
103 | initialized_devices = new Gee.TreeSet<unowned Device> (); |
104 | mounts_availables = new Gee.TreeSet<unowned Mount> (); |
105 | local_playlists = new Gee.TreeSet<Playlist> (); |
106 | @@ -67,10 +65,6 @@ |
107 | get_pre_existing_mounts.begin (); |
108 | } |
109 | |
110 | - public void set_device_preferences (Gee.Collection<DevicePreferences> device_preferences) { |
111 | - this.device_preferences.add_all (device_preferences); |
112 | - } |
113 | - |
114 | public async void get_pre_existing_mounts () { |
115 | var mounts = new Gee.TreeSet<Mount> (); |
116 | var volumes = new Gee.TreeSet<Volume> (); |
117 | @@ -118,15 +112,6 @@ |
118 | //message ("mount_preunmount:%s\n", mount.get_uuid()); |
119 | } |
120 | |
121 | - public DevicePreferences? get_device_preferences (string id) { |
122 | - foreach (var device in device_preferences) { |
123 | - if (device.id == id) |
124 | - return device; |
125 | - } |
126 | - |
127 | - return null; |
128 | - } |
129 | - |
130 | public Gee.Collection<unowned Device> get_initialized_devices () { |
131 | return initialized_devices; |
132 | } |
133 | @@ -134,10 +119,4 @@ |
134 | public Gee.Collection<unowned Mount> get_available_mounts () { |
135 | return mounts_availables; |
136 | } |
137 | - |
138 | - public void add_device_preferences (DevicePreferences dp) { |
139 | - lock (device_preferences) { |
140 | - device_preferences.add (dp); |
141 | - } |
142 | - } |
143 | } |
144 | |
145 | === modified file 'core/LibrariesManager.vala' |
146 | --- core/LibrariesManager.vala 2015-06-12 13:51:08 +0000 |
147 | +++ core/LibrariesManager.vala 2015-08-27 10:21:27 +0000 |
148 | @@ -29,21 +29,25 @@ |
149 | */ |
150 | |
151 | public class Noise.LibrariesManager : GLib.Object { |
152 | - |
153 | + /** |
154 | + * Headless playlists are playlists that are not linked to a library. |
155 | + */ |
156 | + public signal void add_headless_playlist (StaticPlaylist playlist); |
157 | + |
158 | public signal void library_removed (Library library); |
159 | public signal void library_added (Library library); |
160 | - |
161 | + |
162 | public signal void cancel_transfer (); |
163 | public signal void operation_terminated (); |
164 | - |
165 | + |
166 | public double progress; |
167 | public string current_operation; |
168 | private string old_search = null; |
169 | - |
170 | + |
171 | private Gee.HashMap<Library, int> libraries; |
172 | private int current_index = 0; |
173 | public Library local_library; |
174 | - |
175 | + |
176 | public LibrariesManager () { |
177 | libraries = new Gee.HashMap<Library, int> (); |
178 | } |
179 | |
180 | === modified file 'core/Library.vala' |
181 | --- core/Library.vala 2015-06-12 13:51:08 +0000 |
182 | +++ core/Library.vala 2015-08-27 10:21:27 +0000 |
183 | @@ -66,9 +66,9 @@ |
184 | public abstract Media? find_media (Media to_find); |
185 | public abstract Media? media_from_file (File file); |
186 | public abstract Media? media_from_uri (string uri); |
187 | - public abstract Media? media_from_id (int id); |
188 | + public abstract Media? media_from_id (int64 id); |
189 | public abstract Gee.Collection<Media> medias_from_uris (Gee.Collection<string> uris); |
190 | - public abstract Gee.Collection<Media> medias_from_ids (Gee.Collection<int> ids); |
191 | + public abstract Gee.Collection<Media> medias_from_ids (Gee.Collection<int64?> ids); |
192 | public abstract void update_media (Media s, bool updateMeta, bool record_time); |
193 | public abstract void update_medias (Gee.Collection<Media> updates, bool updateMeta, bool record_time); |
194 | public abstract void remove_media (Media s, bool trash); |
195 | @@ -76,14 +76,14 @@ |
196 | |
197 | public abstract bool support_smart_playlists (); |
198 | public abstract void add_smart_playlist (SmartPlaylist p); |
199 | - public abstract void remove_smart_playlist (int id); |
200 | - public abstract SmartPlaylist? smart_playlist_from_id (int id); |
201 | + public abstract void remove_smart_playlist (int64 id); |
202 | + public abstract SmartPlaylist? smart_playlist_from_id (int64 id); |
203 | public abstract SmartPlaylist? smart_playlist_from_name (string name); |
204 | |
205 | public abstract bool support_playlists (); |
206 | public abstract void add_playlist (StaticPlaylist p); |
207 | - public abstract void remove_playlist (int id); |
208 | - public abstract StaticPlaylist? playlist_from_id (int id); |
209 | + public abstract void remove_playlist (int64 id); |
210 | + public abstract StaticPlaylist? playlist_from_id (int64 id); |
211 | public abstract StaticPlaylist? playlist_from_name (string name); |
212 | |
213 | public abstract bool start_file_operations (string? message); |
214 | @@ -99,7 +99,7 @@ |
215 | return i; |
216 | } |
217 | |
218 | - public void media_from_name (Gee.Collection<Media> tests, Gee.Collection<int> found, Gee.Collection<Media> not_found) { |
219 | + public void media_from_name (Gee.Collection<Media> tests, Gee.Collection<int64?> found, Gee.Collection<Media> not_found) { |
220 | foreach (Media test in tests) { |
221 | var media_found = find_media (test); |
222 | if (media_found != null) { |
223 | |
224 | === modified file 'core/Media.vala' |
225 | --- core/Media.vala 2015-06-12 13:51:08 +0000 |
226 | +++ core/Media.vala 2015-08-27 10:21:27 +0000 |
227 | @@ -33,7 +33,7 @@ |
228 | /// Used for unknown titles, artists, or album names. |
229 | protected static string UNKNOWN = _("Unknown"); |
230 | |
231 | - public int rowid { get; set; } |
232 | + public int64 rowid { get; set; } |
233 | |
234 | public virtual string uri { |
235 | owned get { return file.get_uri (); } |
236 | |
237 | === modified file 'core/Playlists/Playlist.vala' |
238 | --- core/Playlists/Playlist.vala 2015-06-12 14:41:35 +0000 |
239 | +++ core/Playlists/Playlist.vala 2015-08-27 10:21:27 +0000 |
240 | @@ -32,10 +32,10 @@ |
241 | public signal void request_play (); |
242 | public virtual Gee.ArrayQueue<Media> medias { get; internal set; } |
243 | |
244 | - public int rowid { get; set; } |
245 | + public int64 rowid { get; set; } |
246 | public GLib.Icon icon; |
247 | - private string _name = ""; |
248 | - public string name { |
249 | + internal string _name = ""; |
250 | + public virtual string name { |
251 | get { |
252 | return _name; |
253 | } |
254 | |
255 | === modified file 'core/Playlists/SmartPlaylist.vala' |
256 | --- core/Playlists/SmartPlaylist.vala 2015-06-12 14:41:35 +0000 |
257 | +++ core/Playlists/SmartPlaylist.vala 2015-08-27 10:21:27 +0000 |
258 | @@ -35,14 +35,14 @@ |
259 | ANY = false |
260 | } |
261 | |
262 | - public ConditionalType conditional { get; set; default = ConditionalType.ALL; } |
263 | + public virtual ConditionalType conditional { get; set; default = ConditionalType.ALL; } |
264 | public Gee.TreeSet<SmartQuery> queries; |
265 | public int query_count { get; set; default = 0; } |
266 | |
267 | - public bool limit { get; set; default = false; } |
268 | - public int limit_amount { get; set; default = 50; } |
269 | + public virtual bool limit { get; set; default = false; } |
270 | + public virtual uint limit_amount { get; set; default = 50; } |
271 | |
272 | - private Noise.Library library; |
273 | + protected Noise.Library library; |
274 | |
275 | /* |
276 | * A SmartPlaylist should be linked to only one library. |
277 | @@ -142,112 +142,112 @@ |
278 | switch (q.field) { |
279 | case Noise.SmartQuery.FieldType.ALBUM : |
280 | if(q.comparator == SmartQuery.ComparatorType.IS) |
281 | - return q.value.down() == s.album.down(); |
282 | + return q.value.get_string ().down () == s.album.down(); |
283 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
284 | - return (q.value.down() in s.album.down()); |
285 | + return (q.value.get_string ().down() in s.album.down()); |
286 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
287 | - return !(q.value.down() in s.album.down()); |
288 | + return !(q.value.get_string ().down() in s.album.down()); |
289 | break; |
290 | case Noise.SmartQuery.FieldType.ARTIST: |
291 | if(q.comparator == SmartQuery.ComparatorType.IS) |
292 | - return q.value.down() == s.artist.down(); |
293 | + return q.value.get_string ().down() == s.artist.down(); |
294 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
295 | - return (q.value.down() in s.artist.down()); |
296 | + return (q.value.get_string ().down() in s.artist.down()); |
297 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
298 | - return !(q.value.down() in s.artist.down()); |
299 | + return !(q.value.get_string ().down() in s.artist.down()); |
300 | break; |
301 | case Noise.SmartQuery.FieldType.COMPOSER: |
302 | if(q.comparator == SmartQuery.ComparatorType.IS) |
303 | - return q.value.down() == s.composer.down(); |
304 | + return q.value.get_string ().down() == s.composer.down(); |
305 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
306 | - return (q.value.down() in s.composer.down()); |
307 | + return (q.value.get_string ().down() in s.composer.down()); |
308 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
309 | - return !(q.value.down() in s.composer.down()); |
310 | + return !(q.value.get_string ().down() in s.composer.down()); |
311 | break; |
312 | case Noise.SmartQuery.FieldType.COMMENT: |
313 | if(q.comparator == SmartQuery.ComparatorType.IS) |
314 | - return q.value.down() == s.comment.down(); |
315 | + return q.value.get_string ().down() == s.comment.down(); |
316 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
317 | - return (q.value.down() in s.comment.down()); |
318 | + return (q.value.get_string ().down() in s.comment.down()); |
319 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
320 | - return !(q.value.down() in s.comment.down()); |
321 | + return !(q.value.get_string ().down() in s.comment.down()); |
322 | break; |
323 | case Noise.SmartQuery.FieldType.GENRE: |
324 | if(q.comparator == SmartQuery.ComparatorType.IS) |
325 | - return q.value.down() == s.genre.down(); |
326 | + return q.value.get_string ().down() == s.genre.down(); |
327 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
328 | - return (q.value.down() in s.genre.down()); |
329 | + return (q.value.get_string ().down() in s.genre.down()); |
330 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
331 | - return !(q.value.down() in s.genre.down()); |
332 | + return !(q.value.get_string ().down() in s.genre.down()); |
333 | break; |
334 | case Noise.SmartQuery.FieldType.GROUPING: |
335 | if(q.comparator == SmartQuery.ComparatorType.IS) |
336 | - return q.value.down() == s.grouping.down(); |
337 | + return q.value.get_string ().down() == s.grouping.down(); |
338 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
339 | - return (q.value.down() in s.grouping.down()); |
340 | + return (q.value.get_string ().down() in s.grouping.down()); |
341 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
342 | - return !(q.value.down() in s.grouping.down()); |
343 | + return !(q.value.get_string ().down() in s.grouping.down()); |
344 | break; |
345 | case Noise.SmartQuery.FieldType.TITLE: |
346 | if(q.comparator == SmartQuery.ComparatorType.IS) |
347 | - return q.value.down() == s.title.down(); |
348 | + return q.value.get_string ().down() == s.title.down(); |
349 | else if(q.comparator == SmartQuery.ComparatorType.CONTAINS) |
350 | - return (q.value.down() in s.title.down()); |
351 | + return (q.value.get_string ().down() in s.title.down()); |
352 | else if(q.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) |
353 | - return !(q.value.down() in s.title.down()); |
354 | + return !(q.value.get_string ().down() in s.title.down()); |
355 | break; |
356 | case Noise.SmartQuery.FieldType.BITRATE: |
357 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
358 | - return int.parse(q.value) == s.bitrate; |
359 | + return q.value.get_int () == s.bitrate; |
360 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
361 | - return (s.bitrate <= int.parse(q.value)); |
362 | + return (s.bitrate <= q.value.get_int ()); |
363 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
364 | - return (s.bitrate >= int.parse(q.value)); |
365 | + return (s.bitrate >= q.value.get_int ()); |
366 | break; |
367 | case Noise.SmartQuery.FieldType.PLAYCOUNT: |
368 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
369 | - return int.parse(q.value) == s.play_count; |
370 | + return q.value.get_int () == s.play_count; |
371 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
372 | - return (s.play_count <= int.parse(q.value)); |
373 | + return (s.play_count <= q.value.get_int ()); |
374 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
375 | - return (s.play_count >= int.parse(q.value)); |
376 | + return (s.play_count >= q.value.get_int ()); |
377 | break; |
378 | case Noise.SmartQuery.FieldType.SKIPCOUNT: |
379 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
380 | - return int.parse(q.value) == s.skip_count; |
381 | + return q.value.get_int () == s.skip_count; |
382 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
383 | - return (s.skip_count <= int.parse(q.value)); |
384 | + return (s.skip_count <= q.value.get_int ()); |
385 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
386 | - return (s.skip_count >= int.parse(q.value)); |
387 | + return (s.skip_count >= q.value.get_int ()); |
388 | break; |
389 | case Noise.SmartQuery.FieldType.YEAR: |
390 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
391 | - return int.parse (q.value) == s.year; |
392 | + return q.value.get_int () == s.year; |
393 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
394 | - return (s.year <= int.parse (q.value)); |
395 | + return (s.year <= q.value.get_int ()); |
396 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
397 | - return (s.year >= int.parse (q.value)); |
398 | + return (s.year >= q.value.get_int ()); |
399 | break; |
400 | case Noise.SmartQuery.FieldType.LENGTH: |
401 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
402 | - return int.parse (q.value) == s.length; |
403 | + return q.value.get_int () == s.length; |
404 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
405 | - return (s.length <= int.parse (q.value)); |
406 | + return (s.length <= q.value.get_int ()); |
407 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
408 | - return (s.length >= int.parse (q.value)); |
409 | + return (s.length >= q.value.get_int ()); |
410 | break; |
411 | case Noise.SmartQuery.FieldType.RATING: |
412 | if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
413 | - return int.parse(q.value) == s.rating; |
414 | + return q.value.get_int () == s.rating; |
415 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_MOST) |
416 | - return (s.rating <= int.parse (q.value)); |
417 | + return (s.rating <= q.value.get_int ()); |
418 | else if(q.comparator == SmartQuery.ComparatorType.IS_AT_LEAST) |
419 | - return (s.rating >= int.parse (q.value)); |
420 | + return (s.rating >= q.value.get_int ()); |
421 | break; |
422 | case Noise.SmartQuery.FieldType.DATE_ADDED: |
423 | var now = new DateTime.now_local (); |
424 | var played = new DateTime.from_unix_local (s.date_added); |
425 | - played = played.add_days (int.parse (q.value)); |
426 | + played = played.add_days (q.value.get_int ()); |
427 | |
428 | if (q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) { |
429 | return (now.get_day_of_year () == played.get_day_of_year () && now.get_year () == played.get_year ()); |
430 | @@ -257,29 +257,13 @@ |
431 | return now.compare (played) > 0; |
432 | } |
433 | break; |
434 | - case Noise.SmartQuery.FieldType.DATE_RELEASED: |
435 | -/* |
436 | - var now = new DateTime.now_local(); |
437 | - var released = new DateTime.from_unix_local(s.podcast_date); |
438 | - released = released.add_days(int.parse(q.value)); |
439 | - |
440 | - if(q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) |
441 | - return (now.get_day_of_year() == released.get_day_of_year() && now.get_year() == released.get_year()); |
442 | - else if(q.comparator == SmartQuery.ComparatorType.IS_WITHIN) { |
443 | - return released.compare(now) > 0; |
444 | - } |
445 | - else if(q.comparator == SmartQuery.ComparatorType.IS_BEFORE) { |
446 | - return now.compare(released) > 0; |
447 | - } |
448 | -*/ |
449 | - break; |
450 | case Noise.SmartQuery.FieldType.LAST_PLAYED: |
451 | if(s.last_played == 0) |
452 | return false; |
453 | |
454 | var now = new DateTime.now_local(); |
455 | var played = new DateTime.from_unix_local (s.last_played); |
456 | - played = played.add_days (int.parse (q.value)); |
457 | + played = played.add_days (q.value.get_int ()); |
458 | |
459 | if (q.comparator == SmartQuery.ComparatorType.IS_EXACTLY) { |
460 | return (now.get_day_of_year () == played.get_day_of_year () && now.get_year () == played.get_year ()); |
461 | |
462 | === modified file 'core/Playlists/SmartQuery.vala' |
463 | --- core/Playlists/SmartQuery.vala 2015-06-12 14:41:35 +0000 |
464 | +++ core/Playlists/SmartQuery.vala 2015-08-27 10:21:27 +0000 |
465 | @@ -49,7 +49,6 @@ |
466 | COMMENT, |
467 | COMPOSER, |
468 | DATE_ADDED, |
469 | - DATE_RELEASED, |
470 | GENRE, |
471 | GROUPING, |
472 | LAST_PLAYED, |
473 | @@ -64,13 +63,13 @@ |
474 | public int rowid { get; set; default = 0; } |
475 | public FieldType field { get; set; default = FieldType.ALBUM; } |
476 | public ComparatorType comparator { get; set; default = ComparatorType.IS; } |
477 | - public string value { get; set; default = ""; } //internally this often holds numbers, but that's ok. |
478 | + public GLib.Value value { get; set; default = GLib.Value (typeof (int)); } |
479 | |
480 | public SmartQuery () { |
481 | |
482 | } |
483 | |
484 | - public SmartQuery.with_info (FieldType field, ComparatorType comparator, string value) { |
485 | + public SmartQuery.with_info (FieldType field, ComparatorType comparator, GLib.Value value) { |
486 | this.field = field; |
487 | this.comparator = comparator; |
488 | this.value = value; |
489 | |
490 | === modified file 'core/Settings.vala' |
491 | --- core/Settings.vala 2015-06-12 13:51:08 +0000 |
492 | +++ core/Settings.vala 2015-08-27 10:21:27 +0000 |
493 | @@ -67,8 +67,8 @@ |
494 | public bool write_metadata_to_file { get; set; } |
495 | public bool copy_imported_music { get; set; } |
496 | public bool close_while_playing { get; set; } |
497 | - public int last_media_playing { get; set; } |
498 | - public int last_playlist_playing { get; set; } |
499 | + public int64 last_media_playing { get; set; } |
500 | + public string last_playlist_playing { get; set; } |
501 | public int last_media_position { get; set; } |
502 | public Shuffle shuffle_mode { get; set; } |
503 | public Repeat repeat_mode { get; set; } |
504 | |
505 | === modified file 'core/Utils/Search.vala' |
506 | --- core/Utils/Search.vala 2015-06-12 13:51:08 +0000 |
507 | +++ core/Utils/Search.vala 2015-08-27 10:21:27 +0000 |
508 | @@ -109,18 +109,22 @@ |
509 | * " " |
510 | * "**a" |
511 | */ |
512 | - public inline int get_rating_from_string (string rating_string) |
513 | - ensures (result != 0 || result == -1) |
514 | + public inline uint? get_rating_from_string (string rating_string) |
515 | + ensures (result != 0) |
516 | { |
517 | - int i; |
518 | + int i = 0; |
519 | unichar c; |
520 | + uint rating; |
521 | |
522 | - for (i = 0; rating_string.get_next_char (ref i, out c);) { |
523 | + for (rating = 0; rating_string.get_next_char (ref i, out c); rating++) { |
524 | if (c != '*') |
525 | - return -1; |
526 | + return null; |
527 | } |
528 | |
529 | - return i > 0 ? i : -1; |
530 | + if (rating == 0) |
531 | + return null; |
532 | + |
533 | + return rating; |
534 | } |
535 | |
536 | public inline bool match_string_to_media (Media m, string search) { |
537 | |
538 | === modified file 'core/Utils/String.vala' |
539 | --- core/Utils/String.vala 2015-06-12 13:51:08 +0000 |
540 | +++ core/Utils/String.vala 2015-08-27 10:21:27 +0000 |
541 | @@ -178,13 +178,16 @@ |
542 | * @param parsed_search_string location where the canonicalized version of the |
543 | * search string is stored. Should be passed to the methods in Noise.Search. |
544 | */ |
545 | - public static void base_search_method (string search, out int parsed_rating, |
546 | + public static void base_search_method (string search, out uint parsed_rating, |
547 | out string parsed_search_string) |
548 | { |
549 | - parsed_rating = Search.get_rating_from_string (search.strip ()); |
550 | + var result = Search.get_rating_from_string (search.strip ()); |
551 | |
552 | - if (parsed_rating > 0) |
553 | + if (result != null) { |
554 | parsed_rating = parsed_rating.clamp (1, 5); |
555 | + } else { |
556 | + parsed_rating = 0; |
557 | + } |
558 | |
559 | parsed_search_string = Search.get_valid_search_string (search); |
560 | } |
561 | |
562 | === modified file 'plugins/CMakeLists.txt' |
563 | --- plugins/CMakeLists.txt 2014-06-16 14:04:06 +0000 |
564 | +++ plugins/CMakeLists.txt 2015-08-27 10:21:27 +0000 |
565 | @@ -12,7 +12,6 @@ |
566 | add_subdirectory (Devices) |
567 | add_subdirectory (LastFM) |
568 | add_subdirectory (MPRIS) |
569 | - add_subdirectory (Zeitgeist) |
570 | else () |
571 | message ("-- Plugins disabled") |
572 | endif () |
573 | |
574 | === modified file 'plugins/Devices/AudioPlayers/AudioPlayerDevice.vala' |
575 | --- plugins/Devices/AudioPlayers/AudioPlayerDevice.vala 2015-02-24 00:04:03 +0000 |
576 | +++ plugins/Devices/AudioPlayers/AudioPlayerDevice.vala 2015-08-27 10:21:27 +0000 |
577 | @@ -24,31 +24,20 @@ |
578 | |
579 | Mount mount; |
580 | GLib.Icon icon; |
581 | - Noise.DevicePreferences pref; |
582 | bool is_androphone = false; |
583 | Gee.LinkedList<string> music_folders; |
584 | - |
585 | + |
586 | private AudioPlayerLibrary library; |
587 | - |
588 | - |
589 | + |
590 | public AudioPlayerDevice(Mount mount, bool is_androphone) { |
591 | this.mount = mount; |
592 | this.is_androphone = is_androphone; |
593 | music_folders = new Gee.LinkedList<string> (); |
594 | library = new AudioPlayerLibrary (this); |
595 | libraries_manager.add_library (library); |
596 | - icon = new Icon (is_androphone ? "phone" : "music-player").gicon; |
597 | - var device_manager = DeviceManager.get_default (); |
598 | - pref = device_manager.get_device_preferences (get_unique_identifier()); |
599 | - if(pref == null) { |
600 | - pref = new Noise.DevicePreferences (get_unique_identifier()); |
601 | - device_manager.add_device_preferences (pref); |
602 | - } |
603 | - } |
604 | - |
605 | - public Noise.DevicePreferences get_preferences() { |
606 | - return pref; |
607 | - } |
608 | + icon = new GLib.ThemedIcon (is_androphone ? "phone" : "music-player"); |
609 | + } |
610 | + |
611 | public void finish_initialization() { |
612 | device_unmounted.connect( () => { |
613 | |
614 | @@ -231,7 +220,7 @@ |
615 | } |
616 | |
617 | public void synchronize () { |
618 | - library.sync_medias (); |
619 | + |
620 | } |
621 | |
622 | public bool only_use_custom_view () { |
623 | |
624 | === modified file 'plugins/Devices/AudioPlayers/AudioPlayerLibrary.vala' |
625 | --- plugins/Devices/AudioPlayers/AudioPlayerLibrary.vala 2015-02-24 00:04:03 +0000 |
626 | +++ plugins/Devices/AudioPlayers/AudioPlayerLibrary.vala 2015-08-27 10:21:27 +0000 |
627 | @@ -110,7 +110,7 @@ |
628 | return; |
629 | } |
630 | |
631 | - int parsed_rating; |
632 | + uint parsed_rating; |
633 | string parsed_search_string; |
634 | String.base_search_method (search, out parsed_rating, out parsed_search_string); |
635 | bool rating_search = parsed_rating > 0; |
636 | @@ -118,7 +118,7 @@ |
637 | lock (medias) { |
638 | foreach (var m in medias) { |
639 | if (rating_search) { |
640 | - if (m.rating == (uint) parsed_rating) |
641 | + if (m.rating == parsed_rating) |
642 | searched_medias.add (m); |
643 | } else if (Search.match_string_to_media (m, parsed_search_string)) { |
644 | searched_medias.add (m); |
645 | @@ -185,96 +185,8 @@ |
646 | } |
647 | return; |
648 | } |
649 | - |
650 | - public void sync_medias () { |
651 | - if(doing_file_operations ()) { |
652 | - warning("Tried to add when already syncing\n"); |
653 | - return; |
654 | - } |
655 | - Playlist playlist = null; |
656 | - if (device.get_preferences().sync_all_music == false) { |
657 | - playlist = device.get_preferences().music_playlist; |
658 | - if (playlist == null) |
659 | - return; |
660 | - } |
661 | - |
662 | - |
663 | - libraries_manager.current_operation = _("Syncing <b>%s</b>…").printf (device.getDisplayName ()); |
664 | - |
665 | - is_doing_file_operations = true; |
666 | - Timeout.add(500, libraries_manager.do_progress_notification_with_timeout); |
667 | - if (playlist == null) |
668 | - sync_medias_async.begin (libraries_manager.local_library.get_medias ()); |
669 | - else |
670 | - sync_medias_async.begin (playlist.medias); |
671 | - return; |
672 | - } |
673 | - |
674 | - public async void sync_medias_async (Gee.Collection<Noise.Media> songs) { |
675 | - var medias_to_remove = new Gee.LinkedList<Noise.Media> (); |
676 | - medias_to_remove.add_all (device.delete_doubles (medias, songs)); |
677 | - |
678 | - var medias_to_sync = new Gee.LinkedList<Noise.Media> (); |
679 | - medias_to_sync.add_all (device.delete_doubles (songs, medias)); |
680 | - |
681 | - int total_medias = medias_to_remove.size + medias_to_sync.size; |
682 | - |
683 | - int sub_index = 0; |
684 | - if (total_medias > 0) { |
685 | - if (device.will_fit_without (medias_to_sync, medias_to_remove)) { |
686 | - foreach(var m in medias_to_remove) { |
687 | - if(!operation_cancelled) { |
688 | - remove_media(m, true); |
689 | - } |
690 | - ++sub_index; |
691 | - libraries_manager.progress = (double)(sub_index/total_medias); |
692 | - } |
693 | - sub_index = 0; |
694 | - imported_files = new Gee.LinkedList<string> (); |
695 | - foreach(var m in medias_to_sync) { |
696 | - if(!operation_cancelled) { |
697 | - add_media (m); |
698 | - } |
699 | - ++sub_index; |
700 | - libraries_manager.progress = (double)(sub_index/total_medias); |
701 | - } |
702 | - tagger.discoverer_import_media (imported_files); |
703 | - |
704 | - if(!operation_cancelled) { |
705 | - // sync playlists |
706 | - /* TODO: add support for podcasts & playlists |
707 | - if (pref.sync_all_music == true) { |
708 | - sync_playlists(); |
709 | - } |
710 | - if (pref.sync_all_podcasts == true) { |
711 | - sync_podcasts(); |
712 | - }*/ |
713 | - |
714 | - libraries_manager.current_operation = _("Finishing sync process…"); |
715 | - |
716 | - } else { |
717 | - libraries_manager.current_operation = _("Cancelling Sync…"); |
718 | - libraries_manager.progress = 1; |
719 | - } |
720 | - } else { |
721 | - device.infobar_message (_("There is not enough space on Device to complete the Sync…"), Gtk.MessageType.INFO); |
722 | - libraries_manager.current_operation = _("There is not enough space on Device to complete the Sync…"); |
723 | - } |
724 | - } |
725 | |
726 | - Idle.add( () => { |
727 | - libraries_manager.progress = 1; |
728 | - device.get_preferences().last_sync_time = (int)time_t(); |
729 | - is_doing_file_operations = false; |
730 | - |
731 | - file_operations_done (); |
732 | - operation_cancelled = false; |
733 | - |
734 | - return false; |
735 | - }); |
736 | - } |
737 | - |
738 | - public override Media? media_from_id (int id) { |
739 | + public override Media? media_from_id (int64 id) { |
740 | lock (medias) { |
741 | foreach (var m in medias) { |
742 | if (m.rowid == id) { |
743 | @@ -284,7 +196,8 @@ |
744 | } |
745 | return null; |
746 | } |
747 | - public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int> ids) { |
748 | + |
749 | + public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int64?> ids) { |
750 | var media_collection = new Gee.LinkedList<Media> (); |
751 | |
752 | lock (medias) { |
753 | @@ -406,10 +319,10 @@ |
754 | public override void add_smart_playlist (SmartPlaylist p) { |
755 | |
756 | } |
757 | - public override void remove_smart_playlist (int id) { |
758 | + public override void remove_smart_playlist (int64 id) { |
759 | |
760 | } |
761 | - public override SmartPlaylist? smart_playlist_from_id (int id) { |
762 | + public override SmartPlaylist? smart_playlist_from_id (int64 id) { |
763 | return null; |
764 | } |
765 | public override SmartPlaylist? smart_playlist_from_name (string name) { |
766 | @@ -429,14 +342,18 @@ |
767 | p.media_removed.connect(() => {keep_playlist_synchronized (p);}); |
768 | p.updated.connect ((old_name) => {remove_playlist_from_name (old_name); keep_playlist_synchronized (p);}); |
769 | } |
770 | - public override void remove_playlist (int id) { |
771 | + public override void remove_playlist (int64 id) { |
772 | if (id < get_playlists ().size) { |
773 | var array_v = new Gee.ArrayList<StaticPlaylist> (); |
774 | array_v.add_all (playlists); |
775 | - var p = array_v.get (id); |
776 | - remove_playlist_from_name (p.name); |
777 | - playlist_removed (p); |
778 | - playlists.remove (p); |
779 | + foreach (var p in array_v) { |
780 | + if (p.rowid == id) { |
781 | + remove_playlist_from_name (p.name); |
782 | + playlist_removed (p); |
783 | + playlists.remove (p); |
784 | + return; |
785 | + } |
786 | + } |
787 | } |
788 | } |
789 | |
790 | @@ -475,11 +392,14 @@ |
791 | } |
792 | } |
793 | |
794 | - public override StaticPlaylist? playlist_from_id (int id) { |
795 | + public override StaticPlaylist? playlist_from_id (int64 id) { |
796 | if (id < get_playlists ().size) { |
797 | var array = new Gee.ArrayList<StaticPlaylist> (); |
798 | array.add_all (get_playlists ()); |
799 | - return array.get (id); |
800 | + foreach (var playlist in array) { |
801 | + if (playlist.rowid == id) |
802 | + return playlist; |
803 | + } |
804 | } |
805 | return null; |
806 | } |
807 | |
808 | === modified file 'plugins/Devices/CDRom/CDRomDevice.vala' |
809 | --- plugins/Devices/CDRom/CDRomDevice.vala 2015-06-12 13:31:55 +0000 |
810 | +++ plugins/Devices/CDRom/CDRomDevice.vala 2015-08-27 10:21:27 +0000 |
811 | @@ -48,7 +48,7 @@ |
812 | |
813 | public CDRomDevice(Mount mount) { |
814 | this.mount = mount; |
815 | - this.icon = new Icon ("media-cdrom-audio").gicon; |
816 | + this.icon = new GLib.ThemedIcon ("media-cdrom-audio"); |
817 | this.display_name = mount.get_name(); |
818 | |
819 | list = new Gee.LinkedList<Noise.Media>(); |
820 | @@ -58,11 +58,7 @@ |
821 | cdplayer = new CDPlayer (mount); |
822 | Noise.App.player.add_playback (cdplayer); |
823 | } |
824 | - |
825 | - public Noise.DevicePreferences get_preferences() { |
826 | - return new Noise.DevicePreferences(get_unique_identifier()); |
827 | - } |
828 | - |
829 | + |
830 | public bool start_initialization() { |
831 | return true; |
832 | } |
833 | |
834 | === modified file 'plugins/Devices/CDRom/CDViewWrapper.vala' |
835 | --- plugins/Devices/CDRom/CDViewWrapper.vala 2015-06-12 16:10:33 +0000 |
836 | +++ plugins/Devices/CDRom/CDViewWrapper.vala 2015-08-27 10:21:27 +0000 |
837 | @@ -28,7 +28,7 @@ |
838 | |
839 | public CDViewWrapper (Noise.StaticPlaylist p) { |
840 | base (ViewWrapper.Hint.READ_ONLY_PLAYLIST, libraries_manager.local_library); |
841 | - tvs = new TreeViewSetup(ListColumn.NUMBER, Gtk.SortType.ASCENDING, ViewWrapper.Hint.ALBUM_LIST); |
842 | + tvs = new TreeViewSetup (ViewWrapper.Hint.PLAYLIST); |
843 | message_head = _("An Error Occured"); |
844 | message_body = _("There was an error while loading this Audio CD."); |
845 | message_type = Gtk.MessageType.ERROR; |
846 | |
847 | === modified file 'plugins/Devices/iPod/iPodDevice.vala' |
848 | --- plugins/Devices/iPod/iPodDevice.vala 2015-02-24 00:04:03 +0000 |
849 | +++ plugins/Devices/iPod/iPodDevice.vala 2015-08-27 10:21:27 +0000 |
850 | @@ -21,7 +21,6 @@ |
851 | */ |
852 | |
853 | public class Noise.Plugins.iPodDevice : GLib.Object, Noise.Device { |
854 | - Noise.DevicePreferences pref; |
855 | GPod.iTunesDB db; |
856 | public Mount mount; |
857 | GLib.Icon icon; |
858 | @@ -32,17 +31,7 @@ |
859 | public iPodDevice (Mount mount) { |
860 | this.mount = mount; |
861 | is_new = mount.get_default_location ().get_parse_name ().has_prefix ("afc://"); |
862 | - var device_manager = DeviceManager.get_default (); |
863 | - pref = device_manager.get_device_preferences (get_unique_identifier ()); |
864 | - icon = new Icon (is_new ? "phone" : "multimedia-player").gicon; |
865 | - if (pref == null) { |
866 | - pref = new Noise.DevicePreferences (get_unique_identifier ()); |
867 | - device_manager.add_device_preferences (pref); |
868 | - } |
869 | - } |
870 | - |
871 | - public Noise.DevicePreferences get_preferences () { |
872 | - return pref; |
873 | + icon = new GLib.ThemedIcon (is_new ? "phone" : "multimedia-player"); |
874 | } |
875 | |
876 | public bool start_initialization () { |
877 | |
878 | === modified file 'plugins/Devices/iPod/iPodLibrary.vala' |
879 | --- plugins/Devices/iPod/iPodLibrary.vala 2015-03-13 18:01:49 +0000 |
880 | +++ plugins/Devices/iPod/iPodLibrary.vala 2015-08-27 10:21:27 +0000 |
881 | @@ -96,7 +96,7 @@ |
882 | return; |
883 | } |
884 | |
885 | - int parsed_rating; |
886 | + uint parsed_rating; |
887 | string parsed_search_string; |
888 | String.base_search_method (search, out parsed_rating, out parsed_search_string); |
889 | bool rating_search = parsed_rating > 0; |
890 | @@ -104,7 +104,7 @@ |
891 | lock (medias) { |
892 | foreach (var m in medias.values) { |
893 | if (rating_search) { |
894 | - if (m.rating == (uint) parsed_rating) |
895 | + if (m.rating == parsed_rating) |
896 | searched_medias.add (m); |
897 | } else if (Search.match_string_to_media (m, parsed_search_string)) { |
898 | searched_medias.add (m); |
899 | @@ -242,11 +242,11 @@ |
900 | }); |
901 | } |
902 | |
903 | - public override Media? media_from_id (int id) { |
904 | + public override Media? media_from_id (int64 id) { |
905 | return null; |
906 | } |
907 | |
908 | - public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int> ids) { |
909 | + public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int64?> ids) { |
910 | var media_collection = new Gee.LinkedList<Media> (); |
911 | lock (medias) { |
912 | foreach (var m in medias.values) { |
913 | @@ -406,11 +406,11 @@ |
914 | return false; |
915 | } |
916 | |
917 | - public override void remove_smart_playlist (int id) { |
918 | + public override void remove_smart_playlist (int64 id) { |
919 | |
920 | } |
921 | |
922 | - public override SmartPlaylist? smart_playlist_from_id (int id) { |
923 | + public override SmartPlaylist? smart_playlist_from_id (int64 id) { |
924 | return null; |
925 | } |
926 | |
927 | @@ -439,24 +439,27 @@ |
928 | p.media_removed.connect((list) => {keep_playlist_synchronized (p, list, false);}); |
929 | } |
930 | |
931 | - public override void remove_playlist (int id) { |
932 | - if (id < get_playlists ().size) { |
933 | - var array = new Gee.ArrayList<unowned GPod.Playlist> (); |
934 | - array.add_all (playlists.keys); |
935 | - var array_v = new Gee.ArrayList<StaticPlaylist> (); |
936 | - array_v.add_all (playlists.values); |
937 | - playlist_removed (array_v.get (id)); |
938 | - playlists.unset (array.get (id)); |
939 | - db.start_sync (); |
940 | - array.get (id).remove (); |
941 | - try { |
942 | - db.write (); |
943 | - } catch (Error err) { |
944 | - critical ("Error when writing iPod database. iPod contents may be incorrect: %s", err.message); |
945 | + public override void remove_playlist (int64 id) { |
946 | + unowned GPod.Playlist to_unset = null; |
947 | + foreach (var entry in playlists.entries) { |
948 | + if (entry.value.rowid == id) { |
949 | + playlist_removed (entry.value); |
950 | + to_unset = entry.key; |
951 | } |
952 | - |
953 | - db.stop_sync (); |
954 | - } |
955 | + } |
956 | + |
957 | + if (to_unset != null) |
958 | + playlists.unset (to_unset); |
959 | + |
960 | + db.start_sync (); |
961 | + to_unset.remove (); |
962 | + try { |
963 | + db.write (); |
964 | + } catch (Error err) { |
965 | + critical ("Error when writing iPod database. iPod contents may be incorrect: %s", err.message); |
966 | + } |
967 | + |
968 | + db.stop_sync (); |
969 | } |
970 | |
971 | private void keep_playlist_synchronized (StaticPlaylist p, Gee.Collection<Media> m, bool to_add) { |
972 | @@ -488,12 +491,13 @@ |
973 | db.stop_sync (); |
974 | } |
975 | |
976 | - public override StaticPlaylist? playlist_from_id (int id) { |
977 | - if (id < get_playlists ().size) { |
978 | - var array = new Gee.ArrayList<StaticPlaylist> (); |
979 | - array.add_all (get_playlists ()); |
980 | - return array.get (id); |
981 | + public override StaticPlaylist? playlist_from_id (int64 id) { |
982 | + foreach (var p in playlists.values) { |
983 | + if (p.rowid == id) { |
984 | + return p; |
985 | + } |
986 | } |
987 | + |
988 | return null; |
989 | } |
990 | |
991 | @@ -562,157 +566,6 @@ |
992 | } |
993 | } |
994 | |
995 | - public bool sync_medias (Gee.Collection<Noise.Media> medias) { |
996 | - if (is_doing_file_operations) { |
997 | - warning("Tried to sync when already syncing\n"); |
998 | - return false; |
999 | - } |
1000 | - |
1001 | - libraries_manager.current_operation = _("Syncing <b>%s</b>…").printf (device.getDisplayName ()); |
1002 | - is_doing_file_operations = true; |
1003 | - Timeout.add(500, libraries_manager.do_progress_notification_with_timeout); |
1004 | - sync_medias_async.begin (medias); |
1005 | - return true; |
1006 | - } |
1007 | - |
1008 | - public async void sync_medias_async (Gee.Collection<Noise.Media> given_medias) { |
1009 | - bool error_occurred = false; |
1010 | - int sub_index = 0; |
1011 | - debug ("Found %d medias to sync.", given_medias.size); |
1012 | - var medias_to_remove = device.delete_doubles (medias.values, given_medias); |
1013 | - debug ("Found %d medias to remove.", medias_to_remove.size); |
1014 | - var medias_to_sync = device.delete_doubles (given_medias, medias.values); |
1015 | - debug ("Found %d medias to add.", medias_to_sync.size); |
1016 | - int total_medias = medias_to_remove.size + medias_to_sync.size; |
1017 | - if (total_medias > 0) { |
1018 | - if (device.will_fit_without(medias_to_sync, medias_to_remove)) { |
1019 | - db.start_sync(); |
1020 | - foreach (var m in medias_to_remove) { |
1021 | - if (!operation_cancelled) { |
1022 | - foreach (var e in medias.entries) { |
1023 | - if (e.value == m) { |
1024 | - remove_media_from_ipod (e.key); |
1025 | - break; |
1026 | - } |
1027 | - } |
1028 | - } |
1029 | - |
1030 | - ++sub_index; |
1031 | - libraries_manager.progress = (double)(sub_index/total_medias); |
1032 | - } |
1033 | - |
1034 | - foreach (var m in medias_to_sync) { |
1035 | - if (!operation_cancelled) { |
1036 | - add_media (m); |
1037 | - } |
1038 | - |
1039 | - ++sub_index; |
1040 | - libraries_manager.progress = (double)(sub_index/total_medias); |
1041 | - } |
1042 | - |
1043 | - if (!operation_cancelled) { |
1044 | - // sync playlists |
1045 | - /* TODO: add support for podcasts & playlists |
1046 | - if (pref.sync_all_music == true) { |
1047 | - sync_playlists(); |
1048 | - } |
1049 | - if (pref.sync_all_podcasts == true) { |
1050 | - sync_podcasts(); |
1051 | - }*/ |
1052 | - |
1053 | - libraries_manager.current_operation = _("Finishing sync process…"); |
1054 | - try { |
1055 | - db.write (); |
1056 | - } catch (GLib.Error err) { |
1057 | - error_occurred = true; |
1058 | - operation_cancelled = true; |
1059 | - } |
1060 | - |
1061 | - /// Clean up unused files |
1062 | - debug ("Cleaning up iPod File System\n"); |
1063 | - var music_folder = File.new_for_uri (device.get_uri () + GPod.Device.get_music_dir (device.get_mount ().get_default_location ().get_path ()).replace (device.get_mount ().get_default_location ().get_path (), "")); |
1064 | - var used_paths = new Gee.LinkedList<string> (); |
1065 | - foreach (unowned GPod.Track t in medias.keys) { |
1066 | - used_paths.add (device.get_uri () + GPod.iTunesDB.filename_ipod2fs (t.ipod_path)); |
1067 | - } |
1068 | - |
1069 | - cleanup_files (music_folder, used_paths); |
1070 | - libraries_manager.progress = 1; |
1071 | - db.stop_sync (); |
1072 | - } else { |
1073 | - libraries_manager.current_operation = _("Cancelling Sync…"); |
1074 | - try { |
1075 | - db.write (); |
1076 | - } catch (Error err) { |
1077 | - critical ("Error when writing iPod database. iPod contents may be incorrect: %s", err.message); |
1078 | - } |
1079 | - db.stop_sync (); |
1080 | - libraries_manager.progress = 1; |
1081 | - } |
1082 | - } else { |
1083 | - device.infobar_message (_("There is not enough space on Device to complete the Sync…"), Gtk.MessageType.INFO); |
1084 | - libraries_manager.current_operation = _("There is not enough space on Device to complete the Sync…"); |
1085 | - } |
1086 | - } |
1087 | - |
1088 | - Idle.add (() => { |
1089 | - libraries_manager.progress = 1; |
1090 | - device.get_preferences ().last_sync_time = (int)time_t (); |
1091 | - is_doing_file_operations = false; |
1092 | - file_operations_done (); |
1093 | - operation_cancelled = false; |
1094 | - return false; |
1095 | - }); |
1096 | - } |
1097 | - |
1098 | - public async void sync_playlists_async (Gee.Collection<Noise.Playlist> spls) { |
1099 | - |
1100 | - /*current_operation = _("Syncing playlists"); |
1101 | - // first remove all playlists from db |
1102 | - var all_playlists = new Gee.LinkedList<unowned GPod.Playlist>(); |
1103 | - foreach (unowned GPod.Playlist p in db.playlists) { |
1104 | - if (!p.is_mpl() && !p.is_podcasts() && !p.is_audiobooks()) { |
1105 | - all_playlists.add(p); |
1106 | - } |
1107 | - } |
1108 | - foreach (unowned GPod.Playlist p in all_playlists) { |
1109 | - p.remove(); |
1110 | - } |
1111 | - |
1112 | - int sub_index = 0; |
1113 | - foreach (var playlist in pls) { |
1114 | - GPod.Playlist p = iPodPlaylistHelper.get_gpod_playlist_from_playlist (playlist); |
1115 | - db.playlist_add((owned)p, -1); |
1116 | - |
1117 | - unowned GPod.Playlist added = db.playlists.nth_data(db.playlists.length() - 1); |
1118 | - foreach (var entry in medias.entries) { |
1119 | - foreach (var e in playlist.medias) { |
1120 | - if (entry.value == e) { |
1121 | - added.add_track(entry.key, -1); |
1122 | - ++sub_index; |
1123 | - //index = (int)(78.0 + (double)(7.0 * (double)((double)sub_index/(double)pls.size))); |
1124 | - break; |
1125 | - } |
1126 | - } |
1127 | - } |
1128 | - } |
1129 | - |
1130 | - foreach (var smart_playlist in spls) { |
1131 | - GPod.Playlist p = iPodPlaylistHelper.get_gpod_playlist_from_smart_playlist (smart_playlist); |
1132 | - |
1133 | - db.playlist_add((owned)p, -1); |
1134 | - |
1135 | - ++sub_index; |
1136 | - //index = (int)(85.0 + (double)(5.0 * (double)((double)sub_index/(double)spls.size))); |
1137 | - } |
1138 | - db.spl_update_live(); |
1139 | - |
1140 | - Idle.add( () => { |
1141 | - |
1142 | - return false; |
1143 | - });*/ |
1144 | - } |
1145 | - |
1146 | void cleanup_files(GLib.File music_folder, Gee.LinkedList<string> used_uris) { |
1147 | GLib.FileInfo file_info = null; |
1148 | try { |
1149 | |
1150 | === modified file 'plugins/Devices/iPod/iPodPlaylistHelper.vala' |
1151 | --- plugins/Devices/iPod/iPodPlaylistHelper.vala 2015-02-26 16:44:26 +0000 |
1152 | +++ plugins/Devices/iPod/iPodPlaylistHelper.vala 2015-08-27 10:21:27 +0000 |
1153 | @@ -115,59 +115,57 @@ |
1154 | message("adding rule\n"); |
1155 | if (q.field == SmartQuery.FieldType.ALBUM) { // strings |
1156 | rule.field = GPod.SPLField.ALBUM; |
1157 | - rule.@string = q.value; |
1158 | + rule.@string = q.value.get_string (); |
1159 | } else if (q.field == SmartQuery.FieldType.ARTIST) { |
1160 | rule.field = GPod.SPLField.ARTIST; |
1161 | - rule.@string = q.value; |
1162 | + rule.@string = q.value.get_string (); |
1163 | } else if (q.field == SmartQuery.FieldType.COMPOSER) { |
1164 | rule.field = GPod.SPLField.COMPOSER; |
1165 | - rule.@string = q.value; |
1166 | + rule.@string = q.value.get_string (); |
1167 | } else if (q.field == SmartQuery.FieldType.COMMENT) { |
1168 | rule.field = GPod.SPLField.COMMENT; |
1169 | - rule.@string = q.value; |
1170 | + rule.@string = q.value.get_string (); |
1171 | } else if (q.field == SmartQuery.FieldType.GENRE) { |
1172 | rule.field = GPod.SPLField.GENRE; |
1173 | - rule.@string = q.value; |
1174 | + rule.@string = q.value.get_string (); |
1175 | } else if (q.field == SmartQuery.FieldType.GROUPING) { |
1176 | rule.field = GPod.SPLField.GROUPING; |
1177 | - rule.@string = q.value; |
1178 | + rule.@string = q.value.get_string (); |
1179 | } else if (q.field == SmartQuery.FieldType.TITLE) { |
1180 | rule.field = GPod.SPLField.SONG_NAME; |
1181 | - rule.@string = q.value; |
1182 | + rule.@string = q.value.get_string (); |
1183 | } else if (q.field == SmartQuery.FieldType.BITRATE) { // ints |
1184 | rule.field = GPod.SPLField.BITRATE; |
1185 | - rule.fromvalue = uint64.parse (q.value); |
1186 | - rule.tovalue = uint64.parse (q.value); |
1187 | + rule.fromvalue = (uint64)q.value.get_int (); |
1188 | + rule.tovalue = (uint64)q.value.get_int (); |
1189 | } else if (q.field == SmartQuery.FieldType.PLAYCOUNT) { |
1190 | rule.field = GPod.SPLField.PLAYCOUNT; |
1191 | - rule.fromvalue = uint64.parse (q.value); |
1192 | - rule.tovalue = uint64.parse (q.value); |
1193 | + rule.fromvalue =(uint64)q.value.get_int (); |
1194 | + rule.tovalue = (uint64)q.value.get_int (); |
1195 | } else if (q.field == SmartQuery.FieldType.SKIPCOUNT) { |
1196 | rule.field = GPod.SPLField.SKIPCOUNT; |
1197 | - rule.fromvalue = uint64.parse (q.value); |
1198 | - rule.tovalue = uint64.parse (q.value); |
1199 | + rule.fromvalue = (uint64)q.value.get_int (); |
1200 | + rule.tovalue = (uint64)q.value.get_int (); |
1201 | } else if (q.field == SmartQuery.FieldType.YEAR) { |
1202 | rule.field = GPod.SPLField.YEAR; |
1203 | - rule.fromvalue = uint64.parse (q.value); |
1204 | - rule.tovalue = uint64.parse (q.value); |
1205 | + rule.fromvalue = (uint64)q.value.get_int (); |
1206 | + rule.tovalue = (uint64)q.value.get_int (); |
1207 | } else if (q.field == SmartQuery.FieldType.LENGTH) { |
1208 | rule.field = GPod.SPLField.TIME; |
1209 | - rule.fromvalue = uint64.parse (q.value) * 1000; |
1210 | - rule.tovalue = uint64.parse (q.value) * 1000; |
1211 | + rule.fromvalue = (uint64)q.value.get_int () * 1000; |
1212 | + rule.tovalue = (uint64)q.value.get_int () * 1000; |
1213 | } else if (q.field == SmartQuery.FieldType.RATING) { |
1214 | rule.field = GPod.SPLField.RATING; |
1215 | - rule.fromvalue = uint64.parse (q.value) * 20; |
1216 | - rule.tovalue = uint64.parse (q.value) * 20; |
1217 | + rule.fromvalue = (uint64)q.value.get_int () * 20; |
1218 | + rule.tovalue = (uint64)q.value.get_int () * 20; |
1219 | } else if (q.field == SmartQuery.FieldType.DATE_ADDED) { |
1220 | rule.field = GPod.SPLField.DATE_ADDED; |
1221 | - rule.fromvalue = uint64.parse (q.value) * 1000; |
1222 | - rule.tovalue = uint64.parse (q.value) * 1000; |
1223 | + rule.fromvalue = (uint64)q.value.get_int () * 1000; |
1224 | + rule.tovalue = (uint64)q.value.get_int () * 1000; |
1225 | } else if (q.field == SmartQuery.FieldType.LAST_PLAYED) { |
1226 | rule.field = GPod.SPLField.LAST_PLAYED; |
1227 | - rule.fromvalue = uint64.parse (q.value) * 20; |
1228 | - rule.tovalue = uint64.parse (q.value) * 20; |
1229 | - } else if (q.field == SmartQuery.FieldType.DATE_RELEASED) { |
1230 | - // no equivalant |
1231 | + rule.fromvalue = (uint64)q.value.get_int () * 20; |
1232 | + rule.tovalue = (uint64)q.value.get_int () * 20; |
1233 | } |
1234 | /* |
1235 | else if (q.field == SmartQuery.FieldType.MEDIA_TYPE) { |
1236 | @@ -220,108 +218,88 @@ |
1237 | switch (field) { |
1238 | case SmartQuery.FieldType.ALBUM: |
1239 | rule.field = GPod.SPLField.ALBUM; |
1240 | - rule.@string = value; |
1241 | + rule.@string = value.get_string (); |
1242 | break; |
1243 | case SmartQuery.FieldType.ARTIST: |
1244 | rule.field = GPod.SPLField.ARTIST; |
1245 | - rule.@string = value; |
1246 | + rule.@string = value.get_string (); |
1247 | break; |
1248 | case SmartQuery.FieldType.COMPOSER: |
1249 | rule.field = GPod.SPLField.COMPOSER; |
1250 | - rule.@string = value; |
1251 | + rule.@string = value.get_string (); |
1252 | break; |
1253 | case SmartQuery.FieldType.COMMENT: |
1254 | rule.field = GPod.SPLField.COMMENT; |
1255 | - rule.@string = value; |
1256 | + rule.@string = value.get_string (); |
1257 | break; |
1258 | case SmartQuery.FieldType.GENRE: |
1259 | rule.field = GPod.SPLField.GENRE; |
1260 | - rule.@string = value; |
1261 | + rule.@string = value.get_string (); |
1262 | break; |
1263 | case SmartQuery.FieldType.GROUPING: |
1264 | rule.field = GPod.SPLField.GROUPING; |
1265 | - rule.@string = value; |
1266 | + rule.@string = value.get_string (); |
1267 | break; |
1268 | case SmartQuery.FieldType.TITLE: |
1269 | rule.field = GPod.SPLField.SONG_NAME; |
1270 | - rule.@string = value; |
1271 | + rule.@string = value.get_string (); |
1272 | break; |
1273 | case SmartQuery.FieldType.BITRATE: |
1274 | rule.field = GPod.SPLField.BITRATE; |
1275 | - rule.fromvalue = uint64.parse (value); |
1276 | - rule.tovalue = uint64.parse (value); |
1277 | + rule.fromvalue = (uint64)value.get_int (); |
1278 | + rule.tovalue = (uint64)value.get_int (); |
1279 | rule.tounits = 1; |
1280 | rule.fromunits = 1; |
1281 | break; |
1282 | case SmartQuery.FieldType.PLAYCOUNT: |
1283 | rule.field = GPod.SPLField.PLAYCOUNT; |
1284 | - rule.fromvalue = uint64.parse (value); |
1285 | - rule.tovalue = uint64.parse (value); |
1286 | + rule.fromvalue = (uint64)value.get_int (); |
1287 | + rule.tovalue = (uint64)value.get_int (); |
1288 | rule.tounits = 1; |
1289 | rule.fromunits = 1; |
1290 | break; |
1291 | case SmartQuery.FieldType.SKIPCOUNT: |
1292 | rule.field = GPod.SPLField.SKIPCOUNT; |
1293 | - rule.fromvalue = uint64.parse (value); |
1294 | - rule.tovalue = uint64.parse (value); |
1295 | + rule.fromvalue = (uint64)value.get_int (); |
1296 | + rule.tovalue = (uint64)value.get_int (); |
1297 | rule.tounits = 1; |
1298 | break; |
1299 | case SmartQuery.FieldType.YEAR: |
1300 | rule.field = GPod.SPLField.YEAR; |
1301 | - rule.fromvalue = uint64.parse (value); |
1302 | - rule.tovalue = uint64.parse (value); |
1303 | + rule.fromvalue = (uint64)value.get_int (); |
1304 | + rule.tovalue = (uint64)value.get_int (); |
1305 | rule.tounits = 1; |
1306 | rule.fromunits = 1; |
1307 | break; |
1308 | case SmartQuery.FieldType.LENGTH: |
1309 | rule.field = GPod.SPLField.TIME; |
1310 | - rule.fromvalue = uint64.parse (value) * 1000; |
1311 | - rule.tovalue = uint64.parse (value) * 1000; |
1312 | + rule.fromvalue = (uint64)value.get_int () * 1000; |
1313 | + rule.tovalue = (uint64)value.get_int () * 1000; |
1314 | rule.tounits = 1; |
1315 | rule.fromunits = 1; |
1316 | break; |
1317 | case SmartQuery.FieldType.RATING: |
1318 | - message("rating rule is %s\n", value); |
1319 | + message("rating rule is %d\n", value.get_int ()); |
1320 | rule.field = GPod.SPLField.RATING; |
1321 | - rule.fromvalue = uint64.parse (value) * 20; |
1322 | - rule.tovalue = uint64.parse (value) * 20; |
1323 | + rule.fromvalue = (uint64)value.get_int () * 20; |
1324 | + rule.tovalue = (uint64)value.get_int () * 20; |
1325 | rule.tounits = 1;//20; |
1326 | rule.fromunits = 1;//20; |
1327 | break; |
1328 | case SmartQuery.FieldType.DATE_ADDED: |
1329 | rule.field = GPod.SPLField.DATE_ADDED; |
1330 | - rule.fromvalue = uint64.parse (value) * 60 * 60 * 24; |
1331 | - rule.tovalue = uint64.parse (value) * 60 * 60 * 24; |
1332 | + rule.fromvalue = (uint64)value.get_int () * 60 * 60 * 24; |
1333 | + rule.tovalue = (uint64)value.get_int () * 60 * 60 * 24; |
1334 | rule.tounits = 1;//60 * 60 * 24; |
1335 | rule.fromunits = 1;//60 * 60 * 24; |
1336 | break; |
1337 | case SmartQuery.FieldType.LAST_PLAYED: |
1338 | rule.field = GPod.SPLField.LAST_PLAYED; |
1339 | - rule.fromvalue = uint64.parse (value) * 60 * 60 * 24; |
1340 | - rule.tovalue = uint64.parse (value) * 60 * 60 * 24; |
1341 | + rule.fromvalue = (uint64)value.get_int () * 60 * 60 * 24; |
1342 | + rule.tovalue = (uint64)value.get_int () * 60 * 60 * 24; |
1343 | rule.tounits = 1;//60 * 60 * 24; |
1344 | rule.fromunits = 1;//60 * 60 * 24; |
1345 | break; |
1346 | - case SmartQuery.FieldType.DATE_RELEASED: |
1347 | - // no equivelant |
1348 | - break; |
1349 | -/* |
1350 | - case SmartQuery.FieldType.MEDIA_TYPE: |
1351 | - rule.field = GPod.SPLField.VIDEO_KIND; |
1352 | - if (value == "0") { |
1353 | - message ("must be song\n"); |
1354 | - rule.fromvalue = 0x00000001; |
1355 | - rule.tovalue = 0x00000001;; |
1356 | - } else if (value == "1") { |
1357 | - rule.fromvalue = 0x00000006; |
1358 | - rule.tovalue = 0x00000006; |
1359 | - message ("must be podcast\n"); |
1360 | - } else if (value == "2") { |
1361 | - rule.fromvalue = 0x00000008; |
1362 | - rule.tovalue = 0x00000008; |
1363 | - } |
1364 | - break; |
1365 | -*/ |
1366 | } |
1367 | |
1368 | // set action type |
1369 | |
1370 | === modified file 'plugins/LastFM/Core.vala' |
1371 | --- plugins/LastFM/Core.vala 2015-05-07 22:46:59 +0000 |
1372 | +++ plugins/LastFM/Core.vala 2015-08-27 10:21:27 +0000 |
1373 | @@ -45,11 +45,15 @@ |
1374 | return core; |
1375 | } |
1376 | |
1377 | + private GLib.Cancellable fetch_cancellable; |
1378 | + |
1379 | private Core () { |
1380 | - similarMedias = new LastFM.SimilarMedias(); |
1381 | + fetch_cancellable = new GLib.Cancellable (); |
1382 | + similarMedias = new LastFM.SimilarMedias (); |
1383 | Noise.App.main_window.update_media_info.connect ((media) => {postNowPlaying (media);}); |
1384 | Noise.App.main_window.media_half_played.connect ((media) => {postScrobbleTrack (media);}); |
1385 | Noise.libraries_manager.local_library.media_imported.connect ((medias) => {fetch_albums_slowly.begin (medias);}); |
1386 | + Noise.NotificationManager.get_default ().search_cover.connect ((m) => { get_album_infos.begin (m, fetch_cancellable);}); |
1387 | similarMedias.similar_retrieved.connect(similar_retrieved_signal); |
1388 | } |
1389 | |
1390 | @@ -126,22 +130,11 @@ |
1391 | albums.add (album_s); |
1392 | if (!album_artist.contains (album_artist_s)) |
1393 | album_artist.add (album_artist_s); |
1394 | - fetch_album_info (media); |
1395 | + get_album_infos.begin (media, fetch_cancellable); |
1396 | } |
1397 | } |
1398 | } |
1399 | |
1400 | - public void fetch_album_info (Noise.Media media) { |
1401 | - try { |
1402 | - new Thread<void*>.try (null, () => { |
1403 | - get_album_infos (media); |
1404 | - return null; |
1405 | - }); |
1406 | - } catch (GLib.Error err) { |
1407 | - warning ("ERROR: Could not create thread to have fun: %s", err.message); |
1408 | - } |
1409 | - } |
1410 | - |
1411 | /** Update's the user's currently playing track on last.fm |
1412 | * |
1413 | */ |
1414 | @@ -188,7 +181,7 @@ |
1415 | } |
1416 | |
1417 | public void fetchCurrentSimilarSongs () { |
1418 | - similarMedias.queryForSimilar (Noise.App.player.current_media); |
1419 | + similarMedias.query_for_similar (Noise.App.player.current_media); |
1420 | } |
1421 | |
1422 | private void similar_retrieved_signal (Gee.LinkedList<int> similarIDs, Gee.LinkedList<Noise.Media> similarDont) { |
1423 | @@ -201,7 +194,7 @@ |
1424 | * @param title The title of media to get similar to |
1425 | * @return The media that are similar |
1426 | */ |
1427 | - public Gee.TreeSet<Noise.Media> getSimilarTracks(string title, string artist) { |
1428 | + public async Gee.TreeSet<Noise.Media> get_similar_tracks (string title, string artist, GLib.Cancellable cancellable) { |
1429 | var returned_medias = new Gee.TreeSet<Noise.Media> (); |
1430 | |
1431 | var uri = new Soup.URI (API_URL); |
1432 | @@ -211,38 +204,42 @@ |
1433 | "track", title, |
1434 | "format", "json"); |
1435 | var session = new Soup.Session (); |
1436 | - var uri_request = session.request_uri (uri); |
1437 | - |
1438 | - /* send the HTTP request */ |
1439 | - var stream = uri_request.send (); |
1440 | - var parser = new Json.Parser (); |
1441 | - parser.load_from_stream (stream); |
1442 | - weak Json.Object parser_object = parser.get_root ().get_object (); |
1443 | - if (parser_object == null || parser_object.has_member ("similartracks") == false) |
1444 | - return returned_medias; |
1445 | - |
1446 | - weak Json.Object similartracks = parser_object.get_object_member ("similartracks"); |
1447 | - if (similartracks.has_member ("track") && similartracks.get_member ("track").get_node_type () == Json.NodeType.ARRAY) { |
1448 | - List<unowned Json.Node> similar_tracks_values = similartracks.get_array_member ("track").get_elements (); |
1449 | - foreach (unowned Json.Node element in similar_tracks_values) { |
1450 | - weak Json.Object track_object = element.get_object (); |
1451 | - var similar_to_add = new Noise.Media (""); |
1452 | - returned_medias.add (similar_to_add); |
1453 | - similar_to_add.title = track_object.get_string_member ("name"); |
1454 | - if (track_object.has_member ("url")) |
1455 | - similar_to_add.comment = track_object.get_string_member ("url"); |
1456 | - if (track_object.has_member ("artist")) { |
1457 | - weak Json.Object artist_object = track_object.get_object_member ("artist"); |
1458 | - if (artist_object.has_member ("name")) |
1459 | - similar_to_add.artist = artist_object.get_string_member ("name"); |
1460 | + try { |
1461 | + var uri_request = session.request_uri (uri); |
1462 | + |
1463 | + /* send the HTTP request */ |
1464 | + var stream = yield uri_request.send_async (cancellable); |
1465 | + var parser = new Json.Parser (); |
1466 | + parser.load_from_stream (stream); |
1467 | + weak Json.Object parser_object = parser.get_root ().get_object (); |
1468 | + if (parser_object == null || parser_object.has_member ("similartracks") == false) |
1469 | + return returned_medias; |
1470 | + |
1471 | + weak Json.Object similartracks = parser_object.get_object_member ("similartracks"); |
1472 | + if (similartracks.has_member ("track") && similartracks.get_member ("track").get_node_type () == Json.NodeType.ARRAY) { |
1473 | + List<unowned Json.Node> similar_tracks_values = similartracks.get_array_member ("track").get_elements (); |
1474 | + foreach (unowned Json.Node element in similar_tracks_values) { |
1475 | + weak Json.Object track_object = element.get_object (); |
1476 | + var similar_to_add = new Noise.Media (""); |
1477 | + returned_medias.add (similar_to_add); |
1478 | + similar_to_add.title = track_object.get_string_member ("name"); |
1479 | + if (track_object.has_member ("url")) |
1480 | + similar_to_add.comment = track_object.get_string_member ("url"); |
1481 | + if (track_object.has_member ("artist")) { |
1482 | + weak Json.Object artist_object = track_object.get_object_member ("artist"); |
1483 | + if (artist_object.has_member ("name")) |
1484 | + similar_to_add.artist = artist_object.get_string_member ("name"); |
1485 | + } |
1486 | } |
1487 | } |
1488 | + } catch (Error e) { |
1489 | + critical (e.message); |
1490 | } |
1491 | |
1492 | return returned_medias; |
1493 | } |
1494 | |
1495 | - public void get_album_infos (Noise.Media m) { |
1496 | + public async void get_album_infos (Noise.Media m, Cancellable cancellable) { |
1497 | var uri = new Soup.URI (API_URL); |
1498 | uri.set_query_from_fields ("method", "album.getinfo", |
1499 | "api_key", api_key, |
1500 | @@ -250,48 +247,52 @@ |
1501 | "album", m.album, |
1502 | "format", "json"); |
1503 | var session = new Soup.Session (); |
1504 | - var uri_request = session.request_uri (uri); |
1505 | - |
1506 | - /* send the HTTP request */ |
1507 | - var stream = uri_request.send (); |
1508 | - var parser = new Json.Parser (); |
1509 | - parser.load_from_stream (stream); |
1510 | - weak Json.Object parser_object = parser.get_root ().get_object (); |
1511 | - if (parser_object == null || parser_object.has_member ("album") == false) |
1512 | - return; |
1513 | - |
1514 | - weak Json.Object album_object = parser_object.get_member ("album").get_object (); |
1515 | - if (album_object.has_member ("image") && album_object.get_member ("image").get_node_type () == Json.NodeType.ARRAY) { |
1516 | - List<unowned Json.Node> image_values = album_object.get_array_member ("image").get_elements (); |
1517 | - string image_url = ""; |
1518 | - string image_size = ""; |
1519 | - foreach (unowned Json.Node element in image_values) { |
1520 | - weak Json.Object image_object = element.get_object (); |
1521 | - unowned string new_size = image_object.get_string_member ("size"); |
1522 | - if (new_size == "mega" || |
1523 | - (new_size == "extralarge" && image_size != "mega") || |
1524 | - (new_size == "large" && image_size != "mega" && image_size != "extralarge")) { |
1525 | - image_url = image_object.get_string_member ("#text").dup (); |
1526 | - image_size = new_size.dup (); |
1527 | - } |
1528 | - } |
1529 | - |
1530 | - var coverart_cache = Noise.CoverartCache.instance; |
1531 | - if (image_url != "" && coverart_cache.has_image (m) == false) { |
1532 | - |
1533 | - debug ("Caching last.fm image from URL: %s", image_url); |
1534 | - var image_file = File.new_for_uri (image_url); |
1535 | - coverart_cache.cache_image_from_file_async.begin (m, image_file); |
1536 | - } |
1537 | - } |
1538 | - |
1539 | - if (album_object.has_member ("releasedate") && m.year == 0) { |
1540 | - var releasedate = album_object.get_string_member ("releasedate"); |
1541 | - var date = Date (); |
1542 | - date.set_parse (releasedate); |
1543 | - if (date.valid ()) { |
1544 | - m.year = date.get_year (); |
1545 | - } |
1546 | + try { |
1547 | + var uri_request = session.request_uri (uri); |
1548 | + |
1549 | + /* send the HTTP request */ |
1550 | + var stream = yield uri_request.send_async (cancellable); |
1551 | + var parser = new Json.Parser (); |
1552 | + parser.load_from_stream (stream); |
1553 | + weak Json.Object parser_object = parser.get_root ().get_object (); |
1554 | + if (parser_object == null || parser_object.has_member ("album") == false) |
1555 | + return; |
1556 | + |
1557 | + weak Json.Object album_object = parser_object.get_member ("album").get_object (); |
1558 | + if (album_object.has_member ("image") && album_object.get_member ("image").get_node_type () == Json.NodeType.ARRAY) { |
1559 | + List<unowned Json.Node> image_values = album_object.get_array_member ("image").get_elements (); |
1560 | + string image_url = ""; |
1561 | + string image_size = ""; |
1562 | + foreach (unowned Json.Node element in image_values) { |
1563 | + weak Json.Object image_object = element.get_object (); |
1564 | + unowned string new_size = image_object.get_string_member ("size"); |
1565 | + if (new_size == "mega" || |
1566 | + (new_size == "extralarge" && image_size != "mega") || |
1567 | + (new_size == "large" && image_size != "mega" && image_size != "extralarge")) { |
1568 | + image_url = image_object.get_string_member ("#text").dup (); |
1569 | + image_size = new_size.dup (); |
1570 | + } |
1571 | + } |
1572 | + |
1573 | + var coverart_cache = Noise.CoverartCache.instance; |
1574 | + if (image_url != "" && coverart_cache.has_image (m) == false) { |
1575 | + |
1576 | + debug ("Caching last.fm image from URL: %s", image_url); |
1577 | + var image_file = File.new_for_uri (image_url); |
1578 | + coverart_cache.cache_image_from_file_async.begin (m, image_file); |
1579 | + } |
1580 | + } |
1581 | + |
1582 | + if (album_object.has_member ("releasedate") && m.year == 0) { |
1583 | + var releasedate = album_object.get_string_member ("releasedate"); |
1584 | + var date = Date (); |
1585 | + date.set_parse (releasedate); |
1586 | + if (date.valid ()) { |
1587 | + m.year = date.get_year (); |
1588 | + } |
1589 | + } |
1590 | + } catch (Error e) { |
1591 | + critical (e.message); |
1592 | } |
1593 | } |
1594 | |
1595 | |
1596 | === modified file 'plugins/LastFM/LastFM.vala' |
1597 | --- plugins/LastFM/LastFM.vala 2015-06-12 16:10:33 +0000 |
1598 | +++ plugins/LastFM/LastFM.vala 2015-08-27 10:21:27 +0000 |
1599 | @@ -86,7 +86,7 @@ |
1600 | var core = LastFM.Core.get_default (); |
1601 | core.initialize (client_id, client_secret, token); |
1602 | App.main_window.source_list_added.connect (source_list_added); |
1603 | - libraries_manager.local_library.add_playlist (core.get_similar_playlist ()); |
1604 | + libraries_manager.add_headless_playlist (core.get_similar_playlist ()); |
1605 | similar_media_widget = new Noise.SimilarMediasWidget (core); |
1606 | added_view = true; |
1607 | } catch (Error e) { |
1608 | |
1609 | === modified file 'plugins/LastFM/SimilarMedia.vala' |
1610 | --- plugins/LastFM/SimilarMedia.vala 2015-05-07 22:46:59 +0000 |
1611 | +++ plugins/LastFM/SimilarMedia.vala 2015-08-27 10:21:27 +0000 |
1612 | @@ -26,59 +26,52 @@ |
1613 | public class LastFM.SimilarMedias : Object { |
1614 | public static const int MAX_FETCHED = 20; |
1615 | |
1616 | - bool working; |
1617 | + public signal void similar_retrieved (Gee.LinkedList<int64?> similarIDs, Gee.LinkedList<Noise.Media> similarDont); |
1618 | |
1619 | public Noise.StaticPlaylist similar_playlist; |
1620 | - private Gee.LinkedList<Noise.Media> similar_medias; |
1621 | - |
1622 | - public signal void similar_retrieved (Gee.LinkedList<int> similarIDs, Gee.LinkedList<Noise.Media> similarDont); |
1623 | + private GLib.Cancellable cancellable; |
1624 | |
1625 | public class SimilarMedias () { |
1626 | - working = false; |
1627 | - similar_medias = new Gee.LinkedList<Noise.Media> (); |
1628 | + cancellable = new GLib.Cancellable (); |
1629 | similar_playlist = new Noise.StaticPlaylist (); |
1630 | similar_playlist.name = _("Similar"); |
1631 | similar_playlist.read_only = true; |
1632 | similar_playlist.show_badge = true; |
1633 | - try { |
1634 | - similar_playlist.icon = GLib.Icon.new_for_string ("playlist-similar"); |
1635 | - } catch (GLib.Error e) { |
1636 | - critical (e.message); |
1637 | - } |
1638 | - |
1639 | + similar_playlist.icon = new GLib.ThemedIcon ("playlist-similar"); |
1640 | + |
1641 | Noise.App.player.changing_player.connect ((m)=>{ |
1642 | - lock (similar_medias) { |
1643 | - similar_medias.clear (); |
1644 | - } |
1645 | lock (similar_playlist) { |
1646 | similar_playlist.clear (); |
1647 | } |
1648 | }); |
1649 | } |
1650 | - |
1651 | - public virtual void queryForSimilar (Noise.Media s) { |
1652 | - |
1653 | - if (!working) { |
1654 | - working = true; |
1655 | - |
1656 | - similar_async (s); |
1657 | + |
1658 | + public virtual void query_for_similar (Noise.Media s) { |
1659 | + if (cancellable.is_cancelled () == false) { |
1660 | + cancellable.cancel (); |
1661 | } |
1662 | + |
1663 | + similar_async.begin (s); |
1664 | } |
1665 | |
1666 | - public void similar_async (Noise.Media s) { |
1667 | + public async void similar_async (Noise.Media s) { |
1668 | debug ("In the similar thread"); |
1669 | - var similarIDs = new Gee.LinkedList<int> (); |
1670 | + cancellable.reset (); |
1671 | + var similar_medias = yield Core.get_default ().get_similar_tracks (s.title, s.artist, cancellable); |
1672 | + if (cancellable.is_cancelled ()) |
1673 | + return; |
1674 | + |
1675 | + var similarIDs = new Gee.LinkedList<int64?> (); |
1676 | var similarDont = new Gee.LinkedList<Noise.Media> (); |
1677 | - |
1678 | - similar_medias.add_all (Core.get_default ().getSimilarTracks (s.title, s.artist)); |
1679 | - lock (similar_medias) { |
1680 | - Noise.libraries_manager.local_library.media_from_name (similar_medias, similarIDs, similarDont); |
1681 | - } |
1682 | + Noise.libraries_manager.local_library.media_from_name (similar_medias, similarIDs, similarDont); |
1683 | + if (cancellable.is_cancelled ()) |
1684 | + return; |
1685 | + |
1686 | similarIDs.offer_head (s.rowid); |
1687 | - |
1688 | - similar_playlist.add_medias (Noise.libraries_manager.local_library.medias_from_ids (similarIDs)); |
1689 | + var found_medias = Noise.libraries_manager.local_library.medias_from_ids (similarIDs); |
1690 | + found_medias.remove (s); |
1691 | + similar_playlist.add_medias (found_medias); |
1692 | similar_retrieved (similarIDs, similarDont); |
1693 | - working = false; |
1694 | } |
1695 | |
1696 | } |
1697 | |
1698 | === modified file 'plugins/LastFM/SimilarMediaWidget.vala' |
1699 | --- plugins/LastFM/SimilarMediaWidget.vala 2015-05-07 22:46:59 +0000 |
1700 | +++ plugins/LastFM/SimilarMediaWidget.vala 2015-08-27 10:21:27 +0000 |
1701 | @@ -35,14 +35,12 @@ |
1702 | lfm.similar_retrieved.connect (similar_retrieved); |
1703 | |
1704 | App.main_window.update_media_info.connect ((m) => { |
1705 | - lfm.fetchCurrentSimilarSongs(); |
1706 | - lfm.fetch_album_info (m); |
1707 | + lfm.fetchCurrentSimilarSongs (); |
1708 | }); |
1709 | App.player.changing_player.connect ((m) => { |
1710 | similars_fetched = false; |
1711 | update_visibilities (); |
1712 | }); |
1713 | - NotificationManager.get_default ().search_cover.connect ((m) => { lfm.fetch_album_info (m);}); |
1714 | |
1715 | love_ban_buttons = new LoveBanButtons (); |
1716 | // put treeview inside scrolled window |
1717 | |
1718 | === modified file 'plugins/LastFM/noise-lastfm.application' |
1719 | --- plugins/LastFM/noise-lastfm.application 2015-05-07 22:46:59 +0000 |
1720 | +++ plugins/LastFM/noise-lastfm.application 2015-08-27 10:21:27 +0000 |
1721 | @@ -3,6 +3,11 @@ |
1722 | <description>Music</description> |
1723 | <desktop-entry>noise.desktop</desktop-entry> |
1724 | <translations>noise</translations> |
1725 | + <services> |
1726 | + <service id="lastfm-scrobble"> |
1727 | + <description>Scrobble all your music</description> |
1728 | + </service> |
1729 | + </services> |
1730 | <service-types> |
1731 | <service-type id="scrobbling"> |
1732 | </service-type> |
1733 | |
1734 | === modified file 'plugins/MPRIS/MPRIS.vala' |
1735 | --- plugins/MPRIS/MPRIS.vala 2015-05-24 21:40:48 +0000 |
1736 | +++ plugins/MPRIS/MPRIS.vala 2015-08-27 10:21:27 +0000 |
1737 | @@ -232,7 +232,7 @@ |
1738 | } |
1739 | |
1740 | private ObjectPath get_track_id (Noise.Media m) { |
1741 | - return new ObjectPath ("/org/pantheon/noise/Track/%d".printf (m.rowid)); |
1742 | + return new ObjectPath ("/org/pantheon/noise/Track/%lld".printf (m.rowid)); |
1743 | } |
1744 | |
1745 | private bool send_property_change() { |
1746 | |
1747 | === removed directory 'plugins/Zeitgeist' |
1748 | === removed file 'plugins/Zeitgeist/CMakeLists.txt' |
1749 | --- plugins/Zeitgeist/CMakeLists.txt 2014-06-28 19:50:12 +0000 |
1750 | +++ plugins/Zeitgeist/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1751 | @@ -1,34 +0,0 @@ |
1752 | -pkg_check_modules(ZEITGEIST_DEPS zeitgeist-2.0) |
1753 | - |
1754 | -if (ZEITGEIST_DEPS_FOUND) |
1755 | - |
1756 | -set(DEPS_CFLAGS ${DEPS_CFLAGS} ${ZEITGEIST_DEPS_CFLAGS}) |
1757 | -set(DEPS_LIBRARIES ${DEPS_LIBRARIES} ${ZEITGEIST_DEPS_LIBRARIES}) |
1758 | -set(DEPS_LIBRARY_DIRS ${DEPS_LIBRARY_DIRS} ${ZEITGEIST_DEPS_LIBRARY_DIRS}) |
1759 | - |
1760 | -add_definitions(${DEPS_CFLAGS}) |
1761 | -link_directories(${DEPS_LIBRARY_DIRS}) |
1762 | - |
1763 | -set(TARGET_NAME zeitgeist) |
1764 | -vala_precompile(ZEITGEIST_VALA_C ${TARGET_NAME} |
1765 | - Zeitgeist.vala |
1766 | -PACKAGES |
1767 | - ${DEPS_PACKAGES} |
1768 | - zeitgeist-2.0 |
1769 | -OPTIONS |
1770 | - ${GLOBAL_VALAC_OPTIONS} |
1771 | -) |
1772 | - |
1773 | -add_library(${TARGET_NAME} MODULE ${ZEITGEIST_VALA_C}) |
1774 | - |
1775 | -target_link_libraries(${TARGET_NAME} ${DEPS_LIBRARIES}) |
1776 | -add_dependencies(${TARGET_NAME} ${SRC_TARGET}) |
1777 | - |
1778 | -install(TARGETS ${TARGET_NAME} DESTINATION ${PLUGIN_DIR}/Zeitgeist/) |
1779 | -install(FILES zeitgeist.plugin DESTINATION ${PLUGIN_DIR}/Zeitgeist/) |
1780 | - |
1781 | -else () |
1782 | - |
1783 | -message("-- Zeitgeist plugin disabled") |
1784 | - |
1785 | -endif () |
1786 | \ No newline at end of file |
1787 | |
1788 | === removed file 'plugins/Zeitgeist/Zeitgeist.vala' |
1789 | --- plugins/Zeitgeist/Zeitgeist.vala 2014-07-22 02:49:15 +0000 |
1790 | +++ plugins/Zeitgeist/Zeitgeist.vala 1970-01-01 00:00:00 +0000 |
1791 | @@ -1,88 +0,0 @@ |
1792 | - |
1793 | -namespace Noise.Plugins { |
1794 | - |
1795 | - public class ZeitgeistPlugin : Peas.ExtensionBase, Peas.Activatable { |
1796 | - |
1797 | - public Object object { owned get; construct; } |
1798 | - |
1799 | - Zeitgeist.Log zeitgeist; |
1800 | - PlaybackManager player; |
1801 | - |
1802 | - Media? current_song = null; |
1803 | - |
1804 | - bool connected = false; |
1805 | - |
1806 | - public void activate () { |
1807 | - message ("Activating Zeitgeist plugin"); |
1808 | - |
1809 | - zeitgeist = Zeitgeist.Log.get_default (); |
1810 | - |
1811 | - Value value = Value (typeof (Object)); |
1812 | - get_property ("object", ref value); |
1813 | - var plugins = (Noise.Plugins.Interface) value.get_object(); |
1814 | - |
1815 | - plugins.register_function (Interface.Hook.WINDOW, () => { |
1816 | - connected = true; |
1817 | - |
1818 | - player = Noise.App.player; |
1819 | - player.media_played.connect (media_changed); |
1820 | - }); |
1821 | - } |
1822 | - |
1823 | - public void deactivate () { |
1824 | - if (connected) |
1825 | - player.media_played.disconnect (media_changed); |
1826 | - |
1827 | - connected = false; |
1828 | - } |
1829 | - |
1830 | - void media_changed (Media played_media) { |
1831 | - if (current_song != null) |
1832 | - log_interaction.begin (current_song, Zeitgeist.ZG.LEAVE_EVENT); |
1833 | - |
1834 | - log_interaction.begin (played_media, Zeitgeist.ZG.ACCESS_EVENT); |
1835 | - current_song = played_media; |
1836 | - } |
1837 | - |
1838 | - async void log_interaction (Media song, string interpretation) { |
1839 | - var time = new DateTime.now_local ().to_unix () * 1000; |
1840 | - |
1841 | - FileInfo? info = null; |
1842 | - try { |
1843 | - info = yield song.file.query_info_async (FileAttribute.STANDARD_CONTENT_TYPE, 0); |
1844 | - } catch (Error e) {} |
1845 | - |
1846 | - var subject = new Zeitgeist.Subject (); |
1847 | - subject.uri = song.uri; |
1848 | - subject.interpretation = Zeitgeist.NFO.AUDIO; |
1849 | - subject.manifestation = Zeitgeist.NFO.FILE_DATA_OBJECT; |
1850 | - subject.origin = song.get_display_location (); |
1851 | - subject.mimetype = info != null ? info.get_content_type () : null; |
1852 | - subject.text = "%s - %s - %s".printf (song.get_display_title (), |
1853 | - song.get_display_artist (), song.get_display_album ()); |
1854 | - |
1855 | - var event = new Zeitgeist.Event (); |
1856 | - event.timestamp = time; |
1857 | - event.interpretation = interpretation; |
1858 | - event.manifestation = Zeitgeist.ZG.USER_ACTIVITY; |
1859 | - event.actor = "application://noise.desktop"; |
1860 | - event.add_subject (subject); |
1861 | - |
1862 | - try { |
1863 | - zeitgeist.insert_event_no_reply (event); |
1864 | - } catch (Error e) { |
1865 | - warning ("Logging to zeitgeist failed: %s", e.message); |
1866 | - } |
1867 | - } |
1868 | - |
1869 | - public void update_state () { |
1870 | - } |
1871 | - } |
1872 | -} |
1873 | - |
1874 | -[ModuleInit] |
1875 | -public void peas_register_types (TypeModule module) { |
1876 | - var objmodule = module as Peas.ObjectModule; |
1877 | - objmodule.register_extension_type (typeof (Peas.Activatable), |
1878 | - typeof (Noise.Plugins.ZeitgeistPlugin)); |
1879 | -} |
1880 | |
1881 | === removed file 'plugins/Zeitgeist/zeitgeist.plugin' |
1882 | --- plugins/Zeitgeist/zeitgeist.plugin 2014-06-16 14:04:06 +0000 |
1883 | +++ plugins/Zeitgeist/zeitgeist.plugin 1970-01-01 00:00:00 +0000 |
1884 | @@ -1,9 +0,0 @@ |
1885 | -[Plugin] |
1886 | -Module=zeitgeist |
1887 | -IAge=2 |
1888 | -Name=Log to Zeitgeist |
1889 | -Description=Log the played songs to Zeitgeist |
1890 | -Authors=Noise Developers |
1891 | -Copyright=Copyright © 2014 Noise Developers |
1892 | -Website=http://launchpad.net/noise |
1893 | - |
1894 | |
1895 | === modified file 'schemas/org.pantheon.noise.gschema.xml' |
1896 | --- schemas/org.pantheon.noise.gschema.xml 2014-11-27 19:22:08 +0000 |
1897 | +++ schemas/org.pantheon.noise.gschema.xml 2015-08-27 10:21:27 +0000 |
1898 | @@ -51,12 +51,12 @@ |
1899 | <summary>List of desktop shells for which the player's window will be minimized instead of hidden when the close-while-playing option is set to false.</summary> |
1900 | <description>For the Pantheon and GNOME desktop shells, the player's window is simply minimized due to the lack of a minimize button; the window is hidden for all the rest of desktop shells, unless they are added to this key. In fact, any dock-based shell should be part of this key, except those that lack a sound menu or in which the dock space is often limited (e.g. Unity). See the description of close-while-playing for more information.</description> |
1901 | </key> |
1902 | - <key type="i" name="last-playlist-playing"> |
1903 | - <default>-1</default> |
1904 | - <summary>ID of last playlist playing</summary> |
1905 | - <description>ID of last playlist playing</description> |
1906 | + <key type="s" name="last-playlist-playing"> |
1907 | + <default>''</default> |
1908 | + <summary>'s' for smart playlist or 'p' for static playlist + ID of last playlist playing</summary> |
1909 | + <description>'s' for smart playlist or 'p' for static playlist + ID of last playlist playing</description> |
1910 | </key> |
1911 | - <key type="i" name="last-media-playing"> |
1912 | + <key type="x" name="last-media-playing"> |
1913 | <default>0</default> |
1914 | <summary>ID of last media playing</summary> |
1915 | <description>ID of last media playing</description> |
1916 | |
1917 | === modified file 'src/CMakeLists.txt' |
1918 | --- src/CMakeLists.txt 2015-06-12 16:10:33 +0000 |
1919 | +++ src/CMakeLists.txt 2015-08-27 10:21:27 +0000 |
1920 | @@ -8,8 +8,12 @@ |
1921 | Objects/MediaArtCache.vala |
1922 | Objects/CoverartCache.vala |
1923 | Objects/MediaKeyListener.vala |
1924 | + Objects/HistoryPlaylist.vala |
1925 | LocalBackend/LocalLibrary.vala |
1926 | LocalBackend/LocalMedia.vala |
1927 | + LocalBackend/LocalSmartPlaylist.vala |
1928 | + LocalBackend/LocalStaticPlaylist.vala |
1929 | + LocalBackend/DevicePreferences.vala |
1930 | Widgets/NavigationArrows.vala |
1931 | Widgets/TopDisplay.vala |
1932 | Widgets/InfoPanel.vala |
1933 | @@ -30,9 +34,7 @@ |
1934 | Widgets/FastView/FastGridModel.vala |
1935 | Widgets/FastView/FastList.vala |
1936 | Widgets/FastView/FastListModel.vala |
1937 | - DataBase/DataBaseManager.vala |
1938 | - DataBase/DataBaseUpdater.vala |
1939 | - DataBase/Tables.vala |
1940 | + DataBase.vala |
1941 | GStreamer/GStreamerTagger.vala |
1942 | GStreamer/Streamer.vala |
1943 | GStreamer/CoverImport.vala |
1944 | |
1945 | === removed directory 'src/DataBase' |
1946 | === renamed file 'src/DataBase/Tables.vala' => 'src/DataBase.vala' |
1947 | --- src/DataBase/Tables.vala 2015-02-24 00:04:03 +0000 |
1948 | +++ src/DataBase.vala 2015-08-27 10:21:27 +0000 |
1949 | @@ -1,6 +1,6 @@ |
1950 | // -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
1951 | /*- |
1952 | - * Copyright (c) 2012 Noise Developers (http://launchpad.net/noise) |
1953 | + * Copyright (c) 2012-2015 Noise Developers (https://launchpad.net/noise) |
1954 | * |
1955 | * This library is free software; you can redistribute it and/or |
1956 | * modify it under the terms of the GNU Library General Public |
1957 | @@ -26,38 +26,270 @@ |
1958 | * statement from your version. |
1959 | */ |
1960 | |
1961 | -namespace Noise.Database.Tables { |
1962 | - |
1963 | -public const string PLAYLISTS = """ |
1964 | -CREATE TABLE IF NOT EXISTS playlists (`name` TEXT, `media` TEXT, |
1965 | -`sort_column_id` INT, `sort_direction` TEXT, `columns` TEXT) |
1966 | -"""; |
1967 | - |
1968 | -public const string SMART_PLAYLISTS = """ |
1969 | -CREATE TABLE IF NOT EXISTS smart_playlists (`name` TEXT, `and_or` INT, `queries` TEXT, |
1970 | -`limit` INT, `limit_amount` INT) |
1971 | -"""; |
1972 | - |
1973 | -public const string COLUMNS = """ |
1974 | -CREATE TABLE IF NOT EXISTS columns (`is_smart` INT, `name` TEXT, `sort_column_id` INT, `sort_direction` TEXT, |
1975 | -`columns` TEXT) |
1976 | -"""; |
1977 | - |
1978 | -public const string MEDIA = """ |
1979 | -CREATE TABLE IF NOT EXISTS media (`uri` TEXT, `file_size` INT, `title` TEXT, |
1980 | -`artist` TEXT, `composer` TEXT, `album_artist` TEXT, `album` TEXT, |
1981 | -`grouping` TEXT, `genre` TEXT,`comment` TEXT, `lyrics` TEXT, `has_embedded` INT, |
1982 | -`year` INT, `track` INT, `track_count` INT, `album_number` INT, |
1983 | -`album_count` INT, `bitrate` INT, `length` INT, `samplerate` INT, `rating` INT, |
1984 | -`playcount` INT, `skipcount` INT, `dateadded` INT, `lastplayed` INT, |
1985 | -`lastmodified` INT, `rowid` INTEGER PRIMARY KEY AUTOINCREMENT) |
1986 | -"""; |
1987 | - |
1988 | -public const string DEVICES = """ |
1989 | -CREATE TABLE IF NOT EXISTS devices (`unique_id` TEXT, `sync_when_mounted` INT, |
1990 | -`sync_music` INT, `sync_podcasts` INT, `sync_audiobooks` INT, `sync_all_music` INT, |
1991 | -`sync_all_podcasts` INT, `sync_all_audiobooks` INT, `music_playlist` STRING, |
1992 | -`podcast_playlist` STRING, `audiobook_playlist` STRING, `last_sync_time` INT) |
1993 | -"""; |
1994 | - |
1995 | +namespace Noise.Database { |
1996 | + namespace Tables { |
1997 | + public const string PLAYLISTS = """CREATE TABLE IF NOT EXISTS playlists (name TEXT, media TEXT, |
1998 | + sort_column_id INT, sort_direction TEXT, columns TEXT, rowid INTEGER PRIMARY KEY AUTOINCREMENT)"""; |
1999 | + |
2000 | + public const string SMART_PLAYLISTS = """CREATE TABLE IF NOT EXISTS smart_playlists (name TEXT, |
2001 | + and_or INT, queries TEXT, limited INT, limit_amount INT, rowid INTEGER PRIMARY KEY AUTOINCREMENT)"""; |
2002 | + |
2003 | + public const string COLUMNS = """CREATE TABLE IF NOT EXISTS columns (unique_id TEXT, sort_column_id INT, |
2004 | + sort_direction INT, columns TEXT)"""; |
2005 | + |
2006 | + public const string MEDIA = """CREATE TABLE IF NOT EXISTS media (uri TEXT, file_size INT, |
2007 | + title TEXT, artist TEXT, composer TEXT, album_artist TEXT, album TEXT, |
2008 | + grouping TEXT, genre TEXT, comment TEXT, lyrics TEXT, has_embedded INT, |
2009 | + year INT, track INT, track_count INT, album_number INT, |
2010 | + album_count INT, bitrate INT, length INT, samplerate INT, rating INT, |
2011 | + playcount INT, skipcount INT, dateadded INT, lastplayed INT, |
2012 | + lastmodified INT, rowid INTEGER PRIMARY KEY AUTOINCREMENT)"""; |
2013 | + |
2014 | + public const string DEVICES = """CREATE TABLE IF NOT EXISTS devices (unique_id TEXT, |
2015 | + sync_when_mounted INT, sync_music INT, sync_all_music INT, music_playlist STRING, |
2016 | + last_sync_time INT)"""; |
2017 | + } |
2018 | + |
2019 | + /* |
2020 | + * NOTE: |
2021 | + * Update those constants when you change the order of columns. |
2022 | + */ |
2023 | + namespace Playlists { |
2024 | + public static const string TABLE_NAME = "playlists"; |
2025 | + public static const string NAME = "+0"; |
2026 | + public static const string MEDIA = "+1"; |
2027 | + public static const string SORT_COLUMN_ID = "+2"; |
2028 | + public static const string SORT_DIRECTION = "+3"; |
2029 | + public static const string COLUMNS = "+4"; |
2030 | + public static const string ROWID = "+5"; |
2031 | + } |
2032 | + |
2033 | + namespace SmartPlaylists { |
2034 | + public static const string TABLE_NAME = "smart_playlists"; |
2035 | + public static const string NAME = "+0"; |
2036 | + public static const string AND_OR = "+1"; |
2037 | + public static const string QUERIES = "+2"; |
2038 | + public static const string LIMITED = "+3"; |
2039 | + public static const string LIMIT_AMOUNT = "+4"; |
2040 | + public static const string ROWID = "+5"; |
2041 | + } |
2042 | + |
2043 | + namespace Media { |
2044 | + public static const string TABLE_NAME = "media"; |
2045 | + public static const string URI = "+0"; |
2046 | + public static const string FILE_SIZE = "+1"; |
2047 | + public static const string TITLE = "+2"; |
2048 | + public static const string ARTIST = "+3"; |
2049 | + public static const string COMPOSER = "+4"; |
2050 | + public static const string ALBUM_ARTIST = "+5"; |
2051 | + public static const string ALBUM = "+6"; |
2052 | + public static const string GROUPING = "+7"; |
2053 | + public static const string GENRE = "+8"; |
2054 | + public static const string COMMENT = "+9"; |
2055 | + public static const string LYRICS = "+10"; |
2056 | + public static const string HAS_EMBEDDED = "+11"; |
2057 | + public static const string YEAR = "+12"; |
2058 | + public static const string TRACK = "+13"; |
2059 | + public static const string TRACK_COUNT = "+14"; |
2060 | + public static const string ALBUM_NUMBER = "+15"; |
2061 | + public static const string ALBUM_COUNT = "+16"; |
2062 | + public static const string BITRATE = "+17"; |
2063 | + public static const string LENGTH = "+18"; |
2064 | + public static const string SAMPLERATE = "+19"; |
2065 | + public static const string RATING = "+20"; |
2066 | + public static const string PLAYCOUNT = "+21"; |
2067 | + public static const string SKIPCOUNT = "+22"; |
2068 | + public static const string DATEADDED = "+23"; |
2069 | + public static const string LASTPLAYED = "+24"; |
2070 | + public static const string LASTMODIFIED = "+25"; |
2071 | + public static const string ROWID = "+26"; |
2072 | + } |
2073 | + |
2074 | + namespace Devices { |
2075 | + public static const string TABLE_NAME = "devices"; |
2076 | + public static const string UNIQUE_ID = "+0"; |
2077 | + public static const string SYNC_WHEN_MOUNTED = "+1"; |
2078 | + public static const string SYNC_MUSIC = "+2"; |
2079 | + public static const string SYNC_ALL_MUSIC = "+3"; |
2080 | + public static const string MUSIC_PLAYLIST = "+4"; |
2081 | + public static const string LAST_SYNC_TIME = "+5"; |
2082 | + } |
2083 | + |
2084 | + namespace Columns { |
2085 | + public static const string TABLE_NAME = "columns"; |
2086 | + public static const string UNIQUE_ID = "+0"; |
2087 | + public static const string SORT_COLUMN_ID = "+1"; |
2088 | + public static const string SORT_DIRECTION = "+2"; |
2089 | + public static const string COLUMNS = "+3"; |
2090 | + } |
2091 | + |
2092 | + /* |
2093 | + * Helper functions. |
2094 | + */ |
2095 | + public static Value make_string_value (string str) { |
2096 | + var val = Value (typeof(string)); |
2097 | + val.set_string (str); |
2098 | + return val; |
2099 | + } |
2100 | + |
2101 | + public static Value make_bool_value (bool bl) { |
2102 | + var val = Value (typeof(bool)); |
2103 | + val.set_boolean (bl); |
2104 | + return val; |
2105 | + } |
2106 | + |
2107 | + public static Value make_uint_value (uint u) { |
2108 | + var val = Value (typeof(uint)); |
2109 | + val.set_uint (u); |
2110 | + return val; |
2111 | + } |
2112 | + |
2113 | + public static Value make_int_value (int u) { |
2114 | + var val = Value (typeof(int)); |
2115 | + val.set_int (u); |
2116 | + return val; |
2117 | + } |
2118 | + |
2119 | + public static Value make_int64_value (int64 u) { |
2120 | + var val = Value (typeof(int64)); |
2121 | + val.set_int64 (u); |
2122 | + return val; |
2123 | + } |
2124 | + |
2125 | + public static Value make_uint64_value (uint64 u) { |
2126 | + var val = Value (typeof(uint64)); |
2127 | + val.set_uint64 (u); |
2128 | + return val; |
2129 | + } |
2130 | + |
2131 | + public static GLib.Value? query_field (int64 rowid, Gda.Connection connection, string table, string field) { |
2132 | + try { |
2133 | + var sql = new Gda.SqlBuilder (Gda.SqlStatementType.SELECT); |
2134 | + sql.select_add_target (table, null); |
2135 | + sql.add_field_value_id (sql.add_id (field), 0); |
2136 | + var id_field = sql.add_id ("rowid"); |
2137 | + var id_param = sql.add_expr_value (null, Database.make_int64_value (rowid)); |
2138 | + var id_cond = sql.add_cond (Gda.SqlOperatorType.EQ, id_field, id_param, 0); |
2139 | + sql.set_where (id_cond); |
2140 | + var data_model = connection.statement_execute_select (sql.get_statement (), null); |
2141 | + return data_model.get_value_at (data_model.get_column_index (field), 0); |
2142 | + } catch (Error e) { |
2143 | + critical ("Could not query field %s: %s", field, e.message); |
2144 | + return null; |
2145 | + } |
2146 | + } |
2147 | + |
2148 | + public static void set_field (int64 rowid, Gda.Connection connection, string table, string field, GLib.Value value) { |
2149 | + try { |
2150 | + var rowid_value = GLib.Value (typeof (int64)); |
2151 | + rowid_value.set_int64 (rowid); |
2152 | + var col_names = new GLib.SList<string> (); |
2153 | + col_names.append (field); |
2154 | + var values = new GLib.SList<GLib.Value?> (); |
2155 | + values.append (value); |
2156 | + connection.update_row_in_table_v (table, "rowid", rowid_value, col_names, values); |
2157 | + } catch (Error e) { |
2158 | + critical ("Could not set field %s: %s", field, e.message); |
2159 | + } |
2160 | + } |
2161 | + |
2162 | + public static Gda.SqlBuilderId process_smart_query (Gda.SqlBuilder builder, SmartQuery sq) { |
2163 | + Value value = Value (sq.value.type ()); |
2164 | + sq.value.copy (ref value); |
2165 | + string field; |
2166 | + switch (sq.field) { |
2167 | + case SmartQuery.FieldType.ALBUM: |
2168 | + field = "album"; |
2169 | + break; |
2170 | + case SmartQuery.FieldType.ARTIST: |
2171 | + field = "artist"; |
2172 | + break; |
2173 | + case SmartQuery.FieldType.BITRATE: |
2174 | + field = "bitrate"; |
2175 | + break; |
2176 | + case SmartQuery.FieldType.COMMENT: |
2177 | + field = "comment"; |
2178 | + break; |
2179 | + case SmartQuery.FieldType.COMPOSER: |
2180 | + field = "composer"; |
2181 | + break; |
2182 | + case SmartQuery.FieldType.DATE_ADDED: |
2183 | + // We need the current timestamp because this field is relative. |
2184 | + value = Value (typeof (int)); |
2185 | + value.set_int ((int)time_t ()); |
2186 | + field = "dateadded"; |
2187 | + break; |
2188 | + case SmartQuery.FieldType.GENRE: |
2189 | + field = "genre"; |
2190 | + break; |
2191 | + case SmartQuery.FieldType.GROUPING: |
2192 | + field = "grouping"; |
2193 | + break; |
2194 | + case SmartQuery.FieldType.LAST_PLAYED: |
2195 | + // We need the current timestamp because this field is relative. |
2196 | + value = Value (typeof (int)); |
2197 | + value.set_int ((int)time_t ()); |
2198 | + field = "lastplayed"; |
2199 | + break; |
2200 | + case SmartQuery.FieldType.LENGTH: |
2201 | + field = "length"; |
2202 | + break; |
2203 | + case SmartQuery.FieldType.PLAYCOUNT: |
2204 | + field = "playcount"; |
2205 | + break; |
2206 | + case SmartQuery.FieldType.RATING: |
2207 | + field = "rating"; |
2208 | + break; |
2209 | + case SmartQuery.FieldType.SKIPCOUNT: |
2210 | + field = "skipcount"; |
2211 | + break; |
2212 | + case SmartQuery.FieldType.YEAR: |
2213 | + field = "year"; |
2214 | + break; |
2215 | + case SmartQuery.FieldType.TITLE: |
2216 | + default: |
2217 | + field = "title"; |
2218 | + break; |
2219 | + } |
2220 | + |
2221 | + Gda.SqlOperatorType sql_operator_type; |
2222 | + switch (sq.comparator) { |
2223 | + case SmartQuery.ComparatorType.IS_NOT: |
2224 | + sql_operator_type = Gda.SqlOperatorType.NOT; |
2225 | + break; |
2226 | + case SmartQuery.ComparatorType.CONTAINS: |
2227 | + case SmartQuery.ComparatorType.NOT_CONTAINS: |
2228 | + value = make_string_value ("%" + value.get_string () + "%"); |
2229 | + sql_operator_type = Gda.SqlOperatorType.LIKE; |
2230 | + break; |
2231 | + case SmartQuery.ComparatorType.IS_EXACTLY: |
2232 | + sql_operator_type = Gda.SqlOperatorType.EQ; |
2233 | + break; |
2234 | + case SmartQuery.ComparatorType.IS_AT_MOST: |
2235 | + sql_operator_type = Gda.SqlOperatorType.LEQ; |
2236 | + break; |
2237 | + case SmartQuery.ComparatorType.IS_AT_LEAST: |
2238 | + sql_operator_type = Gda.SqlOperatorType.GEQ; |
2239 | + break; |
2240 | + case SmartQuery.ComparatorType.IS_WITHIN: |
2241 | + sql_operator_type = Gda.SqlOperatorType.LEQ; |
2242 | + break; |
2243 | + case SmartQuery.ComparatorType.IS_BEFORE: |
2244 | + sql_operator_type = Gda.SqlOperatorType.GEQ; |
2245 | + break; |
2246 | + case SmartQuery.ComparatorType.IS: |
2247 | + default: |
2248 | + sql_operator_type = Gda.SqlOperatorType.LIKE; |
2249 | + break; |
2250 | + } |
2251 | + |
2252 | + var id_field = builder.add_id (field); |
2253 | + var id_value = builder.add_expr_value (null, value); |
2254 | + if (sq.comparator == SmartQuery.ComparatorType.NOT_CONTAINS) { |
2255 | + var cond = builder.add_cond (sql_operator_type, id_field, id_value, 0);; |
2256 | + return builder.add_cond (Gda.SqlOperatorType.NOT, cond, 0, 0); |
2257 | + } else { |
2258 | + return builder.add_cond (sql_operator_type, id_field, id_value, 0); |
2259 | + } |
2260 | + } |
2261 | } |
2262 | |
2263 | === removed file 'src/DataBase/DataBaseManager.vala' |
2264 | --- src/DataBase/DataBaseManager.vala 2015-02-26 17:15:44 +0000 |
2265 | +++ src/DataBase/DataBaseManager.vala 1970-01-01 00:00:00 +0000 |
2266 | @@ -1,937 +0,0 @@ |
2267 | -/* |
2268 | - * Copyright (c) 2012 Noise Developers |
2269 | - * |
2270 | - * This library is free software; you can redistribute it and/or |
2271 | - * modify it under the terms of the GNU General Public License as |
2272 | - * published by the Free Software Foundation; either version 2 of the |
2273 | - * License, or (at your option) any later version. |
2274 | - * |
2275 | - * This is distributed in the hope that it will be useful, |
2276 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2277 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2278 | - * Lesser General Public License for more details. |
2279 | - * |
2280 | - * You should have received a copy of the GNU Lesser General Public |
2281 | - * License along with this program; see the file COPYING. If not, |
2282 | - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
2283 | - * Boston, MA 02111-1307, USA. |
2284 | - * |
2285 | - * Authored by: Scott Ringwelski <sgringwe@mtu.edu>, |
2286 | - * Victor Eduardo <victoreduardm@gmail.com> |
2287 | - */ |
2288 | - |
2289 | -using SQLHeavy; |
2290 | - |
2291 | -public class Noise.DataBaseManager : GLib.Object { |
2292 | - public SQLHeavy.Database database; |
2293 | - private Transaction transaction; // the current sql transaction |
2294 | - |
2295 | - private int index = 0; |
2296 | - private int item_count = 0; |
2297 | - |
2298 | - private static DataBaseManager? dbm = null; |
2299 | - |
2300 | - public static DataBaseManager get_default () { |
2301 | - if (dbm == null) |
2302 | - dbm = new DataBaseManager (); |
2303 | - return dbm; |
2304 | - } |
2305 | - |
2306 | - /** Creates a new DatabaseManager **/ |
2307 | - private DataBaseManager () { |
2308 | - init_database (); |
2309 | - } |
2310 | - |
2311 | - /** Creates/Reads the database file and folder **/ |
2312 | - private void init_database () { |
2313 | - assert (database == null); |
2314 | - |
2315 | - var database_dir = FileUtils.get_data_directory (); |
2316 | - |
2317 | - try { |
2318 | - database_dir.make_directory_with_parents (null); |
2319 | - } |
2320 | - catch (GLib.Error err) { |
2321 | - if (!(err is IOError.EXISTS)) |
2322 | - error ("Could not create data directory: %s", err.message); |
2323 | - } |
2324 | - |
2325 | - string database_path = Path.build_filename (database_dir.get_path (), "database_0_3_0.db"); |
2326 | - var database_file = File.new_for_path (database_path); |
2327 | - |
2328 | - bool new_db = !database_file.query_exists (); |
2329 | - |
2330 | - try { |
2331 | - const SQLHeavy.FileMode flags = SQLHeavy.FileMode.READ |
2332 | - | SQLHeavy.FileMode.WRITE |
2333 | - | SQLHeavy.FileMode.CREATE; |
2334 | - database = new SQLHeavy.Database (database_file.get_path (), flags); |
2335 | - } |
2336 | - catch (SQLHeavy.Error err) { |
2337 | - error ("Could not read/create database file: %s", err.message); |
2338 | - } |
2339 | - |
2340 | - // Disable synchronized commits for performance reasons |
2341 | - database.synchronous = SQLHeavy.SynchronousMode.OFF; |
2342 | - |
2343 | - load_table (Database.Tables.PLAYLISTS); |
2344 | - load_table (Database.Tables.SMART_PLAYLISTS); |
2345 | - load_table (Database.Tables.COLUMNS); |
2346 | - load_table (Database.Tables.MEDIA); |
2347 | - load_table (Database.Tables.DEVICES); |
2348 | - |
2349 | - if (new_db) |
2350 | - add_default_smart_playlists (); |
2351 | - } |
2352 | - |
2353 | - private void load_table (string table) { |
2354 | - try { |
2355 | - database.execute (table); |
2356 | - } |
2357 | - catch (SQLHeavy.Error err) { |
2358 | - warning ("Error while executing %s: %s", table, err.message); |
2359 | - } |
2360 | - } |
2361 | - |
2362 | - public void resetProgress (int items) { |
2363 | - index = 0; |
2364 | - item_count = items; |
2365 | - } |
2366 | - |
2367 | - /** |
2368 | - * Loads media from db |
2369 | - */ |
2370 | - public Gee.TreeSet<LocalMedia> load_media () { |
2371 | - assert (database != null); |
2372 | - var rv = new Gee.TreeSet<LocalMedia>(); |
2373 | - |
2374 | - try { |
2375 | - Query query = new Query (database, "SELECT `rowid` FROM `media`"); |
2376 | - for (var results = query.execute (); !results.finished; results.next()) { |
2377 | - var m = new LocalMedia (results.fetch_int ()); |
2378 | - rv.add (m); |
2379 | - } |
2380 | - } |
2381 | - catch (SQLHeavy.Error err) { |
2382 | - warning ("Could not load media from db: %s\n", err.message); |
2383 | - } |
2384 | - |
2385 | - return rv; |
2386 | - } |
2387 | - |
2388 | - public void clear_media () { |
2389 | - assert (database != null); |
2390 | - try { |
2391 | - database.execute ("DELETE FROM `media`"); |
2392 | - } |
2393 | - catch(SQLHeavy.Error err) { |
2394 | - warning ("Could not clear media: %s \n", err.message); |
2395 | - } |
2396 | - } |
2397 | - |
2398 | - public Gee.TreeSet<LocalMedia> add_media (Gee.Collection<Media> media) { |
2399 | - assert (database != null); |
2400 | - var tree_set = new Gee.TreeSet<LocalMedia> (); |
2401 | - try { |
2402 | - Query query = new Query (database, """INSERT INTO `media` (`uri`, `file_size`, `title`, `artist`, `composer`, `album_artist`, |
2403 | -`album`, `grouping`, `genre`, `comment`, `lyrics`, `has_embedded`, `year`, `track`, `track_count`, `album_number`, `album_count`, |
2404 | -`bitrate`, `length`, `samplerate`, `rating`, `playcount`, `skipcount`, `dateadded`, `lastplayed`, `lastmodified`) |
2405 | -VALUES (:uri, :file_size, :title, :artist, :composer, :album_artist, :album, :grouping, |
2406 | -:genre, :comment, :lyrics, :has_embedded, :year, :track, :track_count, :album_number, :album_count, :bitrate, :length, :samplerate, |
2407 | -:rating, :playcount, :skipcount, :dateadded, :lastplayed, :lastmodified);"""); |
2408 | - |
2409 | - foreach (var s in media) { |
2410 | - if (!s.isTemporary) { |
2411 | - query.set_string(":uri", s.uri); |
2412 | - query.set_int(":file_size", (int)s.file_size); |
2413 | - query.set_string(":title", s.title); |
2414 | - query.set_string(":artist", s.artist); |
2415 | - query.set_string(":composer", s.composer); |
2416 | - query.set_string(":album_artist", s.album_artist); |
2417 | - query.set_string(":album", s.album); |
2418 | - query.set_string(":grouping", s.grouping); |
2419 | - query.set_string(":genre", s.genre); |
2420 | - query.set_string(":comment", s.comment); |
2421 | - query.set_string(":lyrics", s.lyrics); |
2422 | - query.set_int(":has_embedded", s.has_embedded ? 1 : 0); |
2423 | - query.set_int(":year", (int)s.year); |
2424 | - query.set_int(":track", (int)s.track); |
2425 | - query.set_int(":track_count", (int)s.track_count); |
2426 | - query.set_int(":album_number", (int)s.album_number); |
2427 | - query.set_int(":album_count", (int)s.album_count); |
2428 | - query.set_int(":bitrate", (int)s.bitrate); |
2429 | - query.set_int(":length", (int)s.length); |
2430 | - query.set_int(":samplerate", (int)s.samplerate); |
2431 | - query.set_int(":rating", (int)s.rating); |
2432 | - query.set_int(":playcount", (int)s.play_count); |
2433 | - query.set_int(":skipcount", (int)s.skip_count); |
2434 | - query.set_int(":dateadded", (int)s.date_added); |
2435 | - query.set_int(":lastplayed", (int)s.last_played); |
2436 | - query.set_int(":lastmodified", (int)s.last_modified); |
2437 | - query.execute (); |
2438 | - var local_media = new LocalMedia ((int)database.last_insert_id); |
2439 | - tree_set.add (local_media); |
2440 | - } |
2441 | - } |
2442 | - } |
2443 | - catch (SQLHeavy.Error err) { |
2444 | - warning ("Could not save media: %s \n", err.message); |
2445 | - } |
2446 | - return tree_set; |
2447 | - } |
2448 | - |
2449 | - public void remove_media (Gee.Collection<Media> media) { |
2450 | - assert (database != null); |
2451 | - try { |
2452 | - transaction = database.begin_transaction(); |
2453 | - Query query = transaction.prepare ("DELETE FROM `media` WHERE rowid=:rowid"); |
2454 | - |
2455 | - foreach (var m in media) { |
2456 | - query.set_int (":rowid", m.rowid); |
2457 | - query.execute (); |
2458 | - } |
2459 | - |
2460 | - transaction.commit (); |
2461 | - } |
2462 | - catch (SQLHeavy.Error err) { |
2463 | - warning ("Could not remove media from db: %s\n", err.message); |
2464 | - } |
2465 | - } |
2466 | - |
2467 | - /** COLUMNS STATE ** |
2468 | - * load_columns_state() loads the state of each columns from db |
2469 | - * |
2470 | - */ |
2471 | - public Gee.HashMap<Playlist, TreeViewSetup> load_columns_state () { |
2472 | - debug ("load columns"); |
2473 | - assert (database != null); |
2474 | - var rv = new Gee.HashMap<Playlist, TreeViewSetup>(); |
2475 | - |
2476 | - try { |
2477 | - string script = "SELECT * FROM `columns`"; |
2478 | - Query query = new Query(database, script); |
2479 | - |
2480 | - for (var results = query.execute(); !results.finished; results.next() ) { |
2481 | - if (results.fetch_int(0) == 0) { |
2482 | - StaticPlaylist p = libraries_manager.local_library.playlist_from_name (results.fetch_string(1)); |
2483 | - var tvs = new TreeViewSetup (results.fetch_int(2), Gtk.SortType.ASCENDING, ViewWrapper.Hint.PLAYLIST); |
2484 | - tvs.set_sort_direction_from_string(results.fetch_string(3)); |
2485 | - tvs.import_columns(results.fetch_string(4)); |
2486 | - rv.set (p, tvs); |
2487 | - } else { |
2488 | - SmartPlaylist p = libraries_manager.local_library.smart_playlist_from_name (results.fetch_string(1)); |
2489 | - var tvs = new TreeViewSetup (results.fetch_int(2), Gtk.SortType.ASCENDING, ViewWrapper.Hint.SMART_PLAYLIST); |
2490 | - tvs.set_sort_direction_from_string(results.fetch_string(3)); |
2491 | - tvs.import_columns(results.fetch_string(4)); |
2492 | - rv.set (p, tvs); |
2493 | - } |
2494 | - } |
2495 | - } |
2496 | - catch (SQLHeavy.Error err) { |
2497 | - warning ("Could not load columns from db: %s\n", err.message); |
2498 | - } |
2499 | - |
2500 | - return rv; |
2501 | - } |
2502 | - |
2503 | - public void save_columns_state (Gee.Collection<StaticPlaylist>? playlists = null, Gee.Collection<SmartPlaylist>? smart_playlists = null) { |
2504 | - debug ("save columns"); |
2505 | - assert (database != null); |
2506 | - try { |
2507 | - database.execute("DELETE FROM `columns`"); |
2508 | - transaction = database.begin_transaction(); |
2509 | - Query query = transaction.prepare ("""INSERT INTO `columns` (`is_smart`, `name`, `sort_column_id`, `sort_direction`, `columns`) |
2510 | - VALUES (:is_smart, :name, :sort_column_id, :sort_direction, :columns);"""); |
2511 | - |
2512 | - if (playlists != null) { |
2513 | - foreach(StaticPlaylist p in playlists) { |
2514 | - if (p.read_only == false) { |
2515 | - var tvs = App.main_window.get_treeviewsetup_from_playlist (p); |
2516 | - |
2517 | - query.set_int (":is_smart", 0); |
2518 | - query.set_string (":name", p.name); |
2519 | - query.set_int (":sort_column_id", tvs.sort_column_id); |
2520 | - query.set_string (":sort_direction", tvs.sort_direction_to_string()); |
2521 | - query.set_string (":columns", tvs.columns_to_string()); |
2522 | - |
2523 | - query.execute(); |
2524 | - } |
2525 | - } |
2526 | - } |
2527 | - |
2528 | - if (smart_playlists != null) { |
2529 | - foreach(SmartPlaylist p in smart_playlists) { |
2530 | - var tvs = App.main_window.get_treeviewsetup_from_playlist (p); |
2531 | - |
2532 | - query.set_int (":is_smart", 1); |
2533 | - query.set_string (":name", p.name); |
2534 | - query.set_int (":sort_column_id", tvs.sort_column_id); |
2535 | - query.set_string (":sort_direction", tvs.sort_direction_to_string()); |
2536 | - query.set_string (":columns", tvs.columns_to_string()); |
2537 | - |
2538 | - query.execute(); |
2539 | - } |
2540 | - } |
2541 | - |
2542 | - transaction.commit(); |
2543 | - } |
2544 | - catch(SQLHeavy.Error err) { |
2545 | - warning ("Could not save playlists: %s \n", err.message); |
2546 | - } |
2547 | - } |
2548 | - |
2549 | - public void add_columns_state (StaticPlaylist? p = null, SmartPlaylist? sp = null) { |
2550 | - debug ("add columns"); |
2551 | - assert (database != null); |
2552 | - |
2553 | - string name = ""; |
2554 | - int is_smart = 0; |
2555 | - TreeViewSetup tvs; |
2556 | - if (sp == null) { |
2557 | - if (p == null) |
2558 | - return; |
2559 | - if (p.read_only == true) |
2560 | - return; |
2561 | - name = p.name; |
2562 | - tvs = App.main_window.get_treeviewsetup_from_playlist (p); |
2563 | - } else { |
2564 | - if (sp == null) |
2565 | - return; |
2566 | - is_smart = 1; |
2567 | - name = sp.name; |
2568 | - tvs = App.main_window.get_treeviewsetup_from_playlist (sp); |
2569 | - } |
2570 | - |
2571 | - try { |
2572 | - transaction = database.begin_transaction(); |
2573 | - Query query = transaction.prepare ("""INSERT INTO `columns` (`is_smart`, `name`, `sort_column_id`, `sort_direction`, `columns`) |
2574 | - VALUES (:is_smart, :name, :sort_column_id, :sort_direction, :columns);"""); |
2575 | - |
2576 | - query.set_int (":is_smart", is_smart); |
2577 | - query.set_string (":name", name); |
2578 | - query.set_int (":sort_column_id", tvs.sort_column_id); |
2579 | - query.set_string (":sort_direction", tvs.sort_direction_to_string()); |
2580 | - query.set_string (":columns", tvs.columns_to_string()); |
2581 | - query.execute(); |
2582 | - |
2583 | - transaction.commit(); |
2584 | - } |
2585 | - catch(SQLHeavy.Error err) { |
2586 | - warning ("Could not add columns: %s \n", err.message); |
2587 | - } |
2588 | - } |
2589 | - |
2590 | - public void remove_columns_state (StaticPlaylist? p = null, SmartPlaylist? sp = null) { |
2591 | - debug ("remove columns"); |
2592 | - assert (database != null); |
2593 | - |
2594 | - string name = ""; |
2595 | - if (sp == null) { |
2596 | - if (p == null) |
2597 | - return; |
2598 | - if (p.read_only == true) |
2599 | - return; |
2600 | - name = p.name; |
2601 | - } else { |
2602 | - if (sp == null) |
2603 | - return; |
2604 | - name = sp.name; |
2605 | - } |
2606 | - try { |
2607 | - transaction = database.begin_transaction(); |
2608 | - Query query = transaction.prepare("""DELETE FROM `columns` WHERE name=:name"""); |
2609 | - |
2610 | - query.set_string(":name", name); |
2611 | - query.execute(); |
2612 | - |
2613 | - transaction.commit(); |
2614 | - } |
2615 | - catch (SQLHeavy.Error err) { |
2616 | - warning ("Could not remove column from db: %s\n", err.message); |
2617 | - } |
2618 | - } |
2619 | - |
2620 | - public void add_default_columns () { |
2621 | - assert (database != null); |
2622 | - try { |
2623 | - |
2624 | - TreeViewSetup tvs = new TreeViewSetup (ListColumn.ARTIST, Gtk.SortType.ASCENDING, ViewWrapper.Hint.SMART_PLAYLIST); |
2625 | - |
2626 | - transaction = database.begin_transaction(); |
2627 | - Query query = transaction.prepare ("""INSERT INTO `columns` (`is_smart`, `name`, `sort_column_id`, `sort_direction`, `columns`) |
2628 | - VALUES (:is_smart, :name, :sort_column_id, :sort_direction, :columns);"""); |
2629 | - |
2630 | - query.set_int (":is_smart", 1); |
2631 | - query.set_string (":name", _("Favorite Songs")); |
2632 | - query.set_int (":sort_column_id", ListColumn.RATING); |
2633 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2634 | - query.set_string (":columns", tvs.columns_to_string ()); |
2635 | - query.execute (); |
2636 | - |
2637 | - query.set_int (":is_smart", 1); |
2638 | - query.set_string (":name", _("Recently Added")); |
2639 | - query.set_int (":sort_column_id", ListColumn.ARTIST); |
2640 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2641 | - query.set_string (":columns", tvs.columns_to_string ()); |
2642 | - query.execute (); |
2643 | - |
2644 | - /* |
2645 | - query.set_int (":is_smart", 1); |
2646 | - query.set_string (":name", _("Recently Played")); |
2647 | - query.set_int (":sort_column_id", ListColumn.LAST_PLAYED); |
2648 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2649 | - query.set_string (":columns", tvs.columns_to_string ()); |
2650 | - query.execute (); |
2651 | - */ |
2652 | - |
2653 | - query.set_int (":is_smart", 1); |
2654 | - query.set_string (":name", _("Recent Favorites")); |
2655 | - query.set_int (":sort_column_id", ListColumn.RATING); |
2656 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2657 | - query.set_string (":columns", tvs.columns_to_string ()); |
2658 | - query.execute (); |
2659 | - |
2660 | - query.set_int (":is_smart", 1); |
2661 | - query.set_string (":name", _("Never Played")); |
2662 | - query.set_int (":sort_column_id", ListColumn.ARTIST); |
2663 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2664 | - query.set_string (":columns", tvs.columns_to_string ()); |
2665 | - query.execute (); |
2666 | - |
2667 | - query.set_int (":is_smart", 1); |
2668 | - query.set_string (":name", _("Over Played")); |
2669 | - query.set_int (":sort_column_id", ListColumn.PLAY_COUNT); |
2670 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2671 | - query.set_string (":columns", tvs.columns_to_string ()); |
2672 | - query.execute (); |
2673 | - |
2674 | - query.set_int (":is_smart", 1); |
2675 | - query.set_string (":name", _("Not Recently Played")); |
2676 | - query.set_int (":sort_column_id", ListColumn.NUMBER); |
2677 | - query.set_string (":sort_direction", tvs.sort_direction_to_string ()); |
2678 | - query.set_string (":columns", tvs.columns_to_string ()); |
2679 | - query.execute (); |
2680 | - |
2681 | - transaction.commit(); |
2682 | - } |
2683 | - catch (SQLHeavy.Error err) { |
2684 | - warning ("Could not initialize columns: %s\n", err.message); |
2685 | - } |
2686 | - } |
2687 | - |
2688 | - /** PLAYLISTS ** |
2689 | - * load_playlists() loads playlists from db |
2690 | - * |
2691 | - * playlist_from_id loads playlist of given rowid |
2692 | - * |
2693 | - * playlist_from_name() loads playlsit given a name |
2694 | - */ |
2695 | - public Gee.ArrayList<StaticPlaylist> load_playlists () { |
2696 | - var rv = new Gee.ArrayList<StaticPlaylist>(); |
2697 | - assert (database != null); |
2698 | - |
2699 | - try { |
2700 | - string script = "SELECT * FROM `playlists`"; |
2701 | - Query query = new Query(database, script); |
2702 | - |
2703 | - for (var results = query.execute(); !results.finished; results.next() ) { |
2704 | - var p = new StaticPlaylist.with_info(0, results.fetch_string(0)); |
2705 | - |
2706 | - string media = results.fetch_string(1); |
2707 | - |
2708 | - string[] media_strings = media.split("<sep>", 0); |
2709 | - int index; |
2710 | - var uris = new Gee.LinkedList<string> (); |
2711 | - for (index = 0; index < media_strings.length - 1; ++index) { |
2712 | - uris.add (media_strings[index]); |
2713 | - } |
2714 | - p.add_medias (libraries_manager.local_library.medias_from_uris (uris)); |
2715 | - |
2716 | - if (!rv.contains (p)) |
2717 | - rv.add(p); |
2718 | - } |
2719 | - } |
2720 | - catch (SQLHeavy.Error err) { |
2721 | - warning ("Could not load playlists from db: %s\n", err.message); |
2722 | - } |
2723 | - |
2724 | - return rv; |
2725 | - } |
2726 | - |
2727 | - public void save_playlists (Gee.Collection<StaticPlaylist> playlists) { |
2728 | - assert (database != null); |
2729 | - try { |
2730 | - database.execute("DELETE FROM `playlists`"); |
2731 | - transaction = database.begin_transaction(); |
2732 | - Query query = transaction.prepare ("INSERT INTO `playlists` (`name`, `media`) VALUES (:name, :media);"); |
2733 | - |
2734 | - foreach (var p in playlists) { |
2735 | - if (p.read_only == false || p.name == C_("Name of the playlist", "Queue") || p.name == _("History")) { |
2736 | - string rv = ""; |
2737 | - |
2738 | - foreach (var m in p.medias) { |
2739 | - if (m != null) |
2740 | - rv += m.uri + "<sep>"; |
2741 | - } |
2742 | - query.set_string(":name", p.name); |
2743 | - query.set_string(":media", rv); |
2744 | - |
2745 | - query.execute(); |
2746 | - } |
2747 | - } |
2748 | - |
2749 | - transaction.commit(); |
2750 | - } |
2751 | - catch(SQLHeavy.Error err) { |
2752 | - warning ("Could not save playlists: %s \n", err.message); |
2753 | - } |
2754 | - } |
2755 | - |
2756 | - public void save_playlist (StaticPlaylist p, string? old_name = null) { |
2757 | - assert (database != null); |
2758 | - try { |
2759 | - if (p.read_only == true) |
2760 | - return; |
2761 | - |
2762 | - if (old_name == null) { |
2763 | - remove_playlist (p); |
2764 | - } else { |
2765 | - var pl = new StaticPlaylist.with_info (0, old_name); |
2766 | - remove_playlist (pl); |
2767 | - } |
2768 | - transaction = database.begin_transaction(); |
2769 | - Query query = transaction.prepare ("INSERT INTO `playlists` (`name`, `media`) VALUES (:name, :media);"); |
2770 | - |
2771 | - string rv = ""; |
2772 | - |
2773 | - foreach (var m in p.medias) { |
2774 | - if (m != null) |
2775 | - rv += m.uri + "<sep>"; |
2776 | - } |
2777 | - query.set_string(":name", p.name); |
2778 | - query.set_string(":media", rv); |
2779 | - |
2780 | - query.execute(); |
2781 | - |
2782 | - transaction.commit(); |
2783 | - } |
2784 | - catch(SQLHeavy.Error err) { |
2785 | - warning ("Could not save playlists: %s \n", err.message); |
2786 | - } |
2787 | - } |
2788 | - |
2789 | - public void add_playlist (StaticPlaylist p) { |
2790 | - assert (database != null); |
2791 | - if (p.read_only == true) |
2792 | - return; |
2793 | - string rv = ""; |
2794 | - |
2795 | - foreach (var m in p.medias) { |
2796 | - if (m != null) |
2797 | - rv += m.uri + "<sep>"; |
2798 | - } |
2799 | - |
2800 | - try { |
2801 | - transaction = database.begin_transaction(); |
2802 | - Query query = transaction.prepare ("""INSERT INTO `playlists` (`name`, `media`) |
2803 | - VALUES (:name, :media);"""); |
2804 | - |
2805 | - query.set_string(":name", p.name); |
2806 | - query.set_string(":media", rv); |
2807 | - |
2808 | - query.execute(); |
2809 | - |
2810 | - transaction.commit(); |
2811 | - |
2812 | - debug ("playlist %s stored into database", p.name); |
2813 | - } |
2814 | - catch(SQLHeavy.Error err) { |
2815 | - warning ("Could not add playlists: %s \n", err.message); |
2816 | - } |
2817 | - } |
2818 | - |
2819 | - /*public void update_playlists(LinkedList<StaticPlaylist> playlists) { |
2820 | - try { |
2821 | - transaction = database.begin_transaction(); |
2822 | - Query query = transaction.prepare("UPDATE `playlists` SET name=:name, media=:media, sort_column_id=:sort_column_id, sort_direction=:sort_direction, columns=:columns WHERE name=:name"); |
2823 | - |
2824 | - foreach (var p in playlists) { |
2825 | - query.set_string(":name", p.name); |
2826 | - query.set_string(":media", p.media_to_string(App.library_manager)); |
2827 | - query.set_int(":sort_column_id", p.tvs.sort_column_id); |
2828 | - query.set_string(":sort_direction", p.tvs.sort_direction_to_string()); |
2829 | - query.set_string(":columns", p.tvs.columns_to_string()); |
2830 | - |
2831 | - query.execute(); |
2832 | - } |
2833 | - |
2834 | - transaction.commit(); |
2835 | - } |
2836 | - catch(SQLHeavy.Error err) { |
2837 | - warning ("Could not update playlist: %s \n", err.message); |
2838 | - } |
2839 | - }*/ |
2840 | - |
2841 | - public void remove_playlist (StaticPlaylist p) { |
2842 | - assert (database != null); |
2843 | - if (p.read_only == true) |
2844 | - return; |
2845 | - try { |
2846 | - transaction = database.begin_transaction(); |
2847 | - Query query = transaction.prepare("""DELETE FROM `playlists` WHERE name=:name"""); |
2848 | - |
2849 | - query.set_string(":name", p.name); |
2850 | - query.execute(); |
2851 | - |
2852 | - transaction.commit(); |
2853 | - } |
2854 | - catch (SQLHeavy.Error err) { |
2855 | - warning ("Could not remove playlist from db: %s\n", err.message); |
2856 | - } |
2857 | - } |
2858 | - |
2859 | - /** SMART PLAYLISTS **/ |
2860 | - |
2861 | - private static const string QUERY_SEPARATOR = "<query_sep>"; |
2862 | - private static const string VALUE_SEPARATOR = "<val_sep>"; |
2863 | - |
2864 | - /** temp_playlist should be in format of #,#,#,#,#, **/ |
2865 | - public static Gee.LinkedList<SmartQuery> queries_from_string (string q) { |
2866 | - string[] queries_in_string = q.split(QUERY_SEPARATOR, 0); |
2867 | - int index; |
2868 | - |
2869 | - var queries = new Gee.LinkedList<SmartQuery> (); |
2870 | - for(index = 0; index < queries_in_string.length - 1; index++) { |
2871 | - string[] pieces_of_query = queries_in_string[index].split(VALUE_SEPARATOR, 3); |
2872 | - pieces_of_query.resize (3); |
2873 | - |
2874 | - SmartQuery sq = new SmartQuery(); |
2875 | - sq.field = (SmartQuery.FieldType)int.parse(pieces_of_query[0]); |
2876 | - sq.comparator = (SmartQuery.ComparatorType)int.parse(pieces_of_query[1]); |
2877 | - sq.value = pieces_of_query[2]; |
2878 | - |
2879 | - queries.add (sq); |
2880 | - } |
2881 | - |
2882 | - return queries; |
2883 | - } |
2884 | - |
2885 | - // FIXME: This is an implementation detail and should not be present in the core. |
2886 | - public static string queries_to_string (Gee.Collection<SmartQuery> queries) { |
2887 | - string rv = ""; |
2888 | - foreach (SmartQuery q in queries) { |
2889 | - rv += ((int)q.field).to_string () + VALUE_SEPARATOR + ((int)q.comparator).to_string() + VALUE_SEPARATOR + q.value + QUERY_SEPARATOR; |
2890 | - } |
2891 | - |
2892 | - return rv; |
2893 | - } |
2894 | - |
2895 | - public void add_default_smart_playlists () { |
2896 | - assert (database != null); |
2897 | - try { |
2898 | - transaction = database.begin_transaction(); |
2899 | - Query query = transaction.prepare ("""INSERT INTO `smart_playlists` (`name`, `and_or`, `queries`, `limit`, `limit_amount`) VALUES (:name, :and_or, :queries, :limit, :limit_amount);"""); |
2900 | - |
2901 | - query.set_string(":name", _("Favorite Songs")); |
2902 | - query.set_int(":and_or", 1); |
2903 | - query.set_string(":queries", "11<val_sep>2<val_sep>4<query_sep>13<val_sep>0<val_sep>0<query_sep>12<val_sep>6<val_sep>3<query_sep>"); |
2904 | - query.set_int(":limit", 1); |
2905 | - query.set_int(":limit_amount", 50); |
2906 | - query.execute(); |
2907 | - |
2908 | - query.set_string(":name", _("Recently Added")); |
2909 | - query.set_int(":and_or", 1); |
2910 | - query.set_string(":queries", "5<val_sep>7<val_sep>7<query_sep>"); |
2911 | - query.set_int(":limit", 1); |
2912 | - query.set_int(":limit_amount", 50); |
2913 | - query.execute(); |
2914 | - |
2915 | - /* |
2916 | - query.set_string(":name", _("Recently Played")); |
2917 | - query.set_int(":and_or", 1); |
2918 | - query.set_string(":queries", "9<val_sep>7<val_sep>7<query_sep>"); |
2919 | - query.set_int(":limit", 0); |
2920 | - query.set_int(":limit_amount", 50); |
2921 | - query.execute(); |
2922 | - */ |
2923 | - |
2924 | - query.set_string(":name", _("Recent Favorites")); |
2925 | - query.set_int(":and_or", 1); |
2926 | - query.set_string(":queries", "11<val_sep>2<val_sep>4<query_sep>13<val_sep>0<val_sep>0<query_sep>9<val_sep>7<val_sep>7<query_sep>"); |
2927 | - query.set_int(":limit", 1); |
2928 | - query.set_int(":limit_amount", 50); |
2929 | - query.execute(); |
2930 | - |
2931 | - query.set_string(":name", _("Never Played")); |
2932 | - query.set_int(":and_or", 0); |
2933 | - query.set_string(":queries", "11<val_sep>0<val_sep>0<query_sep>"); |
2934 | - query.set_int(":limit", 1); |
2935 | - query.set_int(":limit_amount", 50); |
2936 | - query.execute(); |
2937 | - |
2938 | - query.set_string(":name", _("Over Played")); |
2939 | - query.set_int(":and_or", 1); |
2940 | - query.set_string(":queries", "11<val_sep>4<val_sep>10<query_sep>"); |
2941 | - query.set_int(":limit", 1); |
2942 | - query.set_int(":limit_amount", 50); |
2943 | - query.execute(); |
2944 | - |
2945 | - query.set_string(":name", _("Not Recently Played")); |
2946 | - query.set_int(":and_or", 1); |
2947 | - query.set_string(":queries", "9<val_sep>8<val_sep>7<query_sep>"); |
2948 | - query.set_int(":limit", 1); |
2949 | - query.set_int(":limit_amount", 50); |
2950 | - query.execute(); |
2951 | - |
2952 | - transaction.commit(); |
2953 | - } |
2954 | - catch (SQLHeavy.Error err) { |
2955 | - warning ("Could not initialize smart playlists: %s\n", err.message); |
2956 | - } |
2957 | - } |
2958 | - |
2959 | - public Gee.ArrayList<SmartPlaylist> load_smart_playlists() { |
2960 | - var rv = new Gee.ArrayList<SmartPlaylist>(); |
2961 | - assert (database != null); |
2962 | - |
2963 | - try { |
2964 | - string script = "SELECT * FROM `smart_playlists`"; |
2965 | - Query query = new Query(database, script); |
2966 | - |
2967 | - for (var results = query.execute(); !results.finished; results.next() ) { |
2968 | - SmartPlaylist p = new SmartPlaylist (libraries_manager.local_library); |
2969 | - |
2970 | - p.name = results.fetch_string(0); |
2971 | - p.conditional = (SmartPlaylist.ConditionalType)results.fetch_int(1); |
2972 | - p.add_queries (queries_from_string(results.fetch_string (2))); |
2973 | - p.limit = ( results.fetch_string(3) == "1") ? true : false; |
2974 | - p.limit_amount = results.fetch_int(4); |
2975 | - |
2976 | - rv.add(p); |
2977 | - } |
2978 | - } |
2979 | - catch (SQLHeavy.Error err) { |
2980 | - warning ("Could not load smart playlists from db: %s\n", err.message); |
2981 | - } |
2982 | - |
2983 | - return rv; |
2984 | - } |
2985 | - |
2986 | - public void save_smart_playlists(Gee.Collection<SmartPlaylist> smarts) { |
2987 | - assert (database != null); |
2988 | - try { |
2989 | - database.execute("DELETE FROM `smart_playlists`"); |
2990 | - transaction = database.begin_transaction(); |
2991 | - Query query = transaction.prepare ("INSERT INTO `smart_playlists` (`name`, `and_or`, `queries`, `limit`, `limit_amount`) VALUES (:name, :and_or, :queries, :limit, :limit_amount);"); |
2992 | - |
2993 | - foreach(SmartPlaylist s in smarts) { |
2994 | - query.set_string(":name", s.name); |
2995 | - query.set_int(":and_or", (int)s.conditional); |
2996 | - query.set_string(":queries", queries_to_string (s.get_queries ())); |
2997 | - query.set_int(":limit", ( s.limit ) ? 1 : 0); |
2998 | - query.set_int(":limit_amount", s.limit_amount); |
2999 | - |
3000 | - query.execute(); |
3001 | - } |
3002 | - |
3003 | - transaction.commit(); |
3004 | - } catch (SQLHeavy.Error err) { |
3005 | - warning ("Could not save smart playlists: %s \n", err.message); |
3006 | - } |
3007 | - } |
3008 | - |
3009 | - public void save_smart_playlist (SmartPlaylist p, string? old_name = null) { |
3010 | - assert (database != null); |
3011 | - if (old_name == null) { |
3012 | - remove_smart_playlist (p); |
3013 | - } else { |
3014 | - var sp = new SmartPlaylist (libraries_manager.local_library); |
3015 | - sp.name = old_name; |
3016 | - remove_smart_playlist (sp); |
3017 | - } |
3018 | - |
3019 | - try { |
3020 | - transaction = database.begin_transaction(); |
3021 | - Query query = transaction.prepare("""INSERT INTO `smart_playlists` (`name`, `and_or`, `queries`, `limit`, `limit_amount`) VALUES (:name, :and_or, :queries, :limit, :limit_amount);"""); |
3022 | - |
3023 | - query.set_string(":name", p.name); |
3024 | - query.set_int(":and_or", (int)p.conditional); |
3025 | - query.set_string(":queries", queries_to_string (p.get_queries ())); |
3026 | - query.set_int(":limit", ( p.limit ) ? 1 : 0); |
3027 | - query.set_int(":limit_amount", p.limit_amount); |
3028 | - |
3029 | - query.execute(); |
3030 | - transaction.commit(); |
3031 | - } catch(SQLHeavy.Error err) { |
3032 | - warning ("Could not update smart playlist: %s \n", err.message); |
3033 | - } |
3034 | - } |
3035 | - |
3036 | - public void remove_smart_playlist (SmartPlaylist p) { |
3037 | - assert (database != null); |
3038 | - try { |
3039 | - transaction = database.begin_transaction(); |
3040 | - Query query = transaction.prepare("""DELETE FROM `smart_playlists` WHERE name=:name"""); |
3041 | - |
3042 | - query.set_string(":name", p.name); |
3043 | - query.execute(); |
3044 | - |
3045 | - transaction.commit(); |
3046 | - } catch (SQLHeavy.Error err) { |
3047 | - warning ("Could not remove smart playlist from db: %s\n", err.message); |
3048 | - } |
3049 | - } |
3050 | - |
3051 | - public Gee.Collection<DevicePreferences> load_devices() { |
3052 | - assert (database != null); |
3053 | - var rv = new Gee.ArrayList<DevicePreferences>(); |
3054 | - |
3055 | - try { |
3056 | - string script = """SELECT rowid,* FROM `devices`"""; |
3057 | - Query query = new Query(database, script); |
3058 | - |
3059 | - for (var results = query.execute(); !results.finished; results.next() ) { |
3060 | - DevicePreferences dp = new DevicePreferences(results.fetch_string(1)); |
3061 | - |
3062 | - dp.sync_when_mounted = (results.fetch_int(2) == 1); |
3063 | - dp.sync_music = (results.fetch_int(3) == 1); |
3064 | - dp.sync_podcasts = (results.fetch_int(4) == 1); |
3065 | - dp.sync_audiobooks = (results.fetch_int(5) == 1); |
3066 | - dp.sync_all_music = (results.fetch_int(6) == 1); |
3067 | - dp.sync_all_podcasts = (results.fetch_int(7) == 1); |
3068 | - dp.sync_all_audiobooks = (results.fetch_int(8) == 1); |
3069 | - if (results.fetch_string(9) != null) { |
3070 | - dp.music_playlist = libraries_manager.local_library.playlist_from_name (results.fetch_string(9)); |
3071 | - if (dp.music_playlist == null) |
3072 | - dp.music_playlist = libraries_manager.local_library.smart_playlist_from_name (results.fetch_string(9)); |
3073 | - } |
3074 | - if (results.fetch_string(10) != null) { |
3075 | - dp.podcast_playlist = libraries_manager.local_library.playlist_from_name (results.fetch_string(10)); |
3076 | - if (dp.podcast_playlist == null) |
3077 | - dp.podcast_playlist = libraries_manager.local_library.smart_playlist_from_name (results.fetch_string(10)); |
3078 | - } |
3079 | - if (results.fetch_string(11) != null) { |
3080 | - dp.audiobook_playlist = libraries_manager.local_library.playlist_from_name (results.fetch_string(11)); |
3081 | - if (dp.audiobook_playlist == null) |
3082 | - dp.audiobook_playlist = libraries_manager.local_library.smart_playlist_from_name (results.fetch_string(11)); |
3083 | - } |
3084 | - dp.last_sync_time = results.fetch_int(12); |
3085 | - |
3086 | - rv.add (dp); |
3087 | - } |
3088 | - } catch (SQLHeavy.Error err) { |
3089 | - warning ("Could not load devices from db: %s\n", err.message); |
3090 | - } |
3091 | - |
3092 | - return rv; |
3093 | - } |
3094 | - |
3095 | - public void save_devices(Gee.Collection<DevicePreferences> devices) { |
3096 | - assert (database != null); |
3097 | - try { |
3098 | - database.execute("DELETE FROM `devices`"); |
3099 | - transaction = database.begin_transaction(); |
3100 | - Query query = transaction.prepare("""INSERT INTO `devices` (`unique_id`, `sync_when_mounted`, `sync_music`, |
3101 | - `sync_podcasts`, `sync_audiobooks`, `sync_all_music`, `sync_all_podcasts`, `sync_all_audiobooks`, `music_playlist`, |
3102 | - `podcast_playlist`, `audiobook_playlist`, `last_sync_time`) VALUES (:unique_id, :sync_when_mounted, :sync_music, :sync_podcasts, :sync_audiobooks, |
3103 | - :sync_all_music, :sync_all_podcasts, :sync_all_audiobooks, :music_playlist, :podcast_playlist, :audiobook_playlist, :last_sync_time);"""); |
3104 | - |
3105 | - foreach(DevicePreferences dp in devices) { |
3106 | - query.set_string(":unique_id", dp.id); |
3107 | - query.set_int(":sync_when_mounted", dp.sync_when_mounted ? 1 : 0); |
3108 | - |
3109 | - query.set_int(":sync_music", dp.sync_music ? 1 : 0); |
3110 | - query.set_int(":sync_podcasts", dp.sync_podcasts ? 1 : 0); |
3111 | - query.set_int(":sync_audiobooks", dp.sync_audiobooks ? 1 : 0); |
3112 | - |
3113 | - query.set_int(":sync_all_music", dp.sync_all_music ? 1 : 0); |
3114 | - query.set_int(":sync_all_podcasts", dp.sync_all_podcasts ? 1 : 0); |
3115 | - query.set_int(":sync_all_audiobooks", dp.sync_all_audiobooks ? 1 : 0); |
3116 | - |
3117 | - string music_playlist = ""; |
3118 | - string podcast_playlist = ""; |
3119 | - string audiobook_playlist = ""; |
3120 | - |
3121 | - if (dp.music_playlist != null) |
3122 | - music_playlist = dp.music_playlist.name; |
3123 | - if (dp.podcast_playlist != null) |
3124 | - podcast_playlist = dp.podcast_playlist.name; |
3125 | - if (dp.audiobook_playlist != null) |
3126 | - audiobook_playlist = dp.audiobook_playlist.name; |
3127 | - |
3128 | - query.set_string(":music_playlist", music_playlist); |
3129 | - query.set_string(":podcast_playlist", podcast_playlist); |
3130 | - query.set_string(":audiobook_playlist", audiobook_playlist); |
3131 | - query.set_int(":last_sync_time", dp.last_sync_time); |
3132 | - |
3133 | - query.execute(); |
3134 | - } |
3135 | - |
3136 | - transaction.commit(); |
3137 | - } catch (SQLHeavy.Error err) { |
3138 | - warning ("Could not save devices: %s\n", err.message); |
3139 | - } |
3140 | - } |
3141 | - |
3142 | - public void save_device (DevicePreferences dp) { |
3143 | - assert (database != null); |
3144 | - try { |
3145 | - remove_device (dp); |
3146 | - transaction = database.begin_transaction(); |
3147 | - Query query = transaction.prepare("""INSERT INTO `devices` (`unique_id`, `sync_when_mounted`, `sync_music`, |
3148 | - `sync_podcasts`, `sync_audiobooks`, `sync_all_music`, `sync_all_podcasts`, `sync_all_audiobooks`, `music_playlist`, |
3149 | - `podcast_playlist`, `audiobook_playlist`, `last_sync_time`) VALUES (:unique_id, :sync_when_mounted, :sync_music, :sync_podcasts, :sync_audiobooks, |
3150 | - :sync_all_music, :sync_all_podcasts, :sync_all_audiobooks, :music_playlist, :podcast_playlist, :audiobook_playlist, :last_sync_time);"""); |
3151 | - |
3152 | - query.set_string(":unique_id", dp.id); |
3153 | - query.set_int(":sync_when_mounted", dp.sync_when_mounted ? 1 : 0); |
3154 | - |
3155 | - query.set_int(":sync_music", dp.sync_music ? 1 : 0); |
3156 | - query.set_int(":sync_podcasts", dp.sync_podcasts ? 1 : 0); |
3157 | - query.set_int(":sync_audiobooks", dp.sync_audiobooks ? 1 : 0); |
3158 | - |
3159 | - query.set_int(":sync_all_music", dp.sync_all_music ? 1 : 0); |
3160 | - query.set_int(":sync_all_podcasts", dp.sync_all_podcasts ? 1 : 0); |
3161 | - query.set_int(":sync_all_audiobooks", dp.sync_all_audiobooks ? 1 : 0); |
3162 | - |
3163 | - string music_playlist = ""; |
3164 | - string podcast_playlist = ""; |
3165 | - string audiobook_playlist = ""; |
3166 | - |
3167 | - if (dp.music_playlist != null) |
3168 | - music_playlist = dp.music_playlist.name; |
3169 | - if (dp.podcast_playlist != null) |
3170 | - podcast_playlist = dp.podcast_playlist.name; |
3171 | - if (dp.audiobook_playlist != null) |
3172 | - audiobook_playlist = dp.audiobook_playlist.name; |
3173 | - |
3174 | - query.set_string(":music_playlist", music_playlist); |
3175 | - query.set_string(":podcast_playlist", podcast_playlist); |
3176 | - query.set_string(":audiobook_playlist", audiobook_playlist); |
3177 | - query.set_int(":last_sync_time", dp.last_sync_time); |
3178 | - |
3179 | - query.execute(); |
3180 | - |
3181 | - transaction.commit(); |
3182 | - } |
3183 | - catch(SQLHeavy.Error err) { |
3184 | - warning ("Could not save device: %s\n", err.message); |
3185 | - } |
3186 | - } |
3187 | - |
3188 | - public void remove_device (DevicePreferences device) { |
3189 | - assert (database != null); |
3190 | - try { |
3191 | - transaction = database.begin_transaction(); |
3192 | - Query query = transaction.prepare("""DELETE FROM `devices` WHERE unique_id=:unique_id"""); |
3193 | - |
3194 | - query.set_string(":unique_id", device.id); |
3195 | - query.execute(); |
3196 | - |
3197 | - transaction.commit(); |
3198 | - } |
3199 | - catch (SQLHeavy.Error err) { |
3200 | - warning ("Could not remove smart playlist from db: %s\n", err.message); |
3201 | - } |
3202 | - } |
3203 | -} |
3204 | |
3205 | === removed file 'src/DataBase/DataBaseUpdater.vala' |
3206 | --- src/DataBase/DataBaseUpdater.vala 2015-02-26 16:44:26 +0000 |
3207 | +++ src/DataBase/DataBaseUpdater.vala 1970-01-01 00:00:00 +0000 |
3208 | @@ -1,87 +0,0 @@ |
3209 | -// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*- |
3210 | -/*- |
3211 | - * Copyright (c) 2012 Noise Developers (http://launchpad.net/noise) |
3212 | - * |
3213 | - * This software is licensed under the GNU General Public License |
3214 | - * (version 2 or later). See the COPYING file in this distribution. |
3215 | - * |
3216 | - * The Noise authors hereby grant permission for non-GPL compatible |
3217 | - * GStreamer plugins to be used and distributed together with GStreamer |
3218 | - * and Noise. This permission is above and beyond the permissions granted |
3219 | - * by the GPL license by which Noise is covered. If you modify this code |
3220 | - * you may extend this exception to your version of the code, but you are not |
3221 | - * obligated to do so. If you do not wish to do so, delete this exception |
3222 | - * statement from your version. |
3223 | - * |
3224 | - * Authored by: Scott Ringwelski <sgringwe@mtu.edu>, |
3225 | - * Victor Eduardo <victoreduardm@gmail.com> |
3226 | - */ |
3227 | - |
3228 | -public class Noise.DataBaseUpdater : Object { |
3229 | - |
3230 | - private Gee.LinkedList<Object> to_remove; |
3231 | - |
3232 | - public DataBaseUpdater () { |
3233 | - |
3234 | - to_remove = new Gee.LinkedList<Object> (); |
3235 | - |
3236 | - // Save on a regular basis and before exit |
3237 | - var app = (Noise.App) GLib.Application.get_default (); |
3238 | - app.shutdown.connect_after (() => on_close_ui_save ()); |
3239 | - app.shutdown.connect_after (update_db_sync); |
3240 | - } |
3241 | - |
3242 | - public async void removeItem (Object item) { |
3243 | - if (!to_remove.contains (item)) |
3244 | - to_remove.offer (item); |
3245 | - |
3246 | - update_db_sync (); |
3247 | - } |
3248 | - |
3249 | - private void update_db_sync () { |
3250 | - var dbm = DataBaseManager.get_default (); |
3251 | - for (Object? next = to_remove.poll (); next != null; next = to_remove.poll ()) { |
3252 | - if (next is Gee.Collection) { |
3253 | - dbm.remove_media (next as Gee.Collection<Media>); |
3254 | - } else if (next is StaticPlaylist) { |
3255 | - dbm.remove_playlist (next as StaticPlaylist); |
3256 | - dbm.remove_columns_state (next as StaticPlaylist, null); |
3257 | - } else if (next is SmartPlaylist) { |
3258 | - dbm.remove_smart_playlist (next as SmartPlaylist); |
3259 | - dbm.remove_columns_state (null, next as SmartPlaylist); |
3260 | - } else |
3261 | - assert_not_reached (); |
3262 | - } |
3263 | - } |
3264 | - |
3265 | - private bool on_close_ui_save () { |
3266 | - var playlists_and_queue = new Gee.TreeSet<StaticPlaylist> (); |
3267 | - playlists_and_queue.add_all (libraries_manager.local_library.get_playlists ()); |
3268 | - |
3269 | - playlists_and_queue.add (((LocalLibrary)libraries_manager.local_library).p_music); |
3270 | - |
3271 | - debug ("-- Saving columns state preferences DB."); |
3272 | - |
3273 | - var dbm = DataBaseManager.get_default (); |
3274 | - dbm.save_playlist (((LocalLibrary)libraries_manager.local_library).p_music); |
3275 | - dbm.save_columns_state (playlists_and_queue, libraries_manager.local_library.get_smart_playlists ()); |
3276 | - |
3277 | - debug ("-- Finished columns state preferences DB."); |
3278 | - |
3279 | - return true; |
3280 | - } |
3281 | - // If the name of the playlist changed, it provides the old name to remove it from database |
3282 | - public void save_device (DevicePreferences device) { |
3283 | - DataBaseManager.get_default ().save_device (device); |
3284 | - } |
3285 | - |
3286 | - // If the name of the playlist changed, it provides the old name to remove it from database |
3287 | - public void save_playlist (StaticPlaylist p, string? old_name = null) { |
3288 | - DataBaseManager.get_default ().save_playlist (p, old_name); |
3289 | - } |
3290 | - |
3291 | - // If the name of the playlist changed, it provides the old name to remove it from database |
3292 | - public void save_smart_playlist (SmartPlaylist p, string? old_name = null) { |
3293 | - DataBaseManager.get_default ().save_smart_playlist (p, old_name); |
3294 | - } |
3295 | -} |
3296 | |
3297 | === modified file 'src/Dialogs/FileNotFoundDialog.vala' |
3298 | --- src/Dialogs/FileNotFoundDialog.vala 2015-06-12 13:43:45 +0000 |
3299 | +++ src/Dialogs/FileNotFoundDialog.vala 2015-08-27 10:21:27 +0000 |
3300 | @@ -118,7 +118,7 @@ |
3301 | |
3302 | void locate_media_clicked () { |
3303 | Media m = media_list.get (0); |
3304 | - int media_id = m.rowid; |
3305 | + int64 media_id = m.rowid; |
3306 | |
3307 | string file = ""; |
3308 | var file_chooser = new Gtk.FileChooserDialog (_("Choose Music Folder"), this, |
3309 | |
3310 | === modified file 'src/Dialogs/MediaEditor.vala' |
3311 | --- src/Dialogs/MediaEditor.vala 2015-06-12 13:43:45 +0000 |
3312 | +++ src/Dialogs/MediaEditor.vala 2015-08-27 10:21:27 +0000 |
3313 | @@ -38,8 +38,8 @@ |
3314 | public class Noise.MediaEditor : Gtk.Dialog { |
3315 | LyricFetcher lf; |
3316 | |
3317 | - Gee.LinkedList<int> _allMedias = new Gee.LinkedList<int> (); |
3318 | - Gee.LinkedList<int> _medias = new Gee.LinkedList<int> (); |
3319 | + Gee.LinkedList<int64?> _allMedias = new Gee.LinkedList<int64?> (); |
3320 | + Gee.LinkedList<int64?> _medias = new Gee.LinkedList<int64?> (); |
3321 | |
3322 | //for padding around notebook mostly |
3323 | Gtk.Stack stack; |
3324 | @@ -53,9 +53,9 @@ |
3325 | private Gtk.Label lyricsInfobarLabel; |
3326 | private Library library; |
3327 | |
3328 | - public signal void medias_saved (Gee.Collection<int> medias); |
3329 | + public signal void medias_saved (Gee.Collection<int64?> medias); |
3330 | |
3331 | - public MediaEditor (Gee.Collection<int> allMedias, Gee.Collection<int> medias, Library library) { |
3332 | + public MediaEditor (Gee.Collection<int64?> allMedias, Gee.Collection<int64?> medias, Library library) { |
3333 | this.library = library; |
3334 | this.window_position = Gtk.WindowPosition.CENTER; |
3335 | this.type_hint = Gdk.WindowTypeHint.DIALOG; |
3336 | @@ -64,16 +64,16 @@ |
3337 | this.destroy_with_parent = true; |
3338 | this.resizable = false; |
3339 | this.deletable = false; |
3340 | - |
3341 | + |
3342 | this.set_size_request (520, -1); |
3343 | |
3344 | lf = new LyricFetcher(); |
3345 | - |
3346 | + |
3347 | _allMedias.add_all (allMedias); |
3348 | _medias.add_all (medias); |
3349 | - |
3350 | + |
3351 | stack = new Gtk.Stack (); |
3352 | - |
3353 | + |
3354 | var stack_switcher = new Gtk.StackSwitcher (); |
3355 | stack_switcher.set_stack (stack); |
3356 | stack_switcher.halign = Gtk.Align.CENTER; |
3357 | @@ -104,8 +104,9 @@ |
3358 | buttons.set_child_secondary (arrows, true); |
3359 | |
3360 | var main_grid = new Gtk.Grid (); |
3361 | - main_grid.attach (stack, 0, 0, 1, 1); |
3362 | - main_grid.attach (buttons, 0, 1, 1, 1); |
3363 | + main_grid.attach (stack_switcher, 0, 0, 1, 1); |
3364 | + main_grid.attach (stack, 0, 1, 1, 1); |
3365 | + main_grid.attach (buttons, 0, 2, 1, 1); |
3366 | |
3367 | var content = get_content_area () as Gtk.Container; |
3368 | content.margin_left = content.margin_right = 12; |
3369 | @@ -133,7 +134,7 @@ |
3370 | Media sum = library.media_from_id(_medias.get(0)).copy(); |
3371 | |
3372 | /** find what these media have what common, and keep those values **/ |
3373 | - foreach(int i in _medias) { |
3374 | + foreach (int64 i in _medias) { |
3375 | Media s = library.media_from_id(i); |
3376 | |
3377 | if(s.track != sum.track) |
3378 | @@ -294,13 +295,12 @@ |
3379 | }); |
3380 | } |
3381 | |
3382 | - |
3383 | public void previousClicked() { |
3384 | save_medias(); |
3385 | |
3386 | // now fetch the next media on current_view |
3387 | - int i = 0; // will hold next media to edit |
3388 | - int indexOfCurrentFirst = _allMedias.index_of(_medias.get(0)); |
3389 | + int64 i = 0; // will hold next media to edit |
3390 | + int indexOfCurrentFirst = _allMedias.index_of(_medias.first ()); |
3391 | |
3392 | if(indexOfCurrentFirst == 0) |
3393 | i = _allMedias.get(_allMedias.size - 1); |
3394 | @@ -308,7 +308,7 @@ |
3395 | i = _allMedias.get(indexOfCurrentFirst - 1); |
3396 | |
3397 | // now fetch the previous media on current_view |
3398 | - var newMedias = new Gee.LinkedList<int>(); |
3399 | + var newMedias = new Gee.LinkedList<int64?> (); |
3400 | newMedias.add(i); |
3401 | |
3402 | change_media(newMedias); |
3403 | @@ -318,21 +318,21 @@ |
3404 | save_medias(); |
3405 | |
3406 | // now fetch the next media on current_view |
3407 | - int i = 0; // will hold next media to edit |
3408 | + int64 i = 0; // will hold next media to edit |
3409 | int indexOfCurrentLast = _allMedias.index_of(_medias.get(_medias.size - 1)); |
3410 | |
3411 | if(indexOfCurrentLast == _allMedias.size - 1) |
3412 | - i = _allMedias.get(0); |
3413 | + i = _allMedias.first (); |
3414 | else |
3415 | i = _allMedias.get(indexOfCurrentLast + 1); |
3416 | |
3417 | - var newMedias = new Gee.LinkedList<int>(); |
3418 | + var newMedias = new Gee.LinkedList<int64?>(); |
3419 | newMedias.add(i); |
3420 | |
3421 | change_media(newMedias); |
3422 | } |
3423 | |
3424 | - public void change_media(Gee.LinkedList<int> newMedias) { |
3425 | + public void change_media(Gee.LinkedList<int64?> newMedias) { |
3426 | _medias = newMedias; |
3427 | |
3428 | Media sum = library.media_from_id(newMedias.get(0)); |
3429 | @@ -376,8 +376,8 @@ |
3430 | } |
3431 | |
3432 | public void save_medias() { |
3433 | - foreach(int i in _medias) { |
3434 | - Media s = library.media_from_id(i); |
3435 | + foreach (int64 i in _medias) { |
3436 | + Media s = library.media_from_id (i); |
3437 | |
3438 | if(fields.get("Title").checked()) |
3439 | s.title = fields.get("Title").get_value(); |
3440 | |
3441 | === modified file 'src/Dialogs/SmartPlaylistEditor.vala' |
3442 | --- src/Dialogs/SmartPlaylistEditor.vala 2015-06-12 13:43:45 +0000 |
3443 | +++ src/Dialogs/SmartPlaylistEditor.vala 2015-08-27 10:21:27 +0000 |
3444 | @@ -208,9 +208,10 @@ |
3445 | |
3446 | public virtual void save_click () { |
3447 | sp.clear_queries (); |
3448 | - var queries = new Gee.LinkedList<SmartQuery> (); |
3449 | + var queries = new Gee.TreeSet<SmartQuery> (); |
3450 | foreach (SmartPlaylistEditorQuery speq in queries_list) { |
3451 | - queries.add (speq.get_query ()); |
3452 | + var query = speq.get_query (); |
3453 | + queries.add (query); |
3454 | } |
3455 | |
3456 | sp.add_queries (queries); |
3457 | @@ -265,7 +266,6 @@ |
3458 | field_combobox.append_text (_("Comment")); |
3459 | field_combobox.append_text (_("Composer")); |
3460 | field_combobox.append_text (_("Date Added")); |
3461 | - field_combobox.append_text (_("Date Released")); |
3462 | field_combobox.append_text (_("Genre")); |
3463 | field_combobox.append_text (_("Grouping")); |
3464 | field_combobox.append_text (_("Last Played")); |
3465 | @@ -281,11 +281,11 @@ |
3466 | comparator_combobox.set_active ((int)q.comparator); |
3467 | |
3468 | if (needs_value (q.field)) { |
3469 | - value_entry.text = q.value; |
3470 | + value_entry.text = q.value.get_string (); |
3471 | } else if (q.field == SmartQuery.FieldType.RATING) { |
3472 | - _valueRating.rating = int.parse (q.value); |
3473 | + _valueRating.rating = q.value.get_int (); |
3474 | } else { |
3475 | - _valueNumerical.set_value (int.parse (q.value)); |
3476 | + _valueNumerical.set_value (q.value.get_int ()); |
3477 | } |
3478 | |
3479 | _units = new Gtk.Label (""); |
3480 | @@ -308,16 +308,23 @@ |
3481 | } |
3482 | |
3483 | public SmartQuery get_query () { |
3484 | - SmartQuery rv = new SmartQuery (); |
3485 | + var rv = new SmartQuery (); |
3486 | |
3487 | rv.field = (SmartQuery.FieldType)field_combobox.get_active (); |
3488 | rv.comparator = comparators.get (comparator_combobox.get_active ()); |
3489 | - if (needs_value ((SmartQuery.FieldType)field_combobox.get_active ())) |
3490 | - rv.value = value_entry.text; |
3491 | - else if (field_combobox.get_active () == SmartQuery.FieldType.RATING) |
3492 | - rv.value = _valueRating.rating.to_string (); |
3493 | - else |
3494 | - rv.value = _valueNumerical.value.to_string (); |
3495 | + if (needs_value ((SmartQuery.FieldType)field_combobox.get_active ())) { |
3496 | + var value = Value (typeof (string)); |
3497 | + value.set_string (value_entry.text); |
3498 | + rv.value = value; |
3499 | + } else if (field_combobox.get_active () == SmartQuery.FieldType.RATING) { |
3500 | + var value = Value (typeof (int)); |
3501 | + value.set_int (_valueRating.rating); |
3502 | + rv.value = value; |
3503 | + } else { |
3504 | + var value = Value (typeof (int)); |
3505 | + value.set_int ((int)_valueNumerical.value); |
3506 | + rv.value = value; |
3507 | + } |
3508 | |
3509 | return rv; |
3510 | } |
3511 | @@ -437,7 +444,6 @@ |
3512 | } |
3513 | |
3514 | public bool is_date (SmartQuery.FieldType compared) { |
3515 | - return (compared == SmartQuery.FieldType.LAST_PLAYED || compared == SmartQuery.FieldType.DATE_ADDED |
3516 | - || compared == SmartQuery.FieldType.DATE_RELEASED); |
3517 | + return (compared == SmartQuery.FieldType.LAST_PLAYED || compared == SmartQuery.FieldType.DATE_ADDED); |
3518 | } |
3519 | } |
3520 | |
3521 | === modified file 'src/FileOperator.vala' |
3522 | --- src/FileOperator.vala 2015-05-24 21:46:00 +0000 |
3523 | +++ src/FileOperator.vala 2015-08-27 10:21:27 +0000 |
3524 | @@ -309,7 +309,7 @@ |
3525 | App.main_window.show_notification (_("Import Complete"), _("%s has imported your library.").printf (((Noise.App) GLib.Application.get_default ()).get_name ())); |
3526 | |
3527 | if (import_type == ImportType.PLAYLIST) { |
3528 | - var to_add = new Gee.LinkedList<int> (); |
3529 | + var to_add = new Gee.LinkedList<int64?> (); |
3530 | foreach (var s in all_new_imports) |
3531 | to_add.add (s.rowid); |
3532 | new_playlist.add_medias (to_add); |
3533 | |
3534 | === modified file 'src/LibraryWindow.vala' |
3535 | --- src/LibraryWindow.vala 2015-06-12 16:10:33 +0000 |
3536 | +++ src/LibraryWindow.vala 2015-08-27 10:21:27 +0000 |
3537 | @@ -78,7 +78,6 @@ |
3538 | private Gee.HashMap<unowned Playlist, int> match_playlists; |
3539 | private Gee.HashMap<string, int> match_devices; |
3540 | private Gee.HashMap<unowned Playlist, SourceListEntry> match_playlist_entry; |
3541 | - private Gee.HashMap<Playlist, TreeViewSetup> match_tvs; |
3542 | |
3543 | public LibraryWindow () { |
3544 | headerbar = new Gtk.HeaderBar (); |
3545 | @@ -124,8 +123,10 @@ |
3546 | match_playlists = new Gee.HashMap<unowned Playlist, int> (); |
3547 | match_devices = new Gee.HashMap<string, int> (); |
3548 | match_playlist_entry = new Gee.HashMap<unowned Playlist, SourceListEntry> (); |
3549 | - match_tvs = new Gee.HashMap<Playlist, TreeViewSetup> (); |
3550 | |
3551 | + libraries_manager.add_headless_playlist.connect ((playlist) => { |
3552 | + add_playlist (playlist); |
3553 | + }); |
3554 | |
3555 | // init some booleans |
3556 | if (this.library_manager.get_medias ().size > 0) { |
3557 | @@ -340,7 +341,7 @@ |
3558 | |
3559 | public void connect_to_sourcelist_signals () { |
3560 | |
3561 | - source_list_view.selection_changed.connect ( (page_number) => { |
3562 | + source_list_view.selection_changed.connect ((page_number) => { |
3563 | view_container.set_current_view_from_index (page_number); |
3564 | }); |
3565 | |
3566 | @@ -348,7 +349,7 @@ |
3567 | search_field_has_focus = false; |
3568 | }); |
3569 | |
3570 | - source_list_view.item_action_activated.connect ( (page_number) => { |
3571 | + source_list_view.item_action_activated.connect ((page_number) => { |
3572 | var view = view_container.get_view (page_number); |
3573 | if (view is DeviceView) { |
3574 | ((DeviceView)view).d.eject(); |
3575 | @@ -356,7 +357,7 @@ |
3576 | }); |
3577 | source_list_view.edited.connect (playlist_name_edited); |
3578 | |
3579 | - source_list_view.playlist_rename_clicked.connect ( (page_number) => { |
3580 | + source_list_view.playlist_rename_clicked.connect ((page_number) => { |
3581 | var view = view_container.get_view (page_number); |
3582 | if (view is PlaylistViewWrapper) { |
3583 | search_field_has_focus = false; |
3584 | @@ -364,26 +365,29 @@ |
3585 | } |
3586 | }); |
3587 | |
3588 | - source_list_view.playlist_edit_clicked.connect ( (page_number) => { |
3589 | + source_list_view.playlist_edit_clicked.connect ((page_number) => { |
3590 | var view = view_container.get_view (page_number); |
3591 | if (view is PlaylistViewWrapper) { |
3592 | - show_smart_playlist_dialog(library_manager.smart_playlist_from_id(((PlaylistViewWrapper)view).playlist_id)); |
3593 | + var p = ((PlaylistViewWrapper)view).playlist; |
3594 | + if (p is SmartPlaylist) { |
3595 | + show_smart_playlist_dialog ((SmartPlaylist) p); |
3596 | + } |
3597 | } |
3598 | }); |
3599 | |
3600 | - source_list_view.playlist_remove_clicked.connect ( (page_number) => { |
3601 | + source_list_view.playlist_remove_clicked.connect ((page_number) => { |
3602 | var view = view_container.get_view (page_number); |
3603 | if (view is PlaylistViewWrapper) { |
3604 | var playlistview = (PlaylistViewWrapper)view; |
3605 | if (playlistview.hint == ViewWrapper.Hint.PLAYLIST) { |
3606 | - ((ViewWrapper)view).library.remove_playlist(playlistview.playlist_id); |
3607 | + playlistview.library.remove_playlist (playlistview.playlist.rowid); |
3608 | } else if (playlistview.hint == ViewWrapper.Hint.SMART_PLAYLIST) { |
3609 | - ((ViewWrapper)view).library.remove_smart_playlist(playlistview.playlist_id); |
3610 | + playlistview.library.remove_smart_playlist (playlistview.playlist.rowid); |
3611 | } |
3612 | } |
3613 | }); |
3614 | |
3615 | - source_list_view.device_import_clicked.connect ( (page_number) => { |
3616 | + source_list_view.device_import_clicked.connect ((page_number) => { |
3617 | foreach (var device in DeviceManager.get_default ().get_initialized_devices ()) { |
3618 | if(page_number == match_devices.get (device.get_unique_identifier())) { |
3619 | libraries_manager.transfer_to_local_library (device.get_library().get_medias ()); |
3620 | @@ -392,7 +396,7 @@ |
3621 | } |
3622 | }); |
3623 | |
3624 | - source_list_view.device_new_playlist_clicked.connect ( (page_number) => { |
3625 | + source_list_view.device_new_playlist_clicked.connect ((page_number) => { |
3626 | foreach (var device in DeviceManager.get_default ().get_initialized_devices ()) { |
3627 | if(page_number == match_devices.get (device.get_unique_identifier())) { |
3628 | create_new_playlist (device.get_library()); |
3629 | @@ -401,7 +405,7 @@ |
3630 | } |
3631 | }); |
3632 | |
3633 | - source_list_view.device_sync_clicked.connect ( (page_number) => { |
3634 | + source_list_view.device_sync_clicked.connect ((page_number) => { |
3635 | foreach (var device in DeviceManager.get_default ().get_initialized_devices ()) { |
3636 | if(page_number == match_devices.get (device.get_unique_identifier())) { |
3637 | device.synchronize (); |
3638 | @@ -410,7 +414,7 @@ |
3639 | } |
3640 | }); |
3641 | |
3642 | - source_list_view.device_eject_clicked.connect ( (page_number) => { |
3643 | + source_list_view.device_eject_clicked.connect ((page_number) => { |
3644 | foreach (var device in DeviceManager.get_default ().get_initialized_devices ()) { |
3645 | if(page_number == match_devices.get (device.get_unique_identifier())) { |
3646 | device.eject(); |
3647 | @@ -419,25 +423,25 @@ |
3648 | } |
3649 | }); |
3650 | |
3651 | - source_list_view.playlist_remove_clicked.connect ( (page_number) => { |
3652 | + source_list_view.playlist_remove_clicked.connect ((page_number) => { |
3653 | var view = view_container.get_view (page_number); |
3654 | if (view is PlaylistViewWrapper) { |
3655 | var playlistview = (PlaylistViewWrapper)view; |
3656 | if (playlistview.hint == ViewWrapper.Hint.PLAYLIST) { |
3657 | - ((ViewWrapper)view).library.remove_playlist(playlistview.playlist_id); |
3658 | + playlistview.library.remove_playlist (playlistview.playlist.rowid); |
3659 | } else if (playlistview.hint == ViewWrapper.Hint.SMART_PLAYLIST) { |
3660 | - ((ViewWrapper)view).library.remove_smart_playlist(playlistview.playlist_id); |
3661 | + playlistview.library.remove_smart_playlist (playlistview.playlist.rowid); |
3662 | } |
3663 | } |
3664 | }); |
3665 | |
3666 | - source_list_view.playlist_save_clicked.connect ( (page_number) => { |
3667 | + source_list_view.playlist_save_clicked.connect ((page_number) => { |
3668 | var view = view_container.get_view (page_number); |
3669 | if (view is PlaylistViewWrapper) { |
3670 | var playlistview = (PlaylistViewWrapper)view; |
3671 | if (playlistview.hint != ViewWrapper.Hint.READ_ONLY_PLAYLIST) |
3672 | return; |
3673 | - var playlist = library_manager.playlist_from_id (playlistview.playlist_id); |
3674 | + var playlist = playlistview.playlist; |
3675 | if (playlist != null) { |
3676 | var new_playlist = new StaticPlaylist (); |
3677 | new_playlist.name = PlaylistsUtils.get_new_playlist_name (library_manager.get_playlists (), playlist.name); |
3678 | @@ -447,29 +451,29 @@ |
3679 | } |
3680 | }); |
3681 | |
3682 | - source_list_view.playlist_export_clicked.connect ( (page_number) => { |
3683 | + source_list_view.playlist_export_clicked.connect ((page_number) => { |
3684 | var view = view_container.get_view (page_number); |
3685 | if (view is PlaylistViewWrapper) { |
3686 | var playlistview = (PlaylistViewWrapper)view; |
3687 | switch (playlistview.hint) { |
3688 | case ViewWrapper.Hint.PLAYLIST: |
3689 | case ViewWrapper.Hint.READ_ONLY_PLAYLIST: |
3690 | - PlaylistsUtils.export_playlist (((ViewWrapper)view).library.playlist_from_id (playlistview.playlist_id)); |
3691 | + PlaylistsUtils.export_playlist (playlistview.playlist); |
3692 | break; |
3693 | case ViewWrapper.Hint.SMART_PLAYLIST: |
3694 | - PlaylistsUtils.export_playlist (((ViewWrapper)view).library.smart_playlist_from_id (playlistview.playlist_id)); |
3695 | + PlaylistsUtils.export_playlist (playlistview.playlist); |
3696 | break; |
3697 | } |
3698 | } |
3699 | }); |
3700 | |
3701 | - source_list_view.playlist_media_added.connect ( (page_number, uris) => { |
3702 | + source_list_view.playlist_media_added.connect ((page_number, uris) => { |
3703 | var view = view_container.get_view (page_number); |
3704 | if (view is PlaylistViewWrapper) { |
3705 | var playlistview = (PlaylistViewWrapper) view; |
3706 | if (playlistview.hint == ViewWrapper.Hint.PLAYLIST) { |
3707 | var library = playlistview.library; |
3708 | - var playlist = library.playlist_from_id (playlistview.playlist_id); |
3709 | + var playlist = playlistview.playlist; |
3710 | if (playlist == null) |
3711 | return; |
3712 | |
3713 | @@ -508,18 +512,21 @@ |
3714 | viewSelector.selected = (Widgets.ViewSelector.Mode) Settings.SavedState.get_default ().view_mode; |
3715 | |
3716 | initialization_finished = true; |
3717 | - |
3718 | + |
3719 | // Set the focus on the current view |
3720 | - if (main_settings.last_playlist_playing != -1) { |
3721 | - for (int i =0; i< view_container.get_n_pages (); i++) { |
3722 | - var parent = view_container.get_nth_page (i) as ViewWrapper; |
3723 | - if (parent.relative_id == main_settings.last_playlist_playing) { |
3724 | - if (parent.hint == Noise.ViewWrapper.Hint.PLAYLIST || parent.hint == Noise.ViewWrapper.Hint.READ_ONLY_PLAYLIST) |
3725 | - show_playlist_view (libraries_manager.local_library.playlist_from_id (parent.relative_id)); |
3726 | - else if (parent.hint == Noise.ViewWrapper.Hint.SMART_PLAYLIST) |
3727 | - show_playlist_view (libraries_manager.local_library.smart_playlist_from_id (parent.relative_id)); |
3728 | - break; |
3729 | - } |
3730 | + if (main_settings.last_playlist_playing != "") { |
3731 | + Playlist? p = null; |
3732 | + if (main_settings.last_playlist_playing.contains ("s")) { |
3733 | + int64 rowid = int64.parse (main_settings.last_playlist_playing.replace ("s", "")); |
3734 | + p = library_manager.smart_playlist_from_id (rowid); |
3735 | + } else { |
3736 | + int64 rowid = int64.parse (main_settings.last_playlist_playing.replace ("p", "")); |
3737 | + p = library_manager.playlist_from_id (rowid); |
3738 | + } |
3739 | + |
3740 | + if (p != null) { |
3741 | + show_playlist_view (p); |
3742 | + } else { |
3743 | show_playlist_view (library_manager.p_music); |
3744 | } |
3745 | } else { |
3746 | @@ -534,17 +541,17 @@ |
3747 | searchField.activate.connect (searchFieldActivate); |
3748 | searchField.search_changed.connect (() => {if (searchField.text_length != 1) libraries_manager.search_for_string (searchField.get_text ());}); |
3749 | searchField.text = main_settings.search_string; |
3750 | - libraries_manager.search_for_string (main_settings.search_string); |
3751 | |
3752 | debug ("DONE WITH USER INTERFACE"); |
3753 | |
3754 | - int last_playing_id = main_settings.last_media_playing; |
3755 | - |
3756 | - if (last_playing_id > 0) { |
3757 | + int64 last_playing_id = main_settings.last_media_playing; |
3758 | + if (last_playing_id >= 0) { |
3759 | var last_playing_media = library_manager.media_from_id (last_playing_id); |
3760 | - if (last_playing_media != null && last_playing_media.file.query_exists ()) |
3761 | + if (last_playing_media != null && last_playing_media.file.query_exists ()) { |
3762 | App.player.playMedia (last_playing_media, true); |
3763 | + } |
3764 | } |
3765 | + libraries_manager.search_for_string (Settings.Main.get_default ().search_string); |
3766 | } |
3767 | |
3768 | /** |
3769 | @@ -655,36 +662,20 @@ |
3770 | |
3771 | private void load_playlists () { |
3772 | debug ("Loading playlists"); |
3773 | - |
3774 | - library_manager.add_playlist (App.player.queue_playlist); |
3775 | - library_manager.add_playlist (App.player.history_playlist); |
3776 | - |
3777 | - match_tvs.set_all (DataBaseManager.get_default ().load_columns_state ()); |
3778 | - |
3779 | + |
3780 | foreach (SmartPlaylist p in library_manager.get_smart_playlists()) { |
3781 | add_smartplaylist (p); |
3782 | } |
3783 | |
3784 | foreach (StaticPlaylist p in library_manager.get_playlists()) { |
3785 | - if (p.name != App.player.queue_playlist.name && p.name != App.player.history_playlist.name) |
3786 | - add_playlist (p); |
3787 | - } |
3788 | - |
3789 | - TreeViewSetup? music_tvs = null; |
3790 | - foreach (var entry in match_tvs.entries) { |
3791 | - if (entry.key.name == MUSIC_PLAYLIST) { |
3792 | - music_tvs = entry.value; |
3793 | - music_tvs.set_hint (ViewWrapper.Hint.MUSIC); |
3794 | - break; |
3795 | - } |
3796 | - } |
3797 | - if (music_tvs == null) { |
3798 | - music_tvs = new TreeViewSetup (ListColumn.ARTIST, |
3799 | - Gtk.SortType.ASCENDING, |
3800 | - ViewWrapper.Hint.MUSIC); |
3801 | - match_tvs.set (library_manager.p_music, music_tvs); |
3802 | - } |
3803 | + add_playlist (p); |
3804 | + } |
3805 | + |
3806 | + libraries_manager.add_headless_playlist (App.player.queue_playlist); |
3807 | + libraries_manager.add_headless_playlist (App.player.history_playlist); |
3808 | + |
3809 | // Add Music Library View |
3810 | + var music_tvs = new TreeViewSetup (ViewWrapper.Hint.MUSIC, "library:main", library_manager.connection); |
3811 | var music_view_wrapper = new MusicViewWrapper (music_tvs, library_manager, topDisplay); |
3812 | int view_number = view_container.add_view (music_view_wrapper); |
3813 | var entry = source_list_view.add_item (view_number, _("Music"), ViewWrapper.Hint.MUSIC, new ThemedIcon ("library-music")); |
3814 | @@ -772,20 +763,22 @@ |
3815 | match_devices.unset (device.get_unique_identifier()); |
3816 | remove_view_and_update (page_number); |
3817 | } |
3818 | - |
3819 | + |
3820 | private void create_device_source_list (Device d) { |
3821 | lock (match_devices) { |
3822 | SourceListEntry? entry; |
3823 | - var dv = new DeviceView (d); |
3824 | + var pref = library_manager.get_preferences_for_device (d); |
3825 | + var dv = new DeviceView (d, pref); |
3826 | int view_number = view_container.add_view (dv); |
3827 | - match_devices.set (d.get_unique_identifier(), view_number); |
3828 | - if(d.only_use_custom_view()) { |
3829 | + match_devices.set (d.get_unique_identifier (), view_number); |
3830 | + if (d.only_use_custom_view ()) { |
3831 | message("new custom device (probably a CD) added with %d songs.\n", d.get_library ().get_medias().size); |
3832 | |
3833 | entry = source_list_view.add_item (view_number, d.getDisplayName(), ViewWrapper.Hint.DEVICE, d.get_icon(), new ThemedIcon ("media-eject-symbolic"), null, d); |
3834 | } else { |
3835 | debug ("adding device view with %d\n", d.get_library ().get_medias().size); |
3836 | - var music_view_wrapper = new DeviceViewWrapper(new TreeViewSetup(ListColumn.ARTIST, Gtk.SortType.ASCENDING, ViewWrapper.Hint.DEVICE_AUDIO), d, d.get_library ()); |
3837 | + var tvs = new TreeViewSetup (ViewWrapper.Hint.DEVICE_AUDIO); |
3838 | + var music_view_wrapper = new DeviceViewWrapper(tvs, d, d.get_library ()); |
3839 | |
3840 | int subview_number = view_container.add_view (music_view_wrapper); |
3841 | entry = source_list_view.add_item (view_number, d.getDisplayName(), ViewWrapper.Hint.DEVICE, d.get_icon(), new ThemedIcon ("media-eject-symbolic"), null, d); |
3842 | @@ -825,10 +818,6 @@ |
3843 | library.add_playlist(playlist); |
3844 | } |
3845 | |
3846 | - public TreeViewSetup? get_treeviewsetup_from_playlist (Playlist p) { |
3847 | - return match_tvs.get (p); |
3848 | - } |
3849 | - |
3850 | public void show_playlist_view (Playlist p) { |
3851 | if (match_playlists.has_key (p)) { |
3852 | source_list_view.selected = match_playlist_entry.get (p); |
3853 | @@ -837,46 +826,40 @@ |
3854 | } |
3855 | |
3856 | private void create_playlist_source_list (StaticPlaylist p, SourceListExpandableItem? into_expandable = null, Library? library = library_manager) { |
3857 | - SourceListEntry? entry; |
3858 | - int view_number; |
3859 | - if (p.read_only == false) { |
3860 | - var view = new PlaylistViewWrapper (p.rowid, ViewWrapper.Hint.PLAYLIST, null, library); |
3861 | - view_number = view_container.add_view (view); |
3862 | - entry = source_list_view.add_item (view_number, p.name, ViewWrapper.Hint.PLAYLIST, p.icon, null, into_expandable); |
3863 | + ViewWrapper.Hint hint = ViewWrapper.Hint.PLAYLIST; |
3864 | + if (p.read_only == true) { |
3865 | + hint = ViewWrapper.Hint.READ_ONLY_PLAYLIST; |
3866 | + } |
3867 | + |
3868 | + TreeViewSetup? tvs = null; |
3869 | + if (p is LocalStaticPlaylist) { |
3870 | + tvs = new TreeViewSetup (hint, "library:p%lld".printf (p.rowid), library_manager.connection); |
3871 | + } else if (p == App.player.queue_playlist) { |
3872 | + tvs = new TreeViewSetup (hint, "library:queue", library_manager.connection); |
3873 | + } else if (p == App.player.history_playlist) { |
3874 | + tvs = new TreeViewSetup (hint, "library:history", library_manager.connection); |
3875 | } else { |
3876 | - if (p.name == C_("Name of the playlist", "Queue")) { |
3877 | - var queue_view = new PlaylistViewWrapper (App.player.queue_playlist.rowid, ViewWrapper.Hint.READ_ONLY_PLAYLIST, |
3878 | - match_tvs.get (App.player.queue_playlist), library); |
3879 | - queue_view.set_no_media_alert_message (_("No songs in Queue"), |
3880 | - _("To add songs to the queue, use the <b>secondary click</b> on an item and choose <b>Queue</b>. When a song finishes, the queued songs will be played first before the next song in the currently playing list.")); |
3881 | - view_number = view_container.add_view (queue_view); |
3882 | - entry = source_list_view.add_item (view_number, App.player.queue_playlist.name, |
3883 | - ViewWrapper.Hint.READ_ONLY_PLAYLIST, new ThemedIcon ("playlist-queue")); |
3884 | - update_badge_on_playlist_update (p, entry); |
3885 | - App.player.queue_media (p.medias); |
3886 | - } else if (p.name == _("History")) { |
3887 | - var history_view = new PlaylistViewWrapper (App.player.history_playlist.rowid, ViewWrapper.Hint.READ_ONLY_PLAYLIST, |
3888 | - match_tvs.get(App.player.history_playlist), library); |
3889 | - history_view.set_no_media_alert_message (_("No songs in History"), |
3890 | - _("After a part of a song has been played, it is added to the history list.\nYou can use this list to see all the songs you have played during the current session.")); |
3891 | - view_number = view_container.add_view (history_view); |
3892 | - entry = source_list_view.add_item (view_number, App.player.history_playlist.name, |
3893 | - ViewWrapper.Hint.READ_ONLY_PLAYLIST, new ThemedIcon ("document-open-recent")); |
3894 | - App.player.history_playlist.add_medias (p.medias); |
3895 | - } else { |
3896 | - var view = new PlaylistViewWrapper (p.rowid, ViewWrapper.Hint.READ_ONLY_PLAYLIST, match_tvs.get(p), library); |
3897 | - view_number = view_container.add_view (view); |
3898 | - entry = source_list_view.add_item (view_number, p.name, ViewWrapper.Hint.READ_ONLY_PLAYLIST, p.icon, null, into_expandable); |
3899 | - if (p.show_badge == true) { |
3900 | - update_badge_on_playlist_update (p, entry); |
3901 | - } |
3902 | - } |
3903 | - } |
3904 | - lock (match_playlists) { |
3905 | - match_playlist_entry.set (p, entry); |
3906 | - match_playlists.set (p, view_number); |
3907 | - } |
3908 | - if (newly_created_playlist == true) { |
3909 | + tvs = new TreeViewSetup (hint); |
3910 | + } |
3911 | + |
3912 | + var view = new PlaylistViewWrapper (p, hint, tvs, library); |
3913 | + var view_number = view_container.add_view (view); |
3914 | + var entry = source_list_view.add_item (view_number, p.name, hint, p.icon, null, into_expandable); |
3915 | + if (p.show_badge == true) { |
3916 | + update_badge_on_playlist_update (p, entry); |
3917 | + } |
3918 | + |
3919 | + if (p == App.player.queue_playlist) { |
3920 | + view.set_no_media_alert_message (_("No songs in Queue"), _("To add songs to the queue, use the <b>secondary click</b> on an item and choose <b>Queue</b>. When a song finishes, the queued songs will be played first before the next song in the currently playing list.")); |
3921 | + App.player.queue_media (p.medias); |
3922 | + } else if (p == App.player.history_playlist) { |
3923 | + view.set_no_media_alert_message (_("No songs in History"), _("After a part of a song has been played, it is added to the history list.\nYou can use this list to see all the songs you have played during the current session.")); |
3924 | + } |
3925 | + |
3926 | + match_playlist_entry.set (p, entry); |
3927 | + match_playlists.set (p, view_number); |
3928 | + |
3929 | + if (newly_created_playlist == true && p.read_only == false) { |
3930 | newly_created_playlist = false; |
3931 | show_playlist_view (p); |
3932 | |
3933 | @@ -925,24 +908,34 @@ |
3934 | } |
3935 | } |
3936 | } |
3937 | + |
3938 | private void create_smartplaylist_source_list (SmartPlaylist p, SourceListExpandableItem? into_expandable = null, Library? library = library_manager) { |
3939 | - SourceListEntry? entry; |
3940 | - int view_number; |
3941 | - |
3942 | - var view = new PlaylistViewWrapper (p.rowid, ViewWrapper.Hint.SMART_PLAYLIST, match_tvs.get(p), library_manager); |
3943 | - view.button_clicked.connect ((playlist_id) => { |
3944 | - show_smart_playlist_dialog(library_manager.smart_playlist_from_id(playlist_id)); |
3945 | + TreeViewSetup? tvs = null; |
3946 | + if (p is LocalSmartPlaylist) { |
3947 | + tvs = new TreeViewSetup (ViewWrapper.Hint.SMART_PLAYLIST, "library:s%lld".printf (p.rowid), library_manager.connection); |
3948 | + } else { |
3949 | + tvs = new TreeViewSetup (ViewWrapper.Hint.SMART_PLAYLIST); |
3950 | + } |
3951 | + |
3952 | + var view = new PlaylistViewWrapper (p, ViewWrapper.Hint.SMART_PLAYLIST, tvs, library_manager); |
3953 | + view.button_clicked.connect ((playlist) => { |
3954 | + if (playlist is SmartPlaylist) { |
3955 | + show_smart_playlist_dialog ((SmartPlaylist) playlist); |
3956 | + } |
3957 | }); |
3958 | - view_number = view_container.add_view (view); |
3959 | - entry = source_list_view.add_item (view_number, p.name, ViewWrapper.Hint.SMART_PLAYLIST, p.icon); |
3960 | + |
3961 | + var view_number = view_container.add_view (view); |
3962 | + var entry = source_list_view.add_item (view_number, p.name, ViewWrapper.Hint.SMART_PLAYLIST, p.icon); |
3963 | p.updated.connect ((old_name) => { |
3964 | if (old_name != null) |
3965 | source_list_view.change_playlist_name (match_playlists.get(p), p.name); |
3966 | }); |
3967 | + |
3968 | lock (match_playlists) { |
3969 | match_playlist_entry.set (p, entry); |
3970 | match_playlists.set (p, view_number); |
3971 | } |
3972 | + |
3973 | if (newly_created_playlist == true) { |
3974 | newly_created_playlist = false; |
3975 | show_playlist_view (p); |
3976 | @@ -996,7 +989,7 @@ |
3977 | } |
3978 | |
3979 | |
3980 | - public virtual void playback_stopped (int was_playing) { |
3981 | + public virtual void playback_stopped (int64 was_playing) { |
3982 | playButton.set_image (new Gtk.Image.from_icon_name ("media-playback-start-symbolic", Gtk.IconSize.LARGE_TOOLBAR)); |
3983 | //reset some booleans |
3984 | tested_for_video = false; |
3985 | @@ -1175,7 +1168,7 @@ |
3986 | //at 30 seconds in, we consider the media as played |
3987 | if(sec > 30 && !media_considered_played) { |
3988 | media_considered_played = true; |
3989 | - App.player.current_media.last_played = (int)time_t(); |
3990 | + App.player.current_media.last_played = (int)time_t (); |
3991 | |
3992 | library_manager.update_media (App.player.current_media, false, false); |
3993 | |
3994 | @@ -1185,17 +1178,6 @@ |
3995 | temp_media.add (App.player.current_media); |
3996 | App.player.history_playlist.add_medias (temp_media); |
3997 | } |
3998 | - |
3999 | -#if HAVE_ZEITGEIST |
4000 | - var event = new Zeitgeist.Event.full (Zeitgeist.ZG_ACCESS_EVENT, |
4001 | - Zeitgeist.ZG_SCHEDULED_ACTIVITY, "app://%s".printf (App.instance.get_desktop_file_name ()), |
4002 | - new Zeitgeist.Subject.full(App.player.current_media.uri, |
4003 | - Zeitgeist.NFO_AUDIO, |
4004 | - Zeitgeist.NFO_FILE_DATA_OBJECT, |
4005 | - "text/plain", "", |
4006 | - App.player.current_media.title, "")); |
4007 | - new Zeitgeist.Log ().insert_events_no_reply(event); |
4008 | -#endif |
4009 | } |
4010 | |
4011 | if((sec/media_length > 0.50) && (media_half_played_sended == false)) { |
4012 | |
4013 | === renamed file 'core/Devices/DevicePreferences.vala' => 'src/LocalBackend/DevicePreferences.vala' |
4014 | --- core/Devices/DevicePreferences.vala 2015-06-12 13:51:08 +0000 |
4015 | +++ src/LocalBackend/DevicePreferences.vala 2015-08-27 10:21:27 +0000 |
4016 | @@ -30,24 +30,165 @@ |
4017 | */ |
4018 | |
4019 | public class Noise.DevicePreferences : GLib.Object { |
4020 | - public string id { get; construct set; } |
4021 | - |
4022 | - public bool sync_when_mounted { get; set; } |
4023 | - public int last_sync_time { get; set; } |
4024 | - |
4025 | - public bool sync_music { get; set; default=true; } |
4026 | - public bool sync_podcasts { get; set; default=false; } |
4027 | - public bool sync_audiobooks { get; set; default=false; } |
4028 | - |
4029 | - public bool sync_all_music { get; set; default=true;} |
4030 | - public bool sync_all_podcasts { get; set; default=true; } |
4031 | - public bool sync_all_audiobooks { get; set; default=true; } |
4032 | - |
4033 | - public unowned Playlist music_playlist { get; set; } |
4034 | - public unowned Playlist podcast_playlist { get; set; } // must only contain podcasts. if not, will ignore others |
4035 | - public unowned Playlist audiobook_playlist { get; set; } // must only contain audiobooks. if not, will ignore others |
4036 | - |
4037 | - public DevicePreferences (string id) { |
4038 | - this.id = id; |
4039 | - } |
4040 | + private string id; |
4041 | + |
4042 | + public bool? _sync_when_mounted = null; |
4043 | + public bool sync_when_mounted { |
4044 | + get { |
4045 | + common_bool_getter ("sync_when_mounted", ref _sync_when_mounted); |
4046 | + return _sync_when_mounted; |
4047 | + } |
4048 | + set { |
4049 | + common_bool_setter ("sync_when_mounted", value, ref _sync_when_mounted); |
4050 | + } |
4051 | + } |
4052 | + |
4053 | + public uint? _last_sync_time = null; |
4054 | + public uint last_sync_time { |
4055 | + get { |
4056 | + common_uint_getter ("last_sync_time", ref _last_sync_time); |
4057 | + return _last_sync_time; |
4058 | + } |
4059 | + set { |
4060 | + common_uint_setter ("last_sync_time", value, ref _last_sync_time); |
4061 | + } |
4062 | + } |
4063 | + |
4064 | + public bool? _sync_music = null; |
4065 | + public bool sync_music { |
4066 | + get { |
4067 | + common_bool_getter ("sync_music", ref _sync_music); |
4068 | + return _sync_music; |
4069 | + } |
4070 | + set { |
4071 | + common_bool_setter ("sync_music", value, ref _sync_music); |
4072 | + } |
4073 | + } |
4074 | + |
4075 | + public bool? _sync_all_music = null; |
4076 | + public bool sync_all_music { |
4077 | + get { |
4078 | + common_bool_getter ("sync_all_music", ref _sync_all_music); |
4079 | + return _sync_all_music; |
4080 | + } |
4081 | + set { |
4082 | + common_bool_setter ("sync_all_music", value, ref _sync_all_music); |
4083 | + } |
4084 | + } |
4085 | + |
4086 | + public Playlist? music_playlist { |
4087 | + owned get { |
4088 | + var result = query_field ("music_playlist"); |
4089 | + if (result.type () == typeof (Gda.Null)) { |
4090 | + return null; |
4091 | + } |
4092 | + |
4093 | + string playlist_string = result.get_string (); |
4094 | + if (playlist_string == "" || playlist_string == null) |
4095 | + return null; |
4096 | + if ("p" in playlist_string) { |
4097 | + playlist_string = playlist_string.replace ("p", ""); |
4098 | + return Noise.libraries_manager.local_library.playlist_from_id (int64.parse (playlist_string)); |
4099 | + } else { |
4100 | + playlist_string = playlist_string.replace ("s", ""); |
4101 | + return Noise.libraries_manager.local_library.smart_playlist_from_id (int64.parse (playlist_string)); |
4102 | + } |
4103 | + } |
4104 | + set { |
4105 | + string playlist_string = ""; |
4106 | + if (value != null) { |
4107 | + if (value is StaticPlaylist) { |
4108 | + playlist_string = "p%lld".printf (value.rowid); |
4109 | + } else { |
4110 | + playlist_string = "s%lld".printf (value.rowid); |
4111 | + } |
4112 | + } |
4113 | + |
4114 | + set_field ("music_playlist", Database.make_string_value (playlist_string)); |
4115 | + } |
4116 | + } |
4117 | + |
4118 | + private Gda.Connection connection; |
4119 | + |
4120 | + public DevicePreferences (Noise.Device device, Gda.Connection connection) { |
4121 | + this.id = device.get_unique_identifier (); |
4122 | + this.connection = connection; |
4123 | + if (query_field ("sync_music") == null) { |
4124 | + try { |
4125 | + var builder = new Gda.SqlBuilder (Gda.SqlStatementType.INSERT); |
4126 | + builder.set_table (Database.Devices.TABLE_NAME); |
4127 | + builder.add_field_value_as_gvalue ("unique_id", Database.make_string_value (id)); |
4128 | + connection.statement_execute_non_select (builder.get_statement (), null, null); |
4129 | + } catch (Error e) { |
4130 | + warning ("Could not save media: %s", e.message); |
4131 | + } |
4132 | + } |
4133 | + } |
4134 | + |
4135 | + private uint common_uint_getter (string field, ref uint? temp) { |
4136 | + if (temp != null) |
4137 | + return temp; |
4138 | + |
4139 | + var result = query_field (field); |
4140 | + if (result.type () == typeof (Gda.Null)) { |
4141 | + temp = 0; |
4142 | + return temp; |
4143 | + } |
4144 | + |
4145 | + temp = (uint)result.get_int (); |
4146 | + return temp; |
4147 | + } |
4148 | + |
4149 | + private void common_uint_setter (string field, uint value, ref uint? temp) { |
4150 | + temp = value; |
4151 | + set_field (field, Database.make_uint_value (value)); |
4152 | + } |
4153 | + |
4154 | + private bool common_bool_getter (string field, ref bool? temp) { |
4155 | + if (temp != null) |
4156 | + return temp; |
4157 | + |
4158 | + var result = query_field (field); |
4159 | + if (result.type () == typeof (Gda.Null)) { |
4160 | + temp = false; |
4161 | + return temp; |
4162 | + } |
4163 | + |
4164 | + temp = result.get_int () == 1; |
4165 | + return temp; |
4166 | + } |
4167 | + |
4168 | + private void common_bool_setter (string field, bool value, ref bool? temp) { |
4169 | + temp = value; |
4170 | + set_field (field, Database.make_bool_value (value)); |
4171 | + } |
4172 | + |
4173 | + private GLib.Value? query_field (string field) { |
4174 | + try { |
4175 | + var sql = new Gda.SqlBuilder (Gda.SqlStatementType.SELECT); |
4176 | + sql.select_add_target (Database.Devices.TABLE_NAME, null); |
4177 | + sql.add_field_value_id (sql.add_id (field), 0); |
4178 | + var id_field = sql.add_id ("unique_id"); |
4179 | + var id_param = sql.add_expr_value (null, Database.make_string_value (id)); |
4180 | + var id_cond = sql.add_cond (Gda.SqlOperatorType.EQ, id_field, id_param, 0); |
4181 | + sql.set_where (id_cond); |
4182 | + var data_model = connection.statement_execute_select (sql.get_statement (), null); |
4183 | + return data_model.get_value_at (data_model.get_column_index (field), 0); |
4184 | + } catch (Error e) { |
4185 | + critical ("Could not query field %s: %s", field, e.message); |
4186 | + return null; |
4187 | + } |
4188 | + } |
4189 | + |
4190 | + private void set_field (string field, GLib.Value value) { |
4191 | + try { |
4192 | + var col_names = new GLib.SList<string> (); |
4193 | + col_names.append (field); |
4194 | + var values = new GLib.SList<GLib.Value?> (); |
4195 | + values.append (value); |
4196 | + connection.update_row_in_table_v (Database.Devices.TABLE_NAME, "unique_id", Database.make_string_value (id), col_names, values); |
4197 | + } catch (Error e) { |
4198 | + critical ("Could not set field %s: %s", field, e.message); |
4199 | + } |
4200 | + } |
4201 | } |
4202 | |
4203 | === modified file 'src/LocalBackend/LocalLibrary.vala' |
4204 | --- src/LocalBackend/LocalLibrary.vala 2015-06-12 13:31:55 +0000 |
4205 | +++ src/LocalBackend/LocalLibrary.vala 2015-08-27 10:21:27 +0000 |
4206 | @@ -36,16 +36,13 @@ |
4207 | * the visual representation of this class |
4208 | */ |
4209 | public class Noise.LocalLibrary : Library { |
4210 | - public DataBaseUpdater dbu; |
4211 | - |
4212 | private FileOperator fo; |
4213 | private GStreamerTagger tagger; |
4214 | |
4215 | private Gee.TreeSet<StaticPlaylist> _playlists; |
4216 | private Gee.TreeSet<SmartPlaylist> _smart_playlists; |
4217 | - private Gee.TreeSet<Media> _medias; |
4218 | + private Gee.HashMap<int64?, Media> _medias; |
4219 | private Gee.TreeSet<Media> _searched_medias; |
4220 | - private int playlists_rowid = 0; |
4221 | |
4222 | public StaticPlaylist p_music; |
4223 | |
4224 | @@ -54,64 +51,109 @@ |
4225 | } |
4226 | |
4227 | private Gee.TreeSet<Media> open_media_list; |
4228 | - |
4229 | private bool _doing_file_operations = false; |
4230 | |
4231 | + public Gda.Connection connection { public get; private set; } |
4232 | + private Gda.SqlParser parser; |
4233 | + |
4234 | + private static const string DB_FILE = "database_0_3_1"; |
4235 | + |
4236 | public LocalLibrary () { |
4237 | libraries_manager.local_library = this; |
4238 | _playlists = new Gee.TreeSet<StaticPlaylist> (); |
4239 | _smart_playlists = new Gee.TreeSet<SmartPlaylist> (); |
4240 | - _medias = new Gee.TreeSet<Media> (); |
4241 | + _medias = new Gee.HashMap<int64?, Media> ((Gee.HashDataFunc<int64?>)GLib.int64_hash, |
4242 | + (Gee.EqualDataFunc<int64?>?)GLib.int64_equal, null); |
4243 | _searched_medias = new Gee.TreeSet<Media> (); |
4244 | tagger = new GStreamerTagger(); |
4245 | open_media_list = new Gee.TreeSet<Media> (); |
4246 | p_music = new StaticPlaylist (); |
4247 | p_music.name = MUSIC_PLAYLIST; |
4248 | |
4249 | - this.dbu = new DataBaseUpdater (); |
4250 | this.fo = new FileOperator (); |
4251 | } |
4252 | |
4253 | public override void initialize_library () { |
4254 | - var dbm = DataBaseManager.get_default (); |
4255 | + init_database (); |
4256 | fo.connect_to_manager (); |
4257 | + |
4258 | // Load all media from database |
4259 | - lock (_medias) { |
4260 | - foreach (var m in dbm.load_media ()) { |
4261 | - _medias.add (m); |
4262 | - } |
4263 | + var media_ids = get_rowids_from_table (Database.Media.TABLE_NAME); |
4264 | + foreach (var media_id in media_ids) { |
4265 | + var m = new LocalMedia (media_id, connection); |
4266 | + _medias.set (m.rowid, m); |
4267 | } |
4268 | |
4269 | - // Load smart playlists from database |
4270 | - lock (_smart_playlists) { |
4271 | - foreach (var p in dbm.load_smart_playlists ()) { |
4272 | - _smart_playlists.add (p); |
4273 | - p.rowid = playlists_rowid; |
4274 | - playlists_rowid++; |
4275 | - p.updated.connect ((old_name) => {smart_playlist_updated (p, old_name);}); |
4276 | - } |
4277 | + // Load all smart playlists from database |
4278 | + var sp_ids = get_rowids_from_table (Database.SmartPlaylists.TABLE_NAME); |
4279 | + foreach (var sp_id in sp_ids) { |
4280 | + var sp = new LocalSmartPlaylist (sp_id, connection); |
4281 | + _smart_playlists.add (sp); |
4282 | } |
4283 | |
4284 | // Load all static playlists from database |
4285 | - |
4286 | - lock (_playlists) { |
4287 | - foreach (var p in dbm.load_playlists ()) { |
4288 | - if (p.name == C_("Name of the playlist", "Queue") || p.name == _("History")) { |
4289 | - continue; |
4290 | - } else if (p.name != MUSIC_PLAYLIST) { |
4291 | - _playlists.add (p); |
4292 | - p.rowid = playlists_rowid; |
4293 | - playlists_rowid++; |
4294 | - p.updated.connect ((old_name) => {playlist_updated (p, old_name);}); |
4295 | - continue; |
4296 | - } |
4297 | - } |
4298 | + var p_ids = get_rowids_from_table (Database.Playlists.TABLE_NAME); |
4299 | + foreach (var p_id in p_ids) { |
4300 | + var p = new LocalStaticPlaylist (p_id, connection); |
4301 | + _playlists.add (p); |
4302 | } |
4303 | |
4304 | - DeviceManager.get_default ().set_device_preferences (dbm.load_devices ()); |
4305 | load_media_art_cache.begin (); |
4306 | } |
4307 | |
4308 | + /* |
4309 | + * Database interaction |
4310 | + */ |
4311 | + private void init_database () { |
4312 | + var database_dir = FileUtils.get_data_directory (); |
4313 | + try { |
4314 | + database_dir.make_directory_with_parents (null); |
4315 | + } catch (GLib.Error err) { |
4316 | + if (err is IOError.EXISTS == false) |
4317 | + error ("Could not create data directory: %s", err.message); |
4318 | + } |
4319 | + |
4320 | + var db_file = database_dir.get_child (DB_FILE + ".db"); |
4321 | + bool new_db = !db_file.query_exists (); |
4322 | + if (new_db) { |
4323 | + try { |
4324 | + db_file.create (FileCreateFlags.PRIVATE); |
4325 | + } catch (Error e) { |
4326 | + critical ("Error: %s", e.message); |
4327 | + } |
4328 | + } |
4329 | + |
4330 | + try { |
4331 | + connection = new Gda.Connection.from_string ("SQLite", "DB_DIR=%s;DB_NAME=%s".printf (database_dir.get_path (), DB_FILE), null, Gda.ConnectionOptions.NONE); |
4332 | + connection.open (); |
4333 | + } catch (Error e) { |
4334 | + error (e.message); |
4335 | + } |
4336 | + |
4337 | + parser = connection.create_parser (); |
4338 | + |
4339 | + if (new_db) { |
4340 | + load_table (Database.Tables.PLAYLISTS); |
4341 | + load_table (Database.Tables.SMART_PLAYLISTS); |
4342 | + load_table (Database.Tables.COLUMNS); |
4343 | + load_table (Database.Tables.MEDIA); |
4344 | + load_table (Database.Tables.DEVICES); |
4345 | + LocalSmartPlaylist.add_defaults (connection); |
4346 | + } |
4347 | + } |
4348 | + |
4349 | + private void load_table (string table) { |
4350 | + try { |
4351 | + var statement = parser.parse_string (table, null); |
4352 | + connection.statement_execute_non_select (statement, null, null); |
4353 | + } catch (Error e) { |
4354 | + critical (e.message); |
4355 | + } |
4356 | + } |
4357 | + |
4358 | + /* |
4359 | + * Media art utilities. |
4360 | + */ |
4361 | private async void load_media_art_cache () { |
4362 | lock (_medias) { |
4363 | yield CoverartCache.instance.load_for_media_async (get_medias ()); |
4364 | @@ -135,7 +177,7 @@ |
4365 | } |
4366 | |
4367 | public void remove_all_static_playlists () { |
4368 | - var list = new Gee.TreeSet<int> (); |
4369 | + var list = new Gee.TreeSet<int64?> (); |
4370 | lock (_playlists) { |
4371 | foreach (var p in _playlists) { |
4372 | if (p.read_only == false) |
4373 | @@ -158,9 +200,8 @@ |
4374 | |
4375 | clear_medias (); |
4376 | |
4377 | - App.player.unqueue_media (_medias); |
4378 | + App.player.unqueue_media (_medias.values); |
4379 | |
4380 | - App.player.reset_already_played (); |
4381 | // FIXME: these are library window's internals. Shouldn't be here |
4382 | App.main_window.update_sensitivities.begin (); |
4383 | App.player.stop_playback (); |
4384 | @@ -339,7 +380,7 @@ |
4385 | return result; |
4386 | } |
4387 | |
4388 | - public override StaticPlaylist? playlist_from_id (int id) { |
4389 | + public override StaticPlaylist? playlist_from_id (int64 id) { |
4390 | lock (_playlists) { |
4391 | foreach (var p in get_playlists ()) { |
4392 | if (p.rowid == id) { |
4393 | @@ -367,34 +408,54 @@ |
4394 | } |
4395 | |
4396 | public override void add_playlist (StaticPlaylist p) { |
4397 | - lock (_playlists) { |
4398 | - _playlists.add (p); |
4399 | - } |
4400 | - p.rowid = playlists_rowid; |
4401 | - playlists_rowid++; |
4402 | - p.updated.connect ((old_name) => {playlist_updated (p, old_name);}); |
4403 | - DataBaseManager.get_default ().add_playlist (p); |
4404 | - playlist_added (p); |
4405 | - debug ("playlist %s added",p.name); |
4406 | + string rv = ""; |
4407 | + foreach (var m in p.medias) { |
4408 | + if (rv == "") { |
4409 | + rv = "%lld".printf (m.rowid); |
4410 | + } else { |
4411 | + rv += ";%lld".printf (m.rowid); |
4412 | + } |
4413 | + } |
4414 | + |
4415 | + try { |
4416 | + var builder = new Gda.SqlBuilder (Gda.SqlStatementType.INSERT); |
4417 | + builder.set_table (Database.Playlists.TABLE_NAME); |
4418 | + builder.add_field_value_as_gvalue ("name", Database.make_string_value (p.name)); |
4419 | + builder.add_field_value_as_gvalue ("media", Database.make_string_value (rv)); |
4420 | + var statement = builder.get_statement (); |
4421 | + Gda.Set last_insert_row; |
4422 | + connection.statement_execute_non_select (statement, null, out last_insert_row); |
4423 | + var local_p = new LocalStaticPlaylist (last_insert_row.get_holder_value (Database.Playlists.ROWID).get_int64 (), connection); |
4424 | + |
4425 | + lock (_playlists) { |
4426 | + _playlists.add (local_p); |
4427 | + } |
4428 | + |
4429 | + playlist_added (local_p); |
4430 | + debug ("playlist %s added", local_p.name); |
4431 | + } catch (Error e) { |
4432 | + critical (e.message); |
4433 | + } |
4434 | } |
4435 | |
4436 | - public override void remove_playlist (int id) { |
4437 | + public override void remove_playlist (int64 id) { |
4438 | lock (_playlists) { |
4439 | foreach (var playlist in get_playlists ()) { |
4440 | if (playlist.rowid == id) { |
4441 | _playlists.remove (playlist); |
4442 | - dbu.removeItem.begin (playlist); |
4443 | playlist_removed (playlist); |
4444 | break; |
4445 | } |
4446 | } |
4447 | + |
4448 | + try { |
4449 | + connection.delete_row_from_table (Database.Playlists.TABLE_NAME, "rowid", Database.make_int64_value (id)); |
4450 | + } catch (Error e) { |
4451 | + critical (e.message); |
4452 | + } |
4453 | } |
4454 | } |
4455 | |
4456 | - public void playlist_updated (StaticPlaylist p, string? old_name = null) { |
4457 | - dbu.save_playlist (p, old_name); |
4458 | - } |
4459 | - |
4460 | /* |
4461 | * Smart playlists |
4462 | */ |
4463 | @@ -409,7 +470,7 @@ |
4464 | return result; |
4465 | } |
4466 | |
4467 | - public override SmartPlaylist? smart_playlist_from_id (int id) { |
4468 | + public override SmartPlaylist? smart_playlist_from_id (int64 id) { |
4469 | lock (_smart_playlists) { |
4470 | foreach (var p in get_smart_playlists ()) { |
4471 | if (p.rowid == id) { |
4472 | @@ -433,69 +494,133 @@ |
4473 | return null; |
4474 | } |
4475 | |
4476 | - public async void save_smart_playlists () { |
4477 | - lock (_smart_playlists) { |
4478 | - DataBaseManager.get_default ().save_smart_playlists (get_smart_playlists ()); |
4479 | - } |
4480 | - } |
4481 | - |
4482 | public override void add_smart_playlist (SmartPlaylist p) { |
4483 | - lock (_smart_playlists) { |
4484 | - _smart_playlists.add (p); |
4485 | + try { |
4486 | + var builder = new Gda.SqlBuilder (Gda.SqlStatementType.INSERT); |
4487 | + builder.set_table (Database.SmartPlaylists.TABLE_NAME); |
4488 | + builder.add_field_value_as_gvalue ("name", Database.make_string_value (p.name)); |
4489 | + var statement = builder.get_statement (); |
4490 | + Gda.Set last_insert_row; |
4491 | + connection.statement_execute_non_select (statement, null, out last_insert_row); |
4492 | + if (last_insert_row != null) { |
4493 | + var local_sp = new LocalSmartPlaylist (last_insert_row.get_holder_value (Database.SmartPlaylists.ROWID).get_int64 (), connection); |
4494 | + local_sp.conditional = p.conditional; |
4495 | + local_sp.limit = p.limit; |
4496 | + local_sp.limit_amount = p.limit_amount; |
4497 | + local_sp.add_queries (p.get_queries ()); |
4498 | + |
4499 | + lock (_smart_playlists) { |
4500 | + _smart_playlists.add (local_sp); |
4501 | + } |
4502 | + |
4503 | + smartplaylist_added (local_sp); |
4504 | + } |
4505 | + } catch (Error e) { |
4506 | + critical (e.message); |
4507 | } |
4508 | - |
4509 | - p.rowid = playlists_rowid; |
4510 | - playlists_rowid++; |
4511 | - DataBaseManager.get_default ().save_smart_playlist (p); |
4512 | - p.updated.connect ((old_name) => {smart_playlist_updated (p, old_name);}); |
4513 | - smartplaylist_added (p); |
4514 | } |
4515 | |
4516 | - public override void remove_smart_playlist (int id) { |
4517 | + public override void remove_smart_playlist (int64 id) { |
4518 | lock (_smart_playlists) { |
4519 | foreach (var p in get_smart_playlists ()) { |
4520 | if (p.rowid == id) { |
4521 | _smart_playlists.remove (p); |
4522 | smartplaylist_removed (p); |
4523 | - dbu.removeItem.begin (p); |
4524 | break; |
4525 | } |
4526 | } |
4527 | } |
4528 | - } |
4529 | - |
4530 | - public void smart_playlist_updated (SmartPlaylist p, string? old_name = null) { |
4531 | - dbu.save_smart_playlist (p, old_name); |
4532 | - } |
4533 | + |
4534 | + try { |
4535 | + connection.delete_row_from_table (Database.SmartPlaylists.TABLE_NAME, "rowid", Database.make_int64_value (id)); |
4536 | + } catch (Error e) { |
4537 | + critical (e.message); |
4538 | + } |
4539 | + } |
4540 | + |
4541 | |
4542 | /******************** Media stuff ******************/ |
4543 | |
4544 | public override void search_medias (string search) { |
4545 | - lock (_searched_medias) { |
4546 | - _searched_medias.clear (); |
4547 | - if (search == "") { |
4548 | - _searched_medias.add_all (_medias); |
4549 | - search_finished (); |
4550 | - return; |
4551 | - } |
4552 | - |
4553 | - int parsed_rating; |
4554 | - string parsed_search_string; |
4555 | - String.base_search_method (search, out parsed_rating, out parsed_search_string); |
4556 | - bool rating_search = parsed_rating > 0; |
4557 | - lock (_medias) { |
4558 | - foreach (var m in _medias) { |
4559 | - if (rating_search) { |
4560 | - if (m.rating == (uint) parsed_rating) |
4561 | - _searched_medias.add (m); |
4562 | - } else if (Search.match_string_to_media (m, parsed_search_string)) { |
4563 | - _searched_medias.add (m); |
4564 | - } |
4565 | - } |
4566 | - } |
4567 | - } |
4568 | - |
4569 | - search_finished (); |
4570 | + if (search == "") { |
4571 | + lock (_searched_medias) { |
4572 | + _searched_medias.clear (); |
4573 | + _searched_medias.add_all (_medias.values); |
4574 | + } |
4575 | + search_finished (); |
4576 | + return; |
4577 | + } |
4578 | + |
4579 | + uint parsed_rating; |
4580 | + string parsed_search_string; |
4581 | + String.base_search_method (search, out parsed_rating, out parsed_search_string); |
4582 | + bool rating_search = parsed_rating > 0; |
4583 | + // If we search for a special rating, don't search for something else. |
4584 | + try { |
4585 | + if (parsed_rating > 0) { |
4586 | + var sql = new Gda.SqlBuilder (Gda.SqlStatementType.SELECT); |
4587 | + sql.select_add_target (Database.Media.TABLE_NAME, null); |
4588 | + sql.select_add_field ("rowid", null, null); |
4589 | + var id_field = sql.add_id ("rating"); |
4590 | + var id_value = sql.add_expr_value (null, Database.make_uint_value (parsed_rating)); |
4591 | + var id_cond = sql.add_cond (Gda.SqlOperatorType.GEQ, id_field, id_value, 0); |
4592 | + sql.set_where (id_cond); |
4593 | + |
4594 | + var statm = sql.get_statement (); |
4595 | + var data_model = connection.statement_execute_select (statm, null); |
4596 | + var data_model_iter = data_model.create_iter (); |
4597 | + data_model_iter.move_to_row (-1); |
4598 | + var rowids = new Gee.TreeSet<int64?> (); |
4599 | + while (data_model_iter.move_next ()) { |
4600 | + unowned Value? val = data_model_iter.get_value_at (0); |
4601 | + rowids.add (val.get_int64 ()); |
4602 | + } |
4603 | + |
4604 | + var meds = medias_from_ids (rowids); |
4605 | + lock (_searched_medias) { |
4606 | + _searched_medias.clear (); |
4607 | + _searched_medias.add_all (meds); |
4608 | + } |
4609 | + } else { |
4610 | + var sql = new Gda.SqlBuilder (Gda.SqlStatementType.SELECT); |
4611 | + sql.select_add_target (Database.Media.TABLE_NAME, null); |
4612 | + sql.select_add_field ("rowid", null, null); |
4613 | + Gda.SqlBuilderId[] ids = null; |
4614 | + |
4615 | + string[] fields = {"title", "artist", "composer", "album_artist", "album", "grouping", "comment"}; |
4616 | + foreach (var field in fields) { |
4617 | + var id_field = sql.add_id (field); |
4618 | + var id_value = sql.add_expr_value (null, Database.make_string_value ("%"+search+"%")); |
4619 | + ids += sql.add_cond (Gda.SqlOperatorType.LIKE, id_field, id_value, 0); |
4620 | + } |
4621 | + |
4622 | + var id_cond = sql.add_cond_v (Gda.SqlOperatorType.OR, ids); |
4623 | + sql.set_where (id_cond); |
4624 | + |
4625 | + var statm = sql.get_statement (); |
4626 | + var data_model = connection.statement_execute_select (statm, null); |
4627 | + var data_model_iter = data_model.create_iter (); |
4628 | + data_model_iter.move_to_row (-1); |
4629 | + var rowids = new Gee.TreeSet<int64?> (); |
4630 | + while (data_model_iter.move_next ()) { |
4631 | + unowned Value? val = data_model_iter.get_value_at (0); |
4632 | + rowids.add (val.get_int64 ()); |
4633 | + } |
4634 | + |
4635 | + var meds = medias_from_ids (rowids); |
4636 | + lock (_searched_medias) { |
4637 | + _searched_medias.clear (); |
4638 | + _searched_medias.add_all (meds); |
4639 | + } |
4640 | + } |
4641 | + } catch (Error e) { |
4642 | + critical ("Could not search for %s: %s", search, e.message); |
4643 | + } |
4644 | + |
4645 | + Idle.add (() => { |
4646 | + search_finished (); |
4647 | + return GLib.Source.REMOVE; |
4648 | + }); |
4649 | } |
4650 | |
4651 | public override Gee.Collection<Media> get_search_result () { |
4652 | @@ -510,7 +635,7 @@ |
4653 | // We really only want to clear the songs that are permanent and on the file system |
4654 | // Dont clear podcasts that link to a url, device media, temporary media, previews, songs |
4655 | var unset = new Gee.LinkedList<Media> (); |
4656 | - foreach (var s in _medias) { |
4657 | + foreach (var s in _medias.values) { |
4658 | if (!s.isTemporary && !s.isPreview) |
4659 | unset.add (s); |
4660 | } |
4661 | @@ -521,7 +646,7 @@ |
4662 | |
4663 | public override Gee.Collection<Media> get_medias () { |
4664 | var result = new Gee.TreeSet<Media> (); |
4665 | - result.add_all (_medias); |
4666 | + result.add_all (_medias.values); |
4667 | return result; |
4668 | } |
4669 | |
4670 | @@ -553,21 +678,14 @@ |
4671 | * consistency |
4672 | */ |
4673 | |
4674 | - public override Media? media_from_id (int id) { |
4675 | - lock (_medias) { |
4676 | - foreach (var m in _medias) { |
4677 | - if (m.rowid == id) |
4678 | - return m; |
4679 | - } |
4680 | - } |
4681 | - |
4682 | - return null; |
4683 | + public override Media? media_from_id (int64 id) { |
4684 | + return _medias.get (id); |
4685 | } |
4686 | |
4687 | public override Media? find_media (Media to_find) { |
4688 | Media? found = null; |
4689 | lock (_medias) { |
4690 | - foreach (var m in _medias) { |
4691 | + foreach (var m in _medias.values) { |
4692 | if (to_find.title.down () == m.title.down () && to_find.artist.down () == m.artist.down ()) { |
4693 | found = m; |
4694 | break; |
4695 | @@ -580,7 +698,7 @@ |
4696 | |
4697 | public override Media? media_from_file (File file) { |
4698 | lock (_medias) { |
4699 | - foreach (var m in _medias) { |
4700 | + foreach (var m in _medias.values) { |
4701 | if (m != null && m.file.equal (file)) |
4702 | return m; |
4703 | } |
4704 | @@ -591,7 +709,7 @@ |
4705 | |
4706 | public override Media? media_from_uri (string uri) { |
4707 | lock (_medias) { |
4708 | - foreach (var m in _medias) { |
4709 | + foreach (var m in _medias.values) { |
4710 | if (m != null && m.uri == uri) |
4711 | return m; |
4712 | } |
4713 | @@ -600,15 +718,12 @@ |
4714 | return null; |
4715 | } |
4716 | |
4717 | - public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int> ids) { |
4718 | + public override Gee.Collection<Media> medias_from_ids (Gee.Collection<int64?> ids) { |
4719 | var media_collection = new Gee.TreeSet<Media> (); |
4720 | - lock (_medias) { |
4721 | - foreach (var m in _medias) { |
4722 | - if (ids.contains (m.rowid)) |
4723 | - media_collection.add (m); |
4724 | - |
4725 | - if (media_collection.size == ids.size) |
4726 | - break; |
4727 | + foreach (var id in ids) { |
4728 | + var m = _medias.get (id); |
4729 | + if (m != null) { |
4730 | + media_collection.add (m); |
4731 | } |
4732 | } |
4733 | |
4734 | @@ -618,7 +733,7 @@ |
4735 | public override Gee.Collection<Media> medias_from_uris (Gee.Collection<string> uris) { |
4736 | var media_collection = new Gee.LinkedList<Media> (); |
4737 | lock (_medias) { |
4738 | - foreach (var m in _medias) { |
4739 | + foreach (var m in _medias.values) { |
4740 | if (uris.contains (m.uri)) |
4741 | media_collection.add (m); |
4742 | if (media_collection.size == uris.size) |
4743 | @@ -636,7 +751,7 @@ |
4744 | } |
4745 | |
4746 | public override void add_medias (Gee.Collection<Media> new_media) { |
4747 | - if (new_media.size < 1) // happens more often than you would think |
4748 | + if (new_media.is_empty) // happens more often than you would think |
4749 | return; |
4750 | |
4751 | // make a copy of the media list so that it doesn't get modified before |
4752 | @@ -644,21 +759,26 @@ |
4753 | var media = new Gee.TreeSet<Media> (); |
4754 | media.add_all (new_media); |
4755 | |
4756 | - var local_media = DataBaseManager.get_default ().add_media (media); |
4757 | - _medias.add_all (local_media); |
4758 | - media_added (local_media.read_only_view); |
4759 | + var local_media = new Gee.HashMap<int64?, LocalMedia> (); |
4760 | + foreach (var m in media) { |
4761 | + var local_m = new LocalMedia.from_media (connection, m); |
4762 | + local_media.set (local_m.rowid, local_m); |
4763 | + } |
4764 | + |
4765 | + _medias.set_all (local_media); |
4766 | + media_added (local_media.values.read_only_view); |
4767 | |
4768 | // Update search results |
4769 | if (App.main_window.searchField.text == "") { |
4770 | - _searched_medias.add_all (local_media); |
4771 | + _searched_medias.add_all (local_media.values); |
4772 | } else { |
4773 | - int parsed_rating; |
4774 | + uint parsed_rating; |
4775 | string parsed_search_string; |
4776 | String.base_search_method (App.main_window.searchField.text, out parsed_rating, out parsed_search_string); |
4777 | bool rating_search = parsed_rating > 0; |
4778 | - foreach (var m in local_media) { |
4779 | + foreach (var m in local_media.values) { |
4780 | if (rating_search) { |
4781 | - if (m.rating == (uint) parsed_rating) |
4782 | + if (m.rating == parsed_rating) |
4783 | _searched_medias.add (m); |
4784 | } else if (Search.match_string_to_media (m, parsed_search_string)) { |
4785 | _searched_medias.add (m); |
4786 | @@ -678,10 +798,8 @@ |
4787 | public override void remove_medias (Gee.Collection<Media> to_remove, bool trash) { |
4788 | var toRemove = new Gee.TreeSet<Media> (); |
4789 | toRemove.add_all (to_remove); |
4790 | - foreach (var s in toRemove) { |
4791 | - if (s == App.player.current_media) |
4792 | - App.player.stop_playback (); |
4793 | - } |
4794 | + if (App.player.current_media in toRemove) |
4795 | + App.player.stop_playback (); |
4796 | |
4797 | if (trash) |
4798 | fo.remove_media (toRemove); |
4799 | @@ -689,12 +807,11 @@ |
4800 | // Emit signal before actually removing the media because otherwise |
4801 | // media_from_id () and media_from_ids () wouldn't work. |
4802 | media_removed (toRemove.read_only_view); |
4803 | - dbu.removeItem.begin (toRemove); |
4804 | |
4805 | lock (_medias) { |
4806 | foreach (Media s in toRemove) { |
4807 | _searched_medias.remove (s); |
4808 | - _medias.remove (s); |
4809 | + _medias.unset (s.rowid); |
4810 | } |
4811 | } |
4812 | |
4813 | @@ -703,17 +820,25 @@ |
4814 | p.remove_medias (toRemove); |
4815 | } |
4816 | |
4817 | - DataBaseManager.get_default ().remove_media (toRemove); |
4818 | + foreach (var m in toRemove) { |
4819 | + try { |
4820 | + connection.delete_row_from_table (Database.Media.TABLE_NAME, "rowid", Database.make_int64_value (m.rowid)); |
4821 | + } catch (Error e) { |
4822 | + critical (e.message); |
4823 | + } |
4824 | + } |
4825 | + |
4826 | search_finished (); |
4827 | } |
4828 | |
4829 | public Gee.TreeSet<Noise.Media> answer_to_device_sync (Device device) { |
4830 | var medias_to_sync = new Gee.TreeSet<Noise.Media> (); |
4831 | - if (device.get_preferences ().sync_music == true) { |
4832 | - if (device.get_preferences ().sync_all_music == true) { |
4833 | + var prefs = get_preferences_for_device (device); |
4834 | + if (prefs.sync_music == true) { |
4835 | + if (prefs.sync_all_music == true) { |
4836 | medias_to_sync.add_all (get_medias ()); |
4837 | } else { |
4838 | - medias_to_sync.add_all (device.get_preferences ().music_playlist.medias); |
4839 | + medias_to_sync.add_all (prefs.music_playlist.medias); |
4840 | } |
4841 | } |
4842 | |
4843 | @@ -744,4 +869,35 @@ |
4844 | file_operations_done (); |
4845 | update_media_art_cache.begin (); |
4846 | } |
4847 | + |
4848 | + Gee.HashMap<string, DevicePreferences> preferences = new Gee.HashMap<string, DevicePreferences> ((Gee.HashDataFunc)GLib.str_hash, (Gee.EqualDataFunc)GLib.str_equal); |
4849 | + public DevicePreferences get_preferences_for_device (Device d) { |
4850 | + var key = d.get_unique_identifier (); |
4851 | + if (preferences.has_key (key)) { |
4852 | + return preferences.get (key); |
4853 | + } else { |
4854 | + var pref = new DevicePreferences (d, connection); |
4855 | + preferences.set (key, pref); |
4856 | + return pref; |
4857 | + } |
4858 | + } |
4859 | + |
4860 | + private Gee.Collection<int64?> get_rowids_from_table (string table_name) { |
4861 | + var ids = new Gee.TreeSet<int64?> (); |
4862 | + try { |
4863 | + var builder = new Gda.SqlBuilder (Gda.SqlStatementType.SELECT); |
4864 | + builder.select_add_target (table_name, null); |
4865 | + builder.select_add_field ("rowid", null, null); |
4866 | + var data_model = connection.statement_execute_select (builder.get_statement (), null); |
4867 | + for (int i = 0; i < data_model.get_n_rows (); i++) { |
4868 | + var rowid = data_model.get_value_at (data_model.get_column_index ("rowid"), i); |
4869 | + ids.add (rowid.get_int64 ()); |
4870 | + } |
4871 | + } catch (Error e) { |
4872 | + // TODO: Expose errors to the user ! |
4873 | + critical ("Could not query table %s : %s", table_name, e.message); |
4874 | + } |
4875 | + |
4876 | + return ids; |
4877 | + } |
4878 | } |
4879 | |
4880 | === modified file 'src/LocalBackend/LocalMedia.vala' |
4881 | --- src/LocalBackend/LocalMedia.vala 2015-02-24 18:16:35 +0000 |
4882 | +++ src/LocalBackend/LocalMedia.vala 2015-08-27 10:21:27 +0000 |
4883 | @@ -29,8 +29,6 @@ |
4884 | */ |
4885 | |
4886 | public class Noise.LocalMedia : Noise.Media { |
4887 | - private SQLHeavy.Database database = Noise.DataBaseManager.get_default ().database; |
4888 | - |
4889 | private uint64? _file_size = null; |
4890 | public override uint64 file_size { |
4891 | get { |
4892 | @@ -66,6 +64,7 @@ |
4893 | common_uint_setter ("track", value, ref _track); |
4894 | } |
4895 | } |
4896 | + |
4897 | private uint? _track_count = null; |
4898 | public override uint track_count { |
4899 | get { |
4900 | @@ -76,6 +75,7 @@ |
4901 | common_uint_setter ("track_count", value, ref _track_count); |
4902 | } |
4903 | } |
4904 | + |
4905 | private string _composer = null; |
4906 | public override string composer { |
4907 | get { |
4908 | @@ -86,6 +86,7 @@ |
4909 | common_string_setter ("composer", value, ref _composer); |
4910 | } |
4911 | } |
4912 | + |
4913 | private string _artist = null; |
4914 | public override string artist { |
4915 | get { |
4916 | @@ -96,6 +97,7 @@ |
4917 | common_string_setter ("artist", value, ref _artist); |
4918 | } |
4919 | } |
4920 | + |
4921 | private string _album_artist = null; |
4922 | public override string album_artist { |
4923 | get { |
4924 | @@ -106,6 +108,7 @@ |
4925 | common_string_setter ("album_artist", value, ref _album_artist); |
4926 | } |
4927 | } |
4928 | + |
4929 | private string _album = null; |
4930 | public override string album { |
4931 | get { |
4932 | @@ -116,6 +119,7 @@ |
4933 | common_string_setter ("album", value, ref _album); |
4934 | } |
4935 | } |
4936 | + |
4937 | private uint? _album_number = null; |
4938 | public override uint album_number { |
4939 | get { |
4940 | @@ -126,6 +130,7 @@ |
4941 | common_uint_setter ("album_number", value, ref _album_number); |
4942 | } |
4943 | } |
4944 | + |
4945 | private uint? _album_count = null; |
4946 | public override uint album_count { |
4947 | get { |
4948 | @@ -136,6 +141,7 @@ |
4949 | common_uint_setter ("album_count", value, ref _album_count); |
4950 | } |
4951 | } |
4952 | + |
4953 | public override unowned Album album_info { get; set; default = null; } |
4954 | private string _grouping = null; |
4955 | public override string grouping { |
4956 | @@ -147,6 +153,7 @@ |
4957 | common_string_setter ("grouping", value, ref _grouping); |
4958 | } |
4959 | } |
4960 | + |
4961 | private string _genre = null; |
4962 | public override string genre { |
4963 | get { |
4964 | @@ -157,6 +164,7 @@ |
4965 | common_string_setter ("genre", value, ref _genre); |
4966 | } |
4967 | } |
4968 | + |
4969 | private string _comment = null; |
4970 | public override string comment { |
4971 | get { |
4972 | @@ -167,6 +175,7 @@ |
4973 | common_string_setter ("comment", value, ref _comment); |
4974 | } |
4975 | } |
4976 | + |
4977 | private string _lyrics = null; |
4978 | public override string lyrics { |
4979 | get { |
4980 | @@ -177,6 +186,7 @@ |
4981 | common_string_setter ("lyrics", value, ref _lyrics); |
4982 | } |
4983 | } |
4984 | + |
4985 | public uint? _year = null; |
4986 | public override uint year { |
4987 | get { |
4988 | @@ -187,6 +197,7 @@ |
4989 | common_uint_setter ("year", value, ref _year); |
4990 | } |
4991 | } |
4992 | + |
4993 | public uint? _bitrate = null; |
4994 | public override uint bitrate { |
4995 | get { |
4996 | @@ -197,6 +208,7 @@ |
4997 | common_uint_setter ("bitrate", value, ref _bitrate); |
4998 | } |
4999 | } |
5000 | + |
So far my only real complaints (besides issues present in trunk ofc) are:
* The duplication in the history playlist.
* Making sure we restore with the last-played track
I'm on the look out for crashes or any other weirdness :D