Merge lp:~cando/gnome-activity-journal/audio_preview into lp:gnome-activity-journal
- audio_preview
- Merge into trunk
Status: | Merged |
---|---|
Merge reported by: | Seif Lotfy |
Merged at revision: | not available |
Proposed branch: | lp:~cando/gnome-activity-journal/audio_preview |
Merge into: | lp:gnome-activity-journal |
Diff against target: |
250 lines (+102/-10) 3 files modified
src/activity_widgets.py (+62/-9) src/common.py (+2/-1) src/supporting_widgets.py (+38/-0) |
To merge this branch: | bzr merge lp:~cando/gnome-activity-journal/audio_preview |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Seif Lotfy | Pending | ||
Review via email: mp+40342@code.launchpad.net |
Commit message
Description of the change
In this branch i've added the support for audio preview.
Stefano Candori (cando) wrote : | # |
Seif Lotfy (seif) wrote : | # |
ok cool
i wont read or work on code till thursday
mabye tehk or RainCT can merge it
On Mon, Nov 8, 2010 at 5:26 PM, Cando <email address hidden> wrote:
> ehm sorry...this diff also contains my other merge proposal(Drag and drop
> feature) as I worked on the same folder.
> I hope that is not a problem.
> --
>
> https:/
> Your team GNOME Zeitgeist Team is requested to review the proposed merge of
> lp:~cando/gnome-activity-journal/audio_preview into
> lp:gnome-activity-journal.
>
> _______
> Mailing list: https:/
> Post to : <email address hidden>
> Unsubscribe : https:/
> More help : https:/
>
--
This is me doing some advertisement for my blog http://
- 1127. By Stefano Candori
-
Fix ThumbView problem with "audio-x-generic" files
Seif Lotfy (seif) wrote : | # |
works flawlessly :)
Stefano Candori (cando) wrote : | # |
^^ awesome!
Preview Diff
1 | === modified file 'src/activity_widgets.py' | |||
2 | --- src/activity_widgets.py 2010-10-31 14:19:15 +0000 | |||
3 | +++ src/activity_widgets.py 2010-11-08 22:27:42 +0000 | |||
4 | @@ -6,6 +6,7 @@ | |||
5 | 6 | # Copyright © 2010 Randal Barlow <email.tehk@gmail.com> | 6 | # Copyright © 2010 Randal Barlow <email.tehk@gmail.com> |
6 | 7 | # Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com> | 7 | # Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com> |
7 | 8 | # Copyright © 2010 Markus Korn <thekorn@gmx.de> | 8 | # Copyright © 2010 Markus Korn <thekorn@gmx.de> |
8 | 9 | # Copyright © 2010 Stefano Candori <stefano.candori@gmail.com> | ||
9 | 9 | # | 10 | # |
10 | 10 | # This program is free software: you can redistribute it and/or modify | 11 | # This program is free software: you can redistribute it and/or modify |
11 | 11 | # it under the terms of the GNU General Public License as published by | 12 | # it under the terms of the GNU General Public License as published by |
12 | @@ -33,8 +34,8 @@ | |||
13 | 33 | import content_objects | 34 | import content_objects |
14 | 34 | from config import event_exists, settings, bookmarker, SUPPORTED_SOURCES | 35 | from config import event_exists, settings, bookmarker, SUPPORTED_SOURCES |
15 | 35 | from store import ContentStruct, CLIENT | 36 | from store import ContentStruct, CLIENT |
18 | 36 | from supporting_widgets import DayLabel, ContextMenu, StaticPreviewTooltip, VideoPreviewTooltip, SearchBox | 37 | from supporting_widgets import DayLabel, ContextMenu, StaticPreviewTooltip, VideoPreviewTooltip, SearchBox,\ |
19 | 37 | 38 | AudioPreviewTooltip | |
20 | 38 | from zeitgeist.datamodel import ResultType, StorageState, TimeRange | 39 | from zeitgeist.datamodel import ResultType, StorageState, TimeRange |
21 | 39 | 40 | ||
22 | 40 | 41 | ||
23 | @@ -454,6 +455,19 @@ | |||
24 | 454 | self.btn.connect("button_press_event", self._show_item_popup) | 455 | self.btn.connect("button_press_event", self._show_item_popup) |
25 | 455 | self.btn.connect("realize", self.realize_cb, evbox) | 456 | self.btn.connect("realize", self.realize_cb, evbox) |
26 | 456 | self.init_multimedia_tooltip() | 457 | self.init_multimedia_tooltip() |
27 | 458 | |||
28 | 459 | self.targets = [("text/uri-list", 0, 0)] | ||
29 | 460 | self.btn.drag_source_set( gtk.gdk.BUTTON1_MASK, self.targets, | ||
30 | 461 | gtk.gdk.ACTION_COPY) | ||
31 | 462 | self.btn.connect("drag_data_get", self.on_drag_data_get) | ||
32 | 463 | |||
33 | 464 | def on_drag_data_get(self, treeview, context, selection, target_id, etime): | ||
34 | 465 | uri = self.content_obj.uri | ||
35 | 466 | #FIXME for the moment we handle only files | ||
36 | 467 | if uri.startswith("file://"): | ||
37 | 468 | uri = uri.replace("%20"," ") | ||
38 | 469 | if os.path.exists(uri[7:]): | ||
39 | 470 | selection.set_uris([uri]) | ||
40 | 457 | 471 | ||
41 | 458 | def realize_cb(self, widget, evbox): | 472 | def realize_cb(self, widget, evbox): |
42 | 459 | evbox.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) | 473 | evbox.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2)) |
43 | @@ -470,12 +484,12 @@ | |||
44 | 470 | self.connect("query-tooltip", self._handle_tooltip) | 484 | self.connect("query-tooltip", self._handle_tooltip) |
45 | 471 | if "video-x-generic" in icon_names and gst is not None: | 485 | if "video-x-generic" in icon_names and gst is not None: |
46 | 472 | self.set_tooltip_window(VideoPreviewTooltip) | 486 | self.set_tooltip_window(VideoPreviewTooltip) |
47 | 487 | elif "audio-x-generic" in icon_names and gst is not None: | ||
48 | 488 | self.set_tooltip_window(AudioPreviewTooltip) | ||
49 | 473 | else: | 489 | else: |
50 | 474 | self.set_tooltip_window(StaticPreviewTooltip) | 490 | self.set_tooltip_window(StaticPreviewTooltip) |
51 | 475 | 491 | ||
52 | 476 | def _handle_tooltip(self, widget, x, y, keyboard_mode, tooltip): | 492 | def _handle_tooltip(self, widget, x, y, keyboard_mode, tooltip): |
53 | 477 | # nothing to do here, we always show the multimedia tooltip | ||
54 | 478 | # if we like video/sound preview later on we can start them here | ||
55 | 479 | tooltip_window = self.get_tooltip_window() | 493 | tooltip_window = self.get_tooltip_window() |
56 | 480 | return tooltip_window.preview(self.content_obj) | 494 | return tooltip_window.preview(self.content_obj) |
57 | 481 | 495 | ||
58 | @@ -649,8 +663,7 @@ | |||
59 | 649 | pass | 663 | pass |
60 | 650 | 664 | ||
61 | 651 | def on_activate(self, event, widget, path, background_area, cell_area, flags): | 665 | def on_activate(self, event, widget, path, background_area, cell_area, flags): |
64 | 652 | self.content_obj.launch() | 666 | pass |
63 | 653 | return True | ||
65 | 654 | 667 | ||
66 | 655 | 668 | ||
67 | 656 | class ThumbIconView(gtk.IconView): | 669 | class ThumbIconView(gtk.IconView): |
68 | @@ -667,9 +680,10 @@ | |||
69 | 667 | self.popupmenu = ContextMenu | 680 | self.popupmenu = ContextMenu |
70 | 668 | self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK) | 681 | self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK) |
71 | 669 | self.connect("button-press-event", self.on_button_press) | 682 | self.connect("button-press-event", self.on_button_press) |
72 | 683 | self.connect("button-release-event", self.on_button_release) | ||
73 | 670 | self.connect("motion-notify-event", self.on_motion_notify) | 684 | self.connect("motion-notify-event", self.on_motion_notify) |
74 | 671 | self.connect("leave-notify-event", self.on_leave_notify) | 685 | self.connect("leave-notify-event", self.on_leave_notify) |
76 | 672 | self.set_selection_mode(gtk.SELECTION_NONE) | 686 | self.set_selection_mode(gtk.SELECTION_SINGLE) |
77 | 673 | self.set_column_spacing(6) | 687 | self.set_column_spacing(6) |
78 | 674 | self.set_row_spacing(6) | 688 | self.set_row_spacing(6) |
79 | 675 | pcolumn = gtk.TreeViewColumn("Preview") | 689 | pcolumn = gtk.TreeViewColumn("Preview") |
80 | @@ -680,6 +694,11 @@ | |||
81 | 680 | SearchBox.connect("search", lambda *args: self.queue_draw()) | 694 | SearchBox.connect("search", lambda *args: self.queue_draw()) |
82 | 681 | SearchBox.connect("clear", lambda *args: self.queue_draw()) | 695 | SearchBox.connect("clear", lambda *args: self.queue_draw()) |
83 | 682 | 696 | ||
84 | 697 | self.targets = [("text/uri-list", 0, 0)] | ||
85 | 698 | self.drag_source_set(gtk.gdk.BUTTON1_MASK, self.targets, | ||
86 | 699 | gtk.gdk.ACTION_COPY) | ||
87 | 700 | self.connect("drag_data_get", self.on_drag_data_get) | ||
88 | 701 | |||
89 | 683 | def _set_model_in_thread(self, items): | 702 | def _set_model_in_thread(self, items): |
90 | 684 | """ | 703 | """ |
91 | 685 | A threaded which generates pixbufs and emblems for a list of events. | 704 | A threaded which generates pixbufs and emblems for a list of events. |
92 | @@ -714,6 +733,17 @@ | |||
93 | 714 | thread = threading.Thread(target=self._set_model_in_thread, args=(items,)) | 733 | thread = threading.Thread(target=self._set_model_in_thread, args=(items,)) |
94 | 715 | thread.start() | 734 | thread.start() |
95 | 716 | 735 | ||
96 | 736 | def on_drag_data_get(self, iconview, context, selection, target_id, etime): | ||
97 | 737 | model = iconview.get_model() | ||
98 | 738 | selected = iconview.get_selected_items() | ||
99 | 739 | content_object = model[selected[0]][0] | ||
100 | 740 | uri = content_object.uri | ||
101 | 741 | #FIXME for the moment we handle only files | ||
102 | 742 | if uri.startswith("file://"): | ||
103 | 743 | uri = uri.replace("%20"," ") | ||
104 | 744 | if os.path.exists(uri[7:]): | ||
105 | 745 | selection.set_uris([uri]) | ||
106 | 746 | |||
107 | 717 | def on_button_press(self, widget, event): | 747 | def on_button_press(self, widget, event): |
108 | 718 | if event.button == 3: | 748 | if event.button == 3: |
109 | 719 | val = self.get_item_at_pos(int(event.x), int(event.y)) | 749 | val = self.get_item_at_pos(int(event.x), int(event.y)) |
110 | @@ -722,7 +752,15 @@ | |||
111 | 722 | model = self.get_model() | 752 | model = self.get_model() |
112 | 723 | obj = model[path[0]][0] | 753 | obj = model[path[0]][0] |
113 | 724 | self.popupmenu.do_popup(event.time, [obj]) | 754 | self.popupmenu.do_popup(event.time, [obj]) |
115 | 725 | return False | 755 | |
116 | 756 | def on_button_release(self, widget, event): | ||
117 | 757 | if event.button == 1: | ||
118 | 758 | val = self.get_item_at_pos(int(event.x), int(event.y)) | ||
119 | 759 | if val: | ||
120 | 760 | path, cell = val | ||
121 | 761 | model = self.get_model() | ||
122 | 762 | obj = model[path[0]][0] | ||
123 | 763 | obj.launch() | ||
124 | 726 | 764 | ||
125 | 727 | def on_leave_notify(self, widget, event): | 765 | def on_leave_notify(self, widget, event): |
126 | 728 | try: | 766 | try: |
127 | @@ -740,7 +778,6 @@ | |||
128 | 740 | self.active_list[path[0]] = True | 778 | self.active_list[path[0]] = True |
129 | 741 | self.last_active = path[0] | 779 | self.last_active = path[0] |
130 | 742 | self.queue_draw() | 780 | self.queue_draw() |
131 | 743 | return True | ||
132 | 744 | 781 | ||
133 | 745 | def query_tooltip(self, widget, x, y, keyboard_mode, tooltip): | 782 | def query_tooltip(self, widget, x, y, keyboard_mode, tooltip): |
134 | 746 | """ | 783 | """ |
135 | @@ -1049,6 +1086,11 @@ | |||
136 | 1049 | SearchBox.connect("search", lambda *args: self.queue_draw()) | 1086 | SearchBox.connect("search", lambda *args: self.queue_draw()) |
137 | 1050 | SearchBox.connect("clear", lambda *args: self.queue_draw()) | 1087 | SearchBox.connect("clear", lambda *args: self.queue_draw()) |
138 | 1051 | 1088 | ||
139 | 1089 | self.targets = [("text/uri-list", 0, 0)] | ||
140 | 1090 | self.drag_source_set( gtk.gdk.BUTTON1_MASK, self.targets, | ||
141 | 1091 | gtk.gdk.ACTION_COPY) | ||
142 | 1092 | self.connect("drag_data_get", self.on_drag_data_get) | ||
143 | 1093 | |||
144 | 1052 | def set_model_from_list(self, items): | 1094 | def set_model_from_list(self, items): |
145 | 1053 | """ | 1095 | """ |
146 | 1054 | Sets creates/sets a model from a list of zeitgeist events | 1096 | Sets creates/sets a model from a list of zeitgeist events |
147 | @@ -1072,6 +1114,17 @@ | |||
148 | 1072 | items = day.get_time_map() | 1114 | items = day.get_time_map() |
149 | 1073 | self.set_model_from_list(items) | 1115 | self.set_model_from_list(items) |
150 | 1074 | 1116 | ||
151 | 1117 | def on_drag_data_get(self, treeview, context, selection, target_id, etime): | ||
152 | 1118 | tree_selection = treeview.get_selection() | ||
153 | 1119 | model, iter = tree_selection.get_selected() | ||
154 | 1120 | content_object = model.get_value(iter, 0) | ||
155 | 1121 | uri = content_object.uri | ||
156 | 1122 | #FIXME for the moment we handle only files | ||
157 | 1123 | if uri.startswith("file://"): | ||
158 | 1124 | uri = uri.replace("%20"," ") | ||
159 | 1125 | if os.path.exists(uri[7:]): | ||
160 | 1126 | selection.set_uris([uri]) | ||
161 | 1127 | |||
162 | 1075 | def on_button_press(self, widget, event): | 1128 | def on_button_press(self, widget, event): |
163 | 1076 | if event.button == 3: | 1129 | if event.button == 3: |
164 | 1077 | path = self.get_dest_row_at_pos(int(event.x), int(event.y)) | 1130 | path = self.get_dest_row_at_pos(int(event.x), int(event.y)) |
165 | 1078 | 1131 | ||
166 | === modified file 'src/common.py' | |||
167 | --- src/common.py 2010-10-30 18:41:28 +0000 | |||
168 | +++ src/common.py 2010-11-08 22:27:42 +0000 | |||
169 | @@ -635,7 +635,7 @@ | |||
170 | 635 | gfile = GioFile.create(uri) | 635 | gfile = GioFile.create(uri) |
171 | 636 | thumb = True | 636 | thumb = True |
172 | 637 | if gfile: | 637 | if gfile: |
174 | 638 | if gfile.has_preview(): | 638 | if gfile.has_preview() and "audio-x-generic" not in gfile.icon_names: |
175 | 639 | pb = gfile.get_thumbnail(size=size) | 639 | pb = gfile.get_thumbnail(size=size) |
176 | 640 | else: | 640 | else: |
177 | 641 | iconsize = int(size[0]*iconscale) | 641 | iconsize = int(size[0]*iconscale) |
178 | @@ -898,6 +898,7 @@ | |||
179 | 898 | is_opendocument = filter(lambda name: "application-vnd.oasis.opendocument" in name, icon_names) | 898 | is_opendocument = filter(lambda name: "application-vnd.oasis.opendocument" in name, icon_names) |
180 | 899 | return "video-x-generic" in icon_names \ | 899 | return "video-x-generic" in icon_names \ |
181 | 900 | or "image-x-generic" in icon_names \ | 900 | or "image-x-generic" in icon_names \ |
182 | 901 | or "audio-x-generic" in icon_names \ | ||
183 | 901 | or "application-pdf" in icon_names \ | 902 | or "application-pdf" in icon_names \ |
184 | 902 | or (("text-x-generic" in icon_names or "text-x-script" in icon_names) and pygments is not None) \ | 903 | or (("text-x-generic" in icon_names or "text-x-script" in icon_names) and pygments is not None) \ |
185 | 903 | or is_opendocument | 904 | or is_opendocument |
186 | 904 | 905 | ||
187 | === modified file 'src/supporting_widgets.py' | |||
188 | --- src/supporting_widgets.py 2010-10-30 18:41:28 +0000 | |||
189 | +++ src/supporting_widgets.py 2010-11-08 22:27:42 +0000 | |||
190 | @@ -6,6 +6,7 @@ | |||
191 | 6 | # Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com> | 6 | # Copyright © 2010 Siegfried Gevatter <siegfried@gevatter.com> |
192 | 7 | # Copyright © 2010 Markus Korn <thekorn@gmx.de> | 7 | # Copyright © 2010 Markus Korn <thekorn@gmx.de> |
193 | 8 | # Copyright © 2010 Randal Barlow <email.tehk@gmail.com> | 8 | # Copyright © 2010 Randal Barlow <email.tehk@gmail.com> |
194 | 9 | # Copyright © 2010 Stefano Candori <stefano.candori@gmail.com> | ||
195 | 9 | # | 10 | # |
196 | 10 | # This program is free software: you can redistribute it and/or modify | 11 | # This program is free software: you can redistribute it and/or modify |
197 | 11 | # it under the terms of the GNU General Public License as published by | 12 | # it under the terms of the GNU General Public License as published by |
198 | @@ -665,6 +666,41 @@ | |||
199 | 665 | finally: | 666 | finally: |
200 | 666 | gtk.gdk.threads_leave() | 667 | gtk.gdk.threads_leave() |
201 | 667 | 668 | ||
202 | 669 | class AudioPreviewTooltip(PreviewTooltip): | ||
203 | 670 | |||
204 | 671 | def __init__(self): | ||
205 | 672 | PreviewTooltip.__init__(self) | ||
206 | 673 | #hack:we don't need any window for audio_preview | ||
207 | 674 | self.set_default_size(0,0) | ||
208 | 675 | self.player = gst.element_factory_make("playbin2", "player") | ||
209 | 676 | fakesink = gst.element_factory_make("fakesink", "fakesink") | ||
210 | 677 | self.player.set_property("video-sink", fakesink) | ||
211 | 678 | bus = self.player.get_bus() | ||
212 | 679 | bus.add_signal_watch() | ||
213 | 680 | bus.connect("message", self.on_message) | ||
214 | 681 | self.connect("hide", self._handle_hide) | ||
215 | 682 | self.connect("show", self._handle_show) | ||
216 | 683 | |||
217 | 684 | def _handle_hide(self, widget): | ||
218 | 685 | self.player.set_state(gst.STATE_NULL) | ||
219 | 686 | |||
220 | 687 | def _handle_show(self, widget): | ||
221 | 688 | self.player.set_state(gst.STATE_PLAYING) | ||
222 | 689 | |||
223 | 690 | def preview(self, gio_file): | ||
224 | 691 | if gio_file.uri == self.player.get_property("uri"): | ||
225 | 692 | return True | ||
226 | 693 | self.player.set_property("uri", gio_file.uri) | ||
227 | 694 | return True | ||
228 | 695 | |||
229 | 696 | def on_message(self, bus, message): | ||
230 | 697 | t = message.type | ||
231 | 698 | if t == gst.MESSAGE_EOS: | ||
232 | 699 | self.player.set_state(gst.STATE_NULL) | ||
233 | 700 | elif t == gst.MESSAGE_ERROR: | ||
234 | 701 | self.player.set_state(gst.STATE_NULL) | ||
235 | 702 | err, debug = message.parse_error() | ||
236 | 703 | print "Error: %s" % err, debug | ||
237 | 668 | 704 | ||
238 | 669 | class AnimatedImage(gtk.Image): | 705 | class AnimatedImage(gtk.Image): |
239 | 670 | animating = None | 706 | animating = None |
240 | @@ -1453,8 +1489,10 @@ | |||
241 | 1453 | ### | 1489 | ### |
242 | 1454 | if gst is not None: | 1490 | if gst is not None: |
243 | 1455 | VideoPreviewTooltip = VideoPreviewTooltip() | 1491 | VideoPreviewTooltip = VideoPreviewTooltip() |
244 | 1492 | AudioPreviewTooltip = AudioPreviewTooltip() | ||
245 | 1456 | else: | 1493 | else: |
246 | 1457 | VideoPreviewTooltip = None | 1494 | VideoPreviewTooltip = None |
247 | 1495 | AudioPreviewTooltip = None | ||
248 | 1458 | StaticPreviewTooltip = StaticPreviewTooltip() | 1496 | StaticPreviewTooltip = StaticPreviewTooltip() |
249 | 1459 | ContextMenu = ContextMenu() | 1497 | ContextMenu = ContextMenu() |
250 | 1460 | SearchBox = SearchBox() | 1498 | SearchBox = SearchBox() |
ehm sorry...this diff also contains my other merge proposal(Drag and drop feature) as I worked on the same folder.
I hope that is not a problem.