Merge lp:~artem-anufrij/noise/Bugfix-1318871 into lp:~elementary-apps/noise/trunk
- Bugfix-1318871
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1693 |
Proposed branch: | lp:~artem-anufrij/noise/Bugfix-1318871 |
Merge into: | lp:~elementary-apps/noise/trunk |
Diff against target: |
317 lines (+117/-41) 4 files modified
src/FileOperator.vala (+1/-1) src/GStreamer/CoverImport.vala (+28/-25) src/Objects/CoverartCache.vala (+1/-1) src/Views/GridView/PopupListView.vala (+87/-14) |
To merge this branch: | bzr merge lp:~artem-anufrij/noise/Bugfix-1318871 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cody Garver (community) | Needs Fixing | ||
Victor Martinez (community) | Needs Information | ||
Review via email: mp+235540@code.launchpad.net |
Commit message
Allow changing the album art in the cache (not written to actual file yet)
Description of the change
- 1683. By artem-anufrij
-
code cleaning... sorry for spam
PerfectCarl (name-is-carl) wrote : | # |
Artem Anufrij (artem-anufrij) wrote : | # |
Sure! You are right!
Please check my changes!
Thank you for your feedback!
Danielle Foré (danrabbit) wrote : | # |
Okay maybe I'm stupid, but I can't figure out how to add/change the album art
Artem Anufrij (artem-anufrij) wrote : | # |
Hey Daniel,
look at this video:
https:/
Victor Martinez (victored) wrote : | # |
I think the bug report was about writing a cover art image to the metadata tags. I don't see any code for that here.
Artem Anufrij (artem-anufrij) wrote : | # |
It happens in the lines 271-306.
I hope I understand you correctly.
Victor Martinez (victored) wrote : | # |
The code is actually just writing the new image to ~/.cache/
These changes only affect the cover art displayed by Noise, and not the actual track metadata.
Artem Anufrij (artem-anufrij) wrote : | # |
> These changes only affect the cover art displayed by Noise, and not the actual
> track metadata.
Yes, its correct. I have the bug description so understood.
Cody Garver (codygarver) wrote : | # |
Needs trunk merged in and conflicts resolved
Code style violations throughout
Artem Anufrij (artem-anufrij) wrote : | # |
Gody,
do you want to merge this branch? IE3 tag will not be updated In my solution only the cover in ./chache/....
It's ok for you?
Artem Anufrij (artem-anufrij) wrote : | # |
I mean ID3-tag
Cody Garver (codygarver) wrote : | # |
Yeah it's still an improvement, just detach the bug
Preview Diff
1 | === modified file 'src/FileOperator.vala' |
2 | --- src/FileOperator.vala 2014-08-07 12:05:52 +0000 |
3 | +++ src/FileOperator.vala 2014-10-08 16:33:46 +0000 |
4 | @@ -387,4 +387,4 @@ |
5 | return false; |
6 | }); |
7 | } |
8 | -} |
9 | +} |
10 | \ No newline at end of file |
11 | |
12 | === modified file 'src/GStreamer/CoverImport.vala' |
13 | --- src/GStreamer/CoverImport.vala 2014-04-27 20:50:28 +0000 |
14 | +++ src/GStreamer/CoverImport.vala 2014-10-08 16:33:46 +0000 |
15 | @@ -21,7 +21,7 @@ |
16 | * Corentin Noël <tintou@mailoo.org> |
17 | */ |
18 | |
19 | -public class Noise.CoverImport : GLib.Object { |
20 | +public class Noise.CoverImport : GLib.Object { |
21 | private const int DISCOVER_SET_SIZE = 50; |
22 | private const int DISCOVERER_TIMEOUT_MS = 10; |
23 | |
24 | @@ -36,37 +36,40 @@ |
25 | original_queue = new Gee.LinkedList<Media> (); |
26 | } |
27 | |
28 | - private void file_set_finished () { |
29 | - if (cancelled) { |
30 | - debug ("import cancelled"); |
31 | - d.stop (); |
32 | - libraries_manager.local_library.media_imported (original_queue); |
33 | - original_queue.clear (); |
34 | - } else if (uri_queue.size == 0) { |
35 | - debug ("queue finished"); |
36 | - d.stop (); |
37 | - libraries_manager.local_library.media_imported (original_queue); |
38 | - original_queue.clear (); |
39 | - } else { |
40 | - import_next_file_set.begin (); |
41 | - } |
42 | - } |
43 | - |
44 | - private async void import_next_file_set () { |
45 | + private void initialize_discoverer () { |
46 | if (d == null) { |
47 | try { |
48 | d = new Gst.PbUtils.Discoverer ((Gst.ClockTime) (10 * Gst.SECOND)); |
49 | } catch (Error err) { |
50 | critical ("Could not create Gst discoverer object: %s", err.message); |
51 | } |
52 | - |
53 | d.discovered.connect (import_media); |
54 | d.finished.connect (file_set_finished); |
55 | } else { |
56 | d.stop (); |
57 | } |
58 | d.start (); |
59 | - |
60 | + } |
61 | + |
62 | + private void file_set_finished () { |
63 | + if (cancelled) { |
64 | + debug ("import cancelled"); |
65 | + d.stop (); |
66 | + libraries_manager.local_library.media_imported (original_queue); |
67 | + original_queue.clear (); |
68 | + } else if (uri_queue.size == 0) { |
69 | + debug ("queue finished"); |
70 | + d.stop (); |
71 | + libraries_manager.local_library.media_imported (original_queue); |
72 | + original_queue.clear (); |
73 | + } else { |
74 | + import_next_file_set.begin (); |
75 | + } |
76 | + } |
77 | + |
78 | + private async void import_next_file_set () { |
79 | + this.initialize_discoverer (); |
80 | + |
81 | for (int i = 0; i < DISCOVER_SET_SIZE; i++) { |
82 | bool not_found = true; |
83 | string uri = null; |
84 | @@ -79,7 +82,7 @@ |
85 | } |
86 | } |
87 | } |
88 | - |
89 | + |
90 | public void cancel_operations () { |
91 | cancelled = true; |
92 | } |
93 | @@ -163,7 +166,7 @@ |
94 | |
95 | if (gstreamer_discovery_successful) { |
96 | var m = libraries_manager.local_library.media_from_uri (uri); |
97 | - |
98 | + |
99 | // Get cover art |
100 | if (m != null) |
101 | yield import_art_async (m, info); |
102 | @@ -178,9 +181,9 @@ |
103 | |
104 | debug ("Importing cover art for: %s", info.get_uri ()); |
105 | |
106 | - var pix = get_image (info.get_tags ()); |
107 | - |
108 | - if (pix != null) |
109 | + var pix = get_image (info.get_tags ()); |
110 | + |
111 | + if (pix != null) |
112 | yield cache.cache_image_async (m, pix); |
113 | else |
114 | debug ("Could not find embedded image for '%s'", info.get_uri ()); |
115 | |
116 | === modified file 'src/Objects/CoverartCache.vala' |
117 | --- src/Objects/CoverartCache.vala 2013-08-17 04:38:12 +0000 |
118 | +++ src/Objects/CoverartCache.vala 2014-10-08 16:33:46 +0000 |
119 | @@ -223,4 +223,4 @@ |
120 | |
121 | return image_file; |
122 | } |
123 | -} |
124 | +} |
125 | \ No newline at end of file |
126 | |
127 | === modified file 'src/Views/GridView/PopupListView.vala' |
128 | --- src/Views/GridView/PopupListView.vala 2014-09-27 22:36:25 +0000 |
129 | +++ src/Views/GridView/PopupListView.vala 2014-10-08 16:33:46 +0000 |
130 | @@ -22,15 +22,18 @@ |
131 | public const int MIN_SIZE = 500; |
132 | |
133 | ViewWrapper view_wrapper; |
134 | - |
135 | + Gtk.Image album_cover; |
136 | Gtk.Label album_label; |
137 | Gtk.Label artist_label; |
138 | + |
139 | + Gtk.Menu cover_action_menu; |
140 | + Gtk.MenuItem cover_set_new; |
141 | + |
142 | Granite.Widgets.Rating rating; |
143 | - |
144 | GenericList list_view; |
145 | |
146 | Gee.Collection<Media> media_list; |
147 | - |
148 | + |
149 | public PopupListView (GridView grid_view) { |
150 | this.delete_event.connect (hide_on_delete); |
151 | window_position = Gtk.WindowPosition.CENTER_ON_PARENT; |
152 | @@ -42,10 +45,27 @@ |
153 | this.view_wrapper = grid_view.parent_view_wrapper; |
154 | |
155 | set_transient_for (App.main_window); |
156 | - App.main_window.close_subwindows.connect (() => {this.hide_on_delete ();}); |
157 | + App.main_window.close_subwindows.connect (() => { this.hide_on_delete (); }); |
158 | destroy_with_parent = true; |
159 | skip_taskbar_hint = true; |
160 | - |
161 | + |
162 | + // cover |
163 | + album_cover = new Gtk.Image (); |
164 | + album_cover.margin_left = album_cover.margin_bottom = 12; |
165 | + |
166 | + Gtk.EventBox cover_event_box = new Gtk.EventBox (); |
167 | + cover_event_box.add (album_cover); |
168 | + |
169 | + cover_action_menu = new Gtk.Menu (); |
170 | + |
171 | + cover_set_new = new Gtk.MenuItem.with_label (_("Set new album cover")); |
172 | + cover_set_new.activate.connect (() => { this.set_new_cover(); }); |
173 | + |
174 | + cover_action_menu.append (cover_set_new); |
175 | + cover_action_menu.show_all (); |
176 | + |
177 | + cover_event_box.button_press_event.connect (show_cover_context_menu); |
178 | + |
179 | // album artist/album labels |
180 | album_label = new Gtk.Label (""); |
181 | artist_label = new Gtk.Label (""); |
182 | @@ -82,12 +102,20 @@ |
183 | |
184 | // Add everything |
185 | Gtk.Box content = get_content_area () as Gtk.Box; |
186 | - content.pack_start (album_label, false, true, 0); |
187 | - content.pack_start (artist_label, false, true, 0); |
188 | + Gtk.Box header = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); |
189 | + Gtk.Box artist = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); |
190 | + |
191 | + artist.pack_start (artist_label, false, true, 0); |
192 | + artist.pack_start (album_label, false, true, 0); |
193 | + |
194 | + header.pack_start (cover_event_box, false, false); |
195 | + header.pack_start (artist, true, false); |
196 | + |
197 | + content.pack_start (header, false, true, 0); |
198 | content.pack_start (list_view_scrolled, true, true, 0); |
199 | - content.pack_start(rating, false, true, 0); |
200 | + content.pack_start (rating, false, true, 0); |
201 | |
202 | - rating.rating_changed.connect(rating_changed); |
203 | + rating.rating_changed.connect (rating_changed); |
204 | } |
205 | |
206 | /** |
207 | @@ -104,10 +132,19 @@ |
208 | media_list = new Gee.LinkedList<Media> (); |
209 | list_view.set_media (media_list); |
210 | |
211 | + album_cover.set_from_pixbuf (CoverartCache.instance.get_cover (new Media (""))); |
212 | + |
213 | // Reset size request |
214 | set_size (MIN_SIZE); |
215 | } |
216 | |
217 | + public bool show_cover_context_menu (Gtk.Widget sender, Gdk.EventButton evt) { |
218 | + if (evt.type == Gdk.EventType.BUTTON_PRESS && evt.button == 3) |
219 | + cover_action_menu.popup (null, null, null, evt.button, evt.time); |
220 | + |
221 | + return true; |
222 | + } |
223 | + |
224 | public void set_parent_wrapper (ViewWrapper parent_wrapper) { |
225 | this.view_wrapper = parent_wrapper; |
226 | this.list_view.set_parent_wrapper (parent_wrapper); |
227 | @@ -115,8 +152,8 @@ |
228 | |
229 | public void set_album (Album album) { |
230 | reset (); |
231 | - |
232 | - lock(media_list) { |
233 | + |
234 | + lock (media_list) { |
235 | |
236 | string name = album.get_display_name (); |
237 | string artist = album.get_display_artist (); |
238 | @@ -124,6 +161,8 @@ |
239 | string title_format = C_("Title format used on Album View Popup: $ALBUM by $ARTIST", "%s by %s"); |
240 | set_title (title_format.printf (name, artist)); |
241 | |
242 | + |
243 | + show_album_cover (CoverartCache.instance.get_album_cover (album)); |
244 | album_label.set_label (name); |
245 | artist_label.set_label (artist); |
246 | |
247 | @@ -137,7 +176,6 @@ |
248 | |
249 | // Search again to match the view wrapper's search |
250 | list_view.do_search (App.main_window.searchField.text); |
251 | - |
252 | } |
253 | |
254 | if (list_view.get_realized ()) |
255 | @@ -148,10 +186,16 @@ |
256 | view_wrapper.library.media_updated.connect (update_album_rating); |
257 | } |
258 | |
259 | + void show_album_cover (Gdk.Pixbuf pixbuf) |
260 | + { |
261 | + var cover_art_with_shadow = PixbufUtils.render_pixbuf_shadow (pixbuf); |
262 | + album_cover.set_from_pixbuf (cover_art_with_shadow); |
263 | + } |
264 | + |
265 | void update_album_rating () { |
266 | // We don't want to set the overall_rating as each media's rating. |
267 | // See rating_changed() in case you want to figure out what would happen. |
268 | - rating.rating_changed.disconnect(rating_changed); |
269 | + rating.rating_changed.disconnect (rating_changed); |
270 | |
271 | // Use average rating for the album |
272 | int total_rating = 0, n_media = 0; |
273 | @@ -173,7 +217,7 @@ |
274 | |
275 | void rating_changed (int new_rating) { |
276 | var updated = new Gee.LinkedList<Media> (); |
277 | - lock(media_list) { |
278 | + lock (media_list) { |
279 | |
280 | foreach (var media in media_list) { |
281 | if (media == null) |
282 | @@ -212,6 +256,35 @@ |
283 | } |
284 | } |
285 | } |
286 | + |
287 | + private void set_new_cover () |
288 | + { |
289 | + var file = new Gtk.FileChooserDialog (_("Open"), this, Gtk.FileChooserAction.OPEN, |
290 | + _("_Cancel"), Gtk.ResponseType.CANCEL, _("_Open"), Gtk.ResponseType.ACCEPT); |
291 | + |
292 | + var image_filter = new Gtk.FileFilter (); |
293 | + image_filter.set_filter_name (_("Image files")); |
294 | + image_filter.add_mime_type ("image/*"); |
295 | + |
296 | + file.add_filter (image_filter); |
297 | + |
298 | + if (file.run () == Gtk.ResponseType.ACCEPT) { |
299 | + Gdk.Pixbuf pix = null; |
300 | + try { |
301 | + pix = new Gdk.Pixbuf.from_file (file.get_filename ()); |
302 | + } catch (Error err) { |
303 | + debug ("Set new cover failed: %s", err.message); |
304 | + } |
305 | + |
306 | + if (pix != null) { |
307 | + CoverartCache cache = CoverartCache.instance; |
308 | + cache.changed.connect (() => { show_album_cover (cache.get_cover (media_list.to_array () [0])); }); |
309 | + cache.cache_image_async (media_list.to_array () [0], pix); |
310 | + } |
311 | + } |
312 | + |
313 | + file.destroy (); |
314 | + } |
315 | |
316 | /** |
317 | * Force squared layout |
The feature is very neat!
I don't know what the UI team thinks about it, but I like it.
That being said, I have remarks.
General
-------
Why did you use the CoverImporter and not the CoverCache?
You have the image for the album, so you don't need to re execute all the complicated cover import process but just to add the image to the cover cache and causes the album list to refresh.
Besides exposing the (now public) cover_importer is not a good idea.
It is best to simply add a new public method that would use the private member.
Formatting
----------
There must be a space between the function name and parenthesis.
my_function () ;