3 # This file is part of Jamaendo.
4 # Copyright (c) 2010 Kristoffer Gronlund
6 # Jamaendo is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # Jamaendo is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Jamaendo. If not, see <http://www.gnu.org/licenses/>.
19 # Player code heavily based on http://thpinfo.com/2008/panucci/:
20 # A resuming media player for Podcasts and Audiobooks
21 # Copyright (c) 2008-05-26 Thomas Perl <thpinfo.com>
22 # (based on http://pygstdocs.berlios.de/pygst-tutorial/seeking.html)
24 # Jamaendo jamendo.com API wrapper licensed under the New BSD License;
25 # see module for details.
33 from settings import settings
37 gobject.threads_init()
39 log = logging.getLogger(__name__)
46 if util.platform == 'maemo':
47 log.critical('Using GTK widgets, install "python2.5-hildon" '
48 'for this to work properly.')
50 log.critical('This ui (probably) only works in maemo')
51 import helldon as hildon
53 from dbus.mainloop.glib import DBusGMainLoop
55 DBusGMainLoop(set_as_default=True)
59 from postoffice import postoffice
60 from playerwindow import open_playerwindow
61 from search import SearchWindow
62 from featured import FeaturedWindow
63 from radios import RadiosWindow
64 from favorites import FavoritesWindow
65 from playlists import PlaylistsWindow
66 from listbox import ButtonListDialog
74 def create_window(self):
75 log.debug("Creating main window...")
76 self.app = hildon.Program()
77 self.window = hildon.StackableWindow()
78 self.app.add_window(self.window)
80 self.window.set_title("jamaendo")
82 self.window.connect("destroy", self.destroy)
84 self.CONFDIR = os.path.expanduser('~/MyDocs/.jamaendo')
85 jamaendo.set_cache_dir(self.CONFDIR)
86 settings.set_filename(os.path.join(self.CONFDIR, 'ui_settings'))
89 postoffice.connect('request-album-cover', self, self.on_request_cover)
90 postoffice.connect('request-images', self, self.on_request_images)
91 log.debug("Created main window.")
93 def create_menu(self):
94 self.menu = hildon.AppMenu()
96 #search = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
97 #search.set_label("Search")
98 #search.connect("clicked", self.on_search)
99 #self.menu.append(search)
101 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
102 player.set_label("Open player")
103 player.connect("clicked", self.on_player)
104 self.menu.append(player)
106 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
107 player.set_label("Favorites")
108 player.connect("clicked", self.on_favorites)
109 self.menu.append(player)
111 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
112 player.set_label("Playlists")
113 player.connect("clicked", self.on_playlists)
114 self.menu.append(player)
116 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
117 player.set_label("Settings")
118 player.connect("clicked", self.on_settings)
119 self.menu.append(player)
122 # Don't use localdb ATM
123 #refresh = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
124 #refresh.set_label("Refresh")
125 #refresh.connect("clicked", self.on_refresh)
126 #self.menu.append(refresh)
128 menu_about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
129 menu_about.set_label("About")
130 menu_about.connect("clicked", self.show_about, self.window)
131 self.menu.append(menu_about)
132 gtk.about_dialog_set_url_hook(self.open_link, None)
135 self.window.set_app_menu(self.menu)
138 def setup_widgets(self):
139 bgimg = util.find_resource('bg.png')
141 background, mask = gtk.gdk.pixbuf_new_from_file(bgimg).render_pixmap_and_mask()
142 self.window.realize()
143 self.window.window.set_back_pixmap(background, False)
145 bbox = gtk.HButtonBox()
146 alignment = gtk.Alignment(xalign=0.2, yalign=0.925, xscale=1.0)
148 bbox.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
150 self.window.add(alignment)
152 self.add_mainscreen_button("Featured", "Most listened to", self.on_featured)
153 self.add_mainscreen_button("Radios", "The best in free music", self.on_radios)
154 self.add_mainscreen_button("Search", "Search for artists/albums", self.on_search)
156 self.window.show_all()
158 def add_mainscreen_button(self, title, subtitle, callback):
159 btn = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT,
160 hildon.BUTTON_ARRANGEMENT_VERTICAL)
161 btn.set_text(title, subtitle)
162 btn.set_property('width-request', 225)
163 btn.connect('clicked', callback)
166 def on_request_cover(self, albumid, size):
167 jamaendo.get_album_cover_async(self.got_album_cover, int(albumid), size)
169 def on_request_images(self, urls):
170 jamaendo.get_images_async(self.got_images, urls)
172 def got_album_cover(self, albumid, size, cover):
173 gtk.gdk.threads_enter()
174 postoffice.notify('album-cover', albumid, size, cover)
175 gtk.gdk.threads_leave()
177 def got_images(self, images):
178 gtk.gdk.threads_enter()
179 postoffice.notify('images', images)
180 gtk.gdk.threads_leave()
182 #def add_featured_button(self):
183 # self.featured_sel = hildon.TouchSelector(text=True)
184 # self.featured_sel.append_text("Albums of the week")
185 # self.featured_sel.append_text("Tracks of the week")
186 # self.featured_sel.append_text("New releases")
187 # btn = hildon.PickerButton(gtk.HILDON_SIZE_THUMB_HEIGHT,
188 # hildon.BUTTON_ARRANGEMENT_VERTICAL)
189 # btn.set_text("Featured", "Most listened to")
190 # btn.set_property('width-request', 225)
191 # btn.set_selector(self.featured_sel)
192 # self.featured_btn = btn
195 def destroy(self, widget):
196 postoffice.disconnect(['request-album-cover', 'request-images'], self)
198 from player import the_player
203 def show_about(self, w, win):
204 dialog = gtk.AboutDialog()
205 dialog.set_program_name("jamaendo")
206 dialog.set_website("http://jamaendo.garage.maemo.org/")
207 dialog.set_website_label("http://jamaendo.garage.maemo.org/")
208 dialog.set_version(VERSION)
209 dialog.set_license("""Copyright (c) 2010, Kristoffer Gronlund
212 Redistribution and use in source and binary forms, with or without
213 modification, are permitted provided that the following conditions are met:
214 * Redistributions of source code must retain the above copyright
215 notice, this list of conditions and the following disclaimer.
216 * Redistributions in binary form must reproduce the above copyright
217 notice, this list of conditions and the following disclaimer in the
218 documentation and/or other materials provided with the distribution.
219 * Neither the name of Jamaendo nor the
220 names of its contributors may be used to endorse or promote products
221 derived from this software without specific prior written permission.
223 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
224 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
225 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
226 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
227 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
229 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
230 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
231 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
232 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
234 dialog.set_authors(("Kristoffer Gronlund <kristoffer.gronlund@purplescout.se>",
235 "Based on Panucci, written by Thomas Perl <thpinfo.com>"))
236 dialog.set_comments("""Jamaendo plays music from the music catalog of JAMENDO.
238 JAMENDO is an online platform that distributes musical works under Creative Commons licenses.""")
239 gtk.about_dialog_set_email_hook(self.open_link, dialog)
240 gtk.about_dialog_set_url_hook(self.open_link, dialog)
241 dialog.connect( 'response', lambda dlg, response: dlg.destroy())
242 for parent in dialog.vbox.get_children():
243 for child in parent.get_children():
244 if isinstance(child, gtk.Label):
245 child.set_selectable(False)
246 child.set_alignment(0.0, 0.5)
250 def open_link(self, d, url, data):
251 #print "url: %s" % (url)
253 webbrowser.open_new(url)
256 #def on_refresh(self, button):
257 # dialog = RefreshDialog()
262 def on_featured(self, button):
263 dialog = ButtonListDialog('Featured', self.window)
264 def fn(btn, feature):
265 self.featuredwnd = FeaturedWindow(feature)
266 self.featuredwnd.show_all()
267 dialog.response(gtk.RESPONSE_OK)
268 for feature, _ in FeaturedWindow.features:
269 dialog.add_button(feature, fn, feature)
274 def on_radios(self, button):
275 self.radioswnd = RadiosWindow()
276 self.radioswnd.show_all()
278 def on_search(self, button):
279 self.searchwnd = SearchWindow()
280 self.searchwnd.show_all()
282 def on_playlists(self, button):
283 self.playlistswnd = PlaylistsWindow()
284 self.playlistswnd.show_all()
286 def on_settings(self, button):
287 dialog = gtk.Dialog()
288 dialog.set_title("Settings")
289 dialog.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK )
291 tbl = gtk.Table(1, 2)
292 tbl.attach(gtk.Label("Username:"), 0, 1, 0, 1)
293 entry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
294 entry.set_placeholder("jamendo.com username")
296 entry.set_text(settings.user)
297 tbl.attach(entry, 1, 2, 0, 1)
298 vbox.pack_start(tbl, True, True, 2)
300 result = dialog.run()
301 val = entry.get_text()
304 if val and result == gtk.RESPONSE_OK:
305 #print "new user name:", val
310 def on_favorites(self, button):
311 self.favoriteswnd = FavoritesWindow()
312 self.favoriteswnd.show_all()
314 def on_player(self, button):
318 def on_search(self, button):
320 self.searchbar.show()
322 self.searchstore = gtk.ListStore(gobject.TYPE_STRING)
323 iter = self.searchstore.append()
324 self.searchstore.set(iter, 0, "Test1")
325 iter = self.searchstore.append()
326 self.searchstore.set(iter, 0, "Test2")
327 self.searchbar = hildon.FindToolbar("Search", self.searchstore, 0)
328 self.searchbar.set_active(0)
329 self.window.add_toolbar(self.searchbar)
330 self.searchbar.show()
334 ossohelper.application_init('org.jamaendo', '0.1')
338 self.window.show_all()
340 ossohelper.application_exit()
342 if __name__=="__main__":