Tweaking about box
[jamaendo] / jamaui / ui.py
1 #!/usr/bin/env python
2 #
3 # This file is part of Jamaendo.
4 # Copyright (c) 2010 Kristoffer Gronlund
5 #
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.
10 #
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.
15 #
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/>.
18 #
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)
23 #
24 # Jamaendo jamendo.com API wrapper licensed under the New BSD License;
25 # see module for details.
26 #
27
28 import os, sys
29 import gtk
30 import gobject
31 import util
32 import logging
33 from settings import settings
34
35 import ossohelper
36
37 gobject.threads_init()
38
39 log = logging.getLogger(__name__)
40
41 VERSION = '0.1'
42
43 try:
44     import hildon
45 except:
46     if util.platform == 'maemo':
47         log.critical('Using GTK widgets, install "python2.5-hildon" '
48             'for this to work properly.')
49     else:
50         log.critical('This ui only works in maemo')
51         sys.exit(1)
52
53 from dbus.mainloop.glib import DBusGMainLoop
54
55 DBusGMainLoop(set_as_default=True)
56
57 import jamaendo
58
59 from playerwindow import open_playerwindow
60 from search import SearchWindow
61 from featured import FeaturedWindow
62 from radios import RadiosWindow
63 from favorites import FavoritesWindow
64
65 class PlaylistsWindow(hildon.StackableWindow):
66     def __init__(self):
67         hildon.StackableWindow.__init__(self)
68         self.set_title("Playlists")
69
70         label = gtk.Label("Playlists")
71         vbox = gtk.VBox(False, 0)
72         vbox.pack_start(label, True, True, 0)
73         self.add(vbox)
74
75 class Jamaui(object):
76     def __init__(self):
77         self.app = None
78         self.menu = None
79         self.window = None
80
81     def create_window(self):
82         self.app = hildon.Program()
83         self.window = hildon.StackableWindow()
84         self.app.add_window(self.window)
85
86         self.window.set_title("jamaendo")
87         self.window.connect("destroy", self.destroy)
88
89         self.CONFDIR = os.path.expanduser('~/MyDocs/.jamaendo')
90         jamaendo.set_cache_dir(self.CONFDIR)
91         settings.set_filename(os.path.join(self.CONFDIR, 'ui_settings'))
92         settings.load()
93
94     def save_settings(self):
95         settings.save()
96
97     def create_menu(self):
98         self.menu = hildon.AppMenu()
99
100         #search = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
101         #search.set_label("Search")
102         #search.connect("clicked", self.on_search)
103         #self.menu.append(search)
104
105         #player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
106         #player.set_label("Open player")
107         #player.connect("clicked", self.on_player)
108         #self.menu.append(player)
109
110         player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
111         player.set_label("Favorites")
112         player.connect("clicked", self.on_favorites)
113         self.menu.append(player)
114
115         #player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
116         #player.set_label("Playlists")
117         #player.connect("clicked", self.on_playlists)
118         #self.menu.append(player)
119
120         player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
121         player.set_label("Settings")
122         player.connect("clicked", self.on_settings)
123         self.menu.append(player)
124
125
126         # Don't use localdb ATM
127         #refresh = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
128         #refresh.set_label("Refresh")
129         #refresh.connect("clicked", self.on_refresh)
130         #self.menu.append(refresh)
131
132         menu_about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
133         menu_about.set_label("About")
134         menu_about.connect("clicked", self.show_about, self.window)
135         self.menu.append(menu_about)
136         gtk.about_dialog_set_url_hook(self.open_link, None)
137
138         self.menu.show_all()
139         self.window.set_app_menu(self.menu)
140
141
142     def setup_widgets(self):
143         bgimg = util.find_resource('bg.png')
144         if bgimg:
145             background, mask = gtk.gdk.pixbuf_new_from_file(bgimg).render_pixmap_and_mask()
146             self.window.realize()
147             self.window.window.set_back_pixmap(background, False)
148
149         bbox = gtk.HButtonBox()
150         alignment = gtk.Alignment(xalign=0.2, yalign=0.925, xscale=1.0)
151         alignment.add(bbox)
152         bbox.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
153         self.bbox = bbox
154         self.window.add(alignment)
155
156         self.add_mainscreen_button("Featured", "Most listened to", self.on_featured)
157         self.add_mainscreen_button("Radios", "The best in free music", self.on_radios)
158         self.add_mainscreen_button("Search", "Search for artists/albums", self.on_search)
159
160         self.window.show_all()
161
162     def add_mainscreen_button(self, title, subtitle, callback):
163         btn = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT,
164                             hildon.BUTTON_ARRANGEMENT_VERTICAL)
165         btn.set_text(title, subtitle)
166         btn.set_property('width-request', 225)
167         btn.connect('clicked', callback)
168         self.bbox.add(btn)
169
170     #def add_featured_button(self):
171     #    self.featured_sel = hildon.TouchSelector(text=True)
172     #    self.featured_sel.append_text("Albums of the week")
173     #    self.featured_sel.append_text("Tracks of the week")
174     #    self.featured_sel.append_text("New releases")
175     #    btn = hildon.PickerButton(gtk.HILDON_SIZE_THUMB_HEIGHT,
176     #                              hildon.BUTTON_ARRANGEMENT_VERTICAL)
177     #    btn.set_text("Featured", "Most listened to")
178     #    btn.set_property('width-request', 225)
179     #    btn.set_selector(self.featured_sel)
180     #    self.featured_btn = btn
181     #    self.bbox.add(btn)
182
183     def destroy(self, widget):
184         gtk.main_quit()
185
186     def show_about(self, w, win):
187         dialog = gtk.AboutDialog()
188         dialog.set_program_name("jamaendo")
189         dialog.set_website("http://github.com/krig")
190         dialog.set_website_label("http://github.com/krig")
191         dialog.set_version(VERSION)
192         dialog.set_license("""Copyright (c) 2010, Kristoffer Gronlund
193 All rights reserved.
194
195 Redistribution and use in source and binary forms, with or without
196 modification, are permitted provided that the following conditions are met:
197      * Redistributions of source code must retain the above copyright
198        notice, this list of conditions and the following disclaimer.
199      * Redistributions in binary form must reproduce the above copyright
200        notice, this list of conditions and the following disclaimer in the
201        documentation and/or other materials provided with the distribution.
202      * Neither the name of Jamaendo nor the
203        names of its contributors may be used to endorse or promote products
204        derived from this software without specific prior written permission.
205
206 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
207 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
208 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
209 DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
210 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
211 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
212 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
213 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
214 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
215 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
216 """)
217         dialog.set_authors(("Kristoffer Gronlund <kristoffer.gronlund@purplescout.se>",
218                             "Based on Panucci, written by Thomas Perl <thpinfo.com>"))
219         dialog.set_comments("""Jamaendo plays music from the music catalog of JAMENDO.
220
221 JAMENDO is an online platform that distributes musical works under Creative Commons licenses.""")
222         gtk.about_dialog_set_email_hook(self.open_link, dialog)
223         gtk.about_dialog_set_url_hook(self.open_link, dialog)
224         dialog.connect( 'response', lambda dlg, response: dlg.destroy())
225         for parent in dialog.vbox.get_children():
226             for child in parent.get_children():
227                 if isinstance(child, gtk.Label):
228                     child.set_selectable(False)
229                     child.set_alignment(0.0, 0.5)
230         dialog.run()
231         dialog.destroy()
232
233     def open_link(self, d, url, data):
234         print "url: %s" % (url)
235         import webbrowser
236         webbrowser.open_new(url)
237
238
239     #def on_refresh(self, button):
240     #    dialog = RefreshDialog()
241     #    dialog.show_all()
242     #    dialog.run()
243     #    dialog.hide()
244
245     def on_featured(self, button):
246         dialog = hildon.PickerDialog(self.window)
247         sel = hildon.TouchSelector(text=True)
248         for feature, _ in FeaturedWindow.features:
249             sel.append_text(feature)
250         dialog.set_selector(sel)
251         dialog.set_title("Featured")
252         if dialog.run() == gtk.RESPONSE_OK:
253             txt = sel.get_current_text()
254             self.featuredwnd = FeaturedWindow(txt)
255             self.featuredwnd.show_all()
256         dialog.destroy()
257
258     def on_radios(self, button):
259         self.radioswnd = RadiosWindow()
260         self.radioswnd.show_all()
261
262     def on_search(self, button):
263         self.searchwnd = SearchWindow()
264         self.searchwnd.show_all()
265
266     def on_playlists(self, button):
267         self.playlistswnd = PlaylistsWindow()
268         self.playlistswnd.show_all()
269
270     def on_settings(self, button):
271         dialog = gtk.Dialog()
272         dialog.set_title("Settings")
273         dialog.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK )
274         vbox = dialog.vbox
275         tbl = gtk.Table(1, 2)
276         tbl.attach(gtk.Label("Username:"), 0, 1, 0, 1)
277         entry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
278         entry.set_placeholder("jamendo.com username")
279         if settings.user:
280             entry.set_text(settings.user)
281         tbl.attach(entry, 1, 2, 0, 1)
282         vbox.pack_start(tbl, True, True, 2)
283         dialog.show_all()
284         result = dialog.run()
285         val = entry.get_text()
286         dialog.destroy()
287         print val, result
288         if val and result == gtk.RESPONSE_OK:
289             print "new user name:", val
290             settings.user = val
291             self.save_settings()
292
293
294     def on_favorites(self, button):
295         self.favoriteswnd = FavoritesWindow()
296         self.favoriteswnd.show_all()
297
298     def on_player(self, button):
299         open_playerwindow([])
300
301     '''
302     def on_search(self, button):
303         if self.searchbar:
304             self.searchbar.show()
305         else:
306             self.searchstore = gtk.ListStore(gobject.TYPE_STRING)
307             iter = self.searchstore.append()
308             self.searchstore.set(iter, 0, "Test1")
309             iter = self.searchstore.append()
310             self.searchstore.set(iter, 0, "Test2")
311             self.searchbar = hildon.FindToolbar("Search", self.searchstore, 0)
312             self.searchbar.set_active(0)
313             self.window.add_toolbar(self.searchbar)
314             self.searchbar.show()
315     '''
316
317     def run(self):
318         ossohelper.application_init('org.jamaendo', '0.1')
319         self.create_window()
320         self.create_menu()
321         self.setup_widgets()
322         self.window.show_all()
323         gtk.main()
324         ossohelper.application_exit()
325
326 if __name__=="__main__":
327     ui = Jamaui()
328     ui.run()
329