00001
00002
00003 import os
00004 import gtk
00005 import gtk.glade
00006 import gobject
00007 import webbrowser
00008
00009 import functions
00010 import clWidgets
00011
00012
00013 def _(txt): return txt
00014
00015 class Pref():
00016 pass
00017
00018
00019 class theme_selection(gtk.ComboBox):
00020 def __init__(self, value="None"):
00021 liststore = gtk.ListStore(gobject.TYPE_STRING)
00022 gtk.ComboBox.__init__(self, liststore)
00023 cell = gtk.CellRendererText()
00024
00025 self.pack_start(cell, True)
00026 self.add_attribute(cell, 'text', 0)
00027 self.set_wrap_width(2)
00028
00029 self.insert_text(0, "None")
00030 self.insert_text(1, value)
00031 self.set_active(1)
00032
00033 counter = 1
00034 themes = functions.sorteddirlist()
00035 for theme in themes:
00036 counter += 1
00037 self.insert_text(counter, theme)
00038 self.show()
00039
00040
00041
00042
00043
00044 class DefaultPrefs():
00045 def __init__(self, pyjama=None):
00046 self.pyjama = pyjama
00047
00048 def create_main(self):
00049
00050
00051
00052 self.main = Pref()
00053 self.main.vbox = gtk.VBox()
00054 self.main.vbox.show()
00055
00056
00057 hbox = gtk.HBox()
00058 hbox.show()
00059 l = gtk.Label("Number of similar Albums to\nshow on album pages")
00060 l.show()
00061 hbox.pack_start(l, False, False, 15)
00062 self.main.spin_similar_albums = gtk.SpinButton()
00063 self.main.spin_similar_albums.set_increments(1, 10)
00064 self.main.spin_similar_albums.set_range(0, 15)
00065 self.main.spin_similar_albums.set_value(5)
00066 self.main.spin_similar_albums.show()
00067 hbox.pack_end(self.main.spin_similar_albums, False, False, 30)
00068 self.main.vbox.pack_start(hbox, False, False, 10)
00069 self.main.spin_similar_albums.set_value(self.pyjama.settings.get_value("PYJAMA", "similar_albums", 5, float))
00070
00071 sep = gtk.HSeparator()
00072 sep.show()
00073 self.main.vbox.pack_start(sep, False, False, 10)
00074
00075
00076 hbox = gtk.HBox()
00077 hbox.show()
00078 l = gtk.Label("Select a theme")
00079 l.show()
00080 hbox.pack_start(l, False, False, 15)
00081 self.main.old_theme = self.pyjama.settings.get_value("PYJAMA", "standard_theme", "None")
00082 self.main.theme = theme_selection(self.main.old_theme)
00083 self.main.theme.show()
00084 hbox.pack_end(self.main.theme, False, False, 30)
00085 self.main.vbox.pack_start(hbox, False, False, 10)
00086
00087
00088 hbox = gtk.HBox()
00089 hbox.show()
00090 l = gtk.Label("Show toolbar text")
00091 l.show()
00092 hbox.pack_start(l, False, False, 15)
00093 self.main.check_show_toolbar_text = gtk.CheckButton()
00094 self.main.check_show_toolbar_text.show()
00095 hbox.pack_end(self.main.check_show_toolbar_text, False, False, 30)
00096 self.main.vbox.pack_start(hbox, False, False, 10)
00097 show_toolbar_text = self.pyjama.settings.get_value("PYJAMA", "show_toolbar_text", False)
00098 self.main.check_show_toolbar_text.set_active(show_toolbar_text)
00099
00100
00101 hbox = gtk.HBox()
00102 hbox.show()
00103 l = gtk.Label("Show pyjama in taskbar")
00104 l.show()
00105 hbox.pack_start(l, False, False, 15)
00106 self.main.check_show_taskbar = gtk.CheckButton()
00107 self.main.check_show_taskbar.show()
00108 hbox.pack_end(self.main.check_show_taskbar, False, False, 30)
00109 self.main.vbox.pack_start(hbox, False, False, 10)
00110 show_window_in_taskbar = self.pyjama.settings.get_value("PYJAMA", "show_window_in_taskbar", False)
00111 self.main.check_show_taskbar.set_active(show_window_in_taskbar)
00112
00113
00114 hbox = gtk.HBox()
00115 hbox.show()
00116 l = gtk.Label("Cover size in notifications")
00117 l.show()
00118 hbox.pack_start(l, False, False, 15)
00119 self.main.spin_notification_size = gtk.SpinButton()
00120 self.main.spin_notification_size.set_increments(1, 10)
00121 self.main.spin_notification_size.set_range(0, 400)
00122 self.main.spin_notification_size.show()
00123 hbox.pack_end(self.main.spin_notification_size, False, False, 30)
00124 self.main.vbox.pack_start(hbox, False, False, 10)
00125 self.main.spin_notification_size.set_value(self.pyjama.settings.get_value("PYJAMA", "notification_cover_size", 75, float))
00126
00127
00128 hbox = gtk.HBox()
00129 hbox.show()
00130 l = gtk.Label("How long should notifications been shown?\nValue in ms")
00131 l.show()
00132 hbox.pack_start(l, False, False, 15)
00133 self.main.spin_notification_delay = gtk.SpinButton()
00134 self.main.spin_notification_delay.set_increments(1, 100)
00135 self.main.spin_notification_delay.set_range(0, 30000)
00136 self.main.spin_notification_delay.set_value(5000)
00137 self.main.spin_notification_delay.show()
00138 hbox.pack_end(self.main.spin_notification_delay, False, False, 30)
00139 self.main.vbox.pack_start(hbox, False, False, 10)
00140 self.main.spin_notification_delay.set_value(self.pyjama.settings.get_value("PYJAMA", "notification_delay", 5000, float))
00141 return self.main.vbox
00142
00143
00144
00145
00146 def create_jamendo(self):
00147 self.jamendo = Pref()
00148 self.jamendo.vbox = gtk.VBox()
00149 self.jamendo.vbox.show()
00150
00151
00152 hbox = gtk.HBox()
00153 hbox.show()
00154 l = gtk.Label()
00155 l.set_markup("How many <b>days</b> should queries been stores\nthat <b>will change from time to time</b>.")
00156 l.show()
00157 hbox.pack_start(l, False, False, 15)
00158 self.jamendo.spin_caching_time_short = gtk.SpinButton()
00159 self.jamendo.spin_caching_time_short.set_increments(1, 100)
00160 self.jamendo.spin_caching_time_short.set_range(1, 365)
00161 self.jamendo.spin_caching_time_short.show()
00162 hbox.pack_end(self.jamendo.spin_caching_time_short, False, False, 30)
00163 self.jamendo.vbox.pack_start(hbox, False, False, 10)
00164 self.jamendo.spin_caching_time_short.set_value(self.pyjama.settings.get_value("JAMENDO", "caching_time_short", 2*86400.0, float)/86400.0)
00165
00166
00167
00168 hbox = gtk.HBox()
00169 hbox.show()
00170 l = gtk.Label()
00171 l.set_markup("How many <b>days</b> should queries been stores\nthat <b>won't change</b> probably.")
00172 l.show()
00173 hbox.pack_start(l, False, False, 15)
00174 self.jamendo.spin_caching_time_long = gtk.SpinButton()
00175 self.jamendo.spin_caching_time_long.set_increments(1, 100)
00176 self.jamendo.spin_caching_time_long.set_range(1, 365)
00177 self.jamendo.spin_caching_time_long.show()
00178 hbox.pack_end(self.jamendo.spin_caching_time_long, False, False, 30)
00179 self.jamendo.vbox.pack_start(hbox, False, False, 10)
00180 self.jamendo.spin_caching_time_long.set_value(self.pyjama.settings.get_value("JAMENDO", "caching_time_long", 90*86400.0, float)/86400.0)
00181
00182
00183 hbox = gtk.HBox()
00184 hbox.show()
00185 l = gtk.Label()
00186 l.set_markup("<b>Streaming</b> format\nOGG has a better quality, MP3 supports seeking.")
00187 l.show()
00188 vbox = gtk.VBox()
00189 vbox.show()
00190 hbox.pack_start(l, False, False, 15)
00191 self.jamendo.rbutton_format_stream_mp3 = gtk.RadioButton(None, "MP3")
00192 self.jamendo.rbutton_format_stream_mp3.show()
00193 vbox.pack_start(self.jamendo.rbutton_format_stream_mp3, False, False, 10)
00194 self.jamendo.rbutton_format_stream_ogg = gtk.RadioButton(self.jamendo.rbutton_format_stream_mp3, "OGG")
00195 self.jamendo.rbutton_format_stream_ogg.show()
00196 vbox.pack_end(self.jamendo.rbutton_format_stream_ogg, False, False, 10)
00197 hbox.pack_end(vbox, False, False, 30 )
00198 self.jamendo.vbox.pack_start(hbox, False, False, 10)
00199 is_mp3 = self.pyjama.settings.get_value("JAMENDO", "format_stream", "mp31").lower() == "mp31"
00200 self.jamendo.rbutton_format_stream_mp3.set_active(is_mp3)
00201 self.jamendo.rbutton_format_stream_ogg.set_active(not is_mp3)
00202
00203
00204 hbox = gtk.HBox()
00205 hbox.show()
00206 l = gtk.Label()
00207 l.set_markup("<b>Download</b> format\nWhich format should be downloaded?")
00208 l.show()
00209 vbox = gtk.VBox()
00210 vbox.show()
00211 hbox.pack_start(l, False, False, 15)
00212 self.jamendo.rbutton_format_torrent_mp3 = gtk.RadioButton(None, "MP3")
00213 self.jamendo.rbutton_format_torrent_mp3.show()
00214 vbox.pack_start(self.jamendo.rbutton_format_torrent_mp3, False, False, 10)
00215 self.jamendo.rbutton_format_torrent_ogg = gtk.RadioButton(self.jamendo.rbutton_format_torrent_mp3, "OGG")
00216 self.jamendo.rbutton_format_torrent_ogg.show()
00217 vbox.pack_end(self.jamendo.rbutton_format_torrent_ogg, False, False, 10)
00218 hbox.pack_end(vbox, False, False, 30 )
00219 self.jamendo.vbox.pack_start(hbox, False, False, 10)
00220 is_mp3 = self.pyjama.settings.get_value("JAMENDO", "format", "mp32").lower() == "mp32"
00221 self.jamendo.rbutton_format_torrent_mp3.set_active(is_mp3)
00222 self.jamendo.rbutton_format_torrent_ogg.set_active(not is_mp3)
00223 return self.jamendo.vbox
00224
00225
00226
00227
00228 def create_sound(self):
00229 self.sound = Pref()
00230 self.sound.vbox = gtk.VBox()
00231 self.sound.vbox.show()
00232 hbox = gtk.HBox()
00233 hbox.show()
00234 l = gtk.Label("Volume on startup")
00235 l.show()
00236 hbox.pack_start(l, False, False, 15)
00237 self.sound.spin_default_volume = gtk.SpinButton()
00238 self.sound.spin_default_volume.set_increments(1, 10)
00239 self.sound.spin_default_volume.set_range(0, 250)
00240 self.sound.spin_default_volume.show()
00241 hbox.pack_end(self.sound.spin_default_volume, False, False, 30)
00242 self.sound.vbox.pack_start(hbox, False, False, 10)
00243 self.sound.spin_default_volume.set_value(self.pyjama.settings.get_value("SOUND", "default_vol", 75, float))
00244
00245 hbox = gtk.HBox()
00246 hbox.show()
00247 l = gtk.Label("Max Volume")
00248 l.show()
00249 hbox.pack_start(l, False, False, 15)
00250 self.sound.spin_max_volume = gtk.SpinButton()
00251 self.sound.spin_max_volume.set_increments(1, 10)
00252 self.sound.spin_max_volume.set_range(0, 250)
00253 self.sound.spin_max_volume.show()
00254 hbox.pack_end(self.sound.spin_max_volume, False, False, 30)
00255 self.sound.vbox.pack_start(hbox, False, False, 10)
00256 self.sound.spin_max_volume.set_value(self.pyjama.settings.get_value("SOUND", "vol_max", 150, float))
00257
00258
00259 if self.pyjama.player.equalizer_available:
00260 self.sound.show_equalizer_box = False
00261 if self.sound.show_equalizer_box:
00262 self.sound.equalizer = clWidgets.EqualizerBox(self.pyjama)
00263 self.sound.vbox.pack_start(self.sound.equalizer, False, False, 10)
00264 else:
00265 self.sound.bEqualizer = clWidgets.ImageButton("view-media-equalizer.png", 50, 50)
00266 self.sound.bEqualizer.set_label("Equalizer")
00267 self.sound.bEqualizer.set_tooltip_text("Show Pyjama's Equalizer")
00268 self.sound.bEqualizer.connect("clicked", self.cb_button_pressed)
00269 self.sound.bEqualizer.show()
00270 self.sound.vbox.pack_start(self.sound.bEqualizer, False, False, 10)
00271
00272 return self.sound.vbox
00273
00274
00275
00276
00277
00278 def create_performance(self):
00279 self.perf = Pref()
00280 self.perf.vbox = gtk.VBox()
00281 self.perf.vbox.show()
00282 img = gtk.Image()
00283 img.show()
00284 img.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
00285 self.perf.vbox.pack_start(img, False, False, 10)
00286 txt = gtk.Label()
00287 txt.show()
00288 txt.set_markup("Only advanced user should set performance \
00289 reladed preferences. For this reason I decided not to let \
00290 someone set those settings via this dialog. \
00291 Please edit <b>pyjama.cfg</b> in order to set \
00292 <i>history size</i>, <i>search limitis</i> or <i>thread related</i> settings.".replace(8*" ", "\n"))
00293 self.perf.vbox.pack_start(txt, False, False, 10)
00294 return self.perf.vbox
00295
00296
00297
00298
00299
00300 def create_plugin(self):
00301 self.plugin_vbox = gtk.VBox()
00302 self.plugin_vbox.show()
00303 img = gtk.Image()
00304 img.set_from_file(os.path.join(functions.install_dir(), "images", "plugin.png"))
00305 img.show()
00306 self.plugin_vbox.pack_start(img, False, True,10)
00307 l = gtk.Label(_("<-- To configure a plugins, select if from the list on the left side."))
00308 l.show()
00309 self.plugin_vbox.pack_start(l, False, True,10)
00310
00311
00312 hbox = gtk.HBox()
00313
00314
00315
00316
00317 l = clWidgets.MyLinkButton("", "Select and unselect plugins")
00318 l.set_tooltip_text("Click here to choose which plugin should be loaded")
00319 l.connect("clicked", self.pyjama.show_plugins)
00320 l.show()
00321
00322 self.plugin_vbox.pack_start(l, False, True, 20)
00323
00324
00325
00326 url = "http://xn--ngel-5qa.de/pyjama/html"
00327 hbox = gtk.HBox()
00328 hbox.show()
00329 l = gtk.Label(_("Learn more about\npyjama's plugin interface:"))
00330 l.show()
00331 hbox.pack_start(l)
00332 l = clWidgets.MyLinkButton(url, _("Pyjama's Documentation"))
00333 l.set_tooltip_text(url)
00334 l.connect("clicked", self.cb_visit_documentation)
00335 l.show()
00336 hbox.pack_start(l)
00337 self.plugin_vbox.pack_end(hbox, False, True, 20)
00338 return self.plugin_vbox
00339
00340
00341
00342
00343
00344 def pyjama_save_preferences(self):
00345
00346 self.pyjama.settings.set_value("PYJAMA", "similar_albums", int(self.main.spin_similar_albums.get_value()))
00347 self.pyjama.settings.set_value("PYJAMA", "show_toolbar_text", self.main.check_show_toolbar_text.get_active())
00348 self.pyjama.settings.set_value("PYJAMA", "show_window_in_taskbar", self.main.check_show_taskbar.get_active())
00349 self.pyjama.settings.set_value("PYJAMA", "notification_cover_size", int(self.main.spin_notification_size.get_value()))
00350 self.pyjama.settings.set_value("PYJAMA", "notification_delay", int(self.main.spin_notification_delay.get_value()))
00351
00352 newtheme = self.pyjama.window.get_active_text(self.main.theme)
00353 self.pyjama.settings.set_value("PYJAMA", "standard_theme", newtheme)
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 def sound_save_preferences(self):
00367
00368 self.pyjama.settings.set_value("SOUND", "vol_max", self.sound.spin_max_volume.get_value(), int)
00369 self.pyjama.settings.set_value("SOUND", "default_vol", self.sound.spin_default_volume.get_value(), int)
00370
00371 if self.sound.show_equalizer_box:
00372 self.sound.equalizer.save()
00373
00374 def perf_save_preferences(self):
00375
00376 pass
00377
00378 def jamendo_save_preferences(self):
00379
00380 self.pyjama.settings.set_value("JAMENDO", "caching_time_long", self.jamendo.spin_caching_time_long.get_value()*86400.0, int)
00381 self.pyjama.settings.set_value("JAMENDO", "caching_time_short", self.jamendo.spin_caching_time_short.get_value()*86400.0, int)
00382
00383
00384 if self.jamendo.rbutton_format_stream_mp3.get_active():
00385 self.pyjama.settings.set_value("JAMENDO", "format_stream", "mp31")
00386 else:
00387 self.pyjama.settings.set_value("JAMENDO", "format_stream", "ogg2")
00388
00389 if self.jamendo.rbutton_format_torrent_mp3.get_active():
00390 self.pyjama.settings.set_value("JAMENDO", "format", "mp32")
00391 else:
00392 self.pyjama.settings.set_value("JAMENDO", "format", "ogg3")
00393
00394
00395 print "Jamendo prefs still need to be saved"
00396
00397 def plugin_save_preferences(self):
00398 pass
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 def cb_visit_documentation(self, widget):
00417 webbrowser.open_new_tab(widget.uri)
00418
00419 def cb_button_pressed(self, widget):
00420 if widget == self.sound.bEqualizer:
00421 eq = clWidgets.EqualizerBox(self.pyjama)
00422 eq.dialog()
00423
00424
00425 PLUGIN_STRING = _("Plugins")
00426
00427 class Preferences():
00428 def __init__(self, pyjama=None):
00429
00430 self.plugins = []
00431 self.modules = []
00432
00433 self.currently_shown_box_name = None
00434
00435 default = DefaultPrefs(pyjama)
00436 self.start_page = self.register_module("Pyjama", default.create_main, default.pyjama_save_preferences, "General Pyjama Preferences")
00437 self.register_module("Sound", default.create_sound, default.sound_save_preferences)
00438 self.register_module("Jamendo", default.create_jamendo, default.jamendo_save_preferences)
00439 self.register_module("Performance", default.create_performance, default.perf_save_preferences)
00440
00441 self.register_module(PLUGIN_STRING, default.create_plugin, default.plugin_save_preferences, "Plugins")
00442
00443
00444
00445 def __init_widgets(self):
00446
00447
00448 xml = gtk.glade.XML(os.path.join(functions.install_dir(), "preferences.glade"))
00449 self.dialog = xml.get_widget('dialog1')
00450 pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(functions.install_dir(), "images", "pyjama.png"))
00451 self.dialog.set_icon(pixbuf)
00452 self.dialog.set_default_size(640,480)
00453
00454
00455 self.caption = xml.get_widget('caption')
00456
00457
00458 self.viewport = xml.get_widget('viewport1')
00459 sw = xml.get_widget('scrolledwindow1')
00460 self.treeview = xml.get_widget('treeview1')
00461
00462
00463 self.model = gtk.TreeStore(gobject.TYPE_STRING)
00464 self.treeview.set_model(self.model)
00465 renderer = gtk.CellRendererText()
00466 column = gtk.TreeViewColumn("Module", renderer, markup=0)
00467 self.treeview.append_column(column)
00468
00469 self.treeview.connect("button-press-event", self.cb_treeview_button_press)
00470 self.treeview.connect("row-activated", self.cb_treeview_row_activated)
00471
00472
00473 def show_preferences(self, page_to_show=None):
00474 self.__init_widgets()
00475 self.loaded_boxes = {}
00476
00477
00478 for module in self.modules:
00479 if module['name'] != PLUGIN_STRING:
00480 self.model.append(None, (module['name'], ))
00481
00482
00483 TreeIterPlugins = self.model.append(None,(PLUGIN_STRING,))
00484 for pref in self.plugins:
00485 self.model.append(TreeIterPlugins, (pref['name'], ))
00486
00487 self.treeview.expand_all()
00488
00489 if page_to_show is None:
00490 self.show_box(self.start_page)
00491 else:
00492 self.find_box(page_to_show)
00493
00494 ret = self.dialog.run()
00495
00496
00497
00498
00499
00500 self.currently_shown_box_name = None
00501
00502 if ret > 0:
00503 for module in self.modules:
00504 if module['name'] in self.loaded_boxes:
00505 module["callback"]()
00506 for plugin in self.plugins:
00507 if plugin['name'] in self.loaded_boxes:
00508 plugin["callback"]()
00509
00510 for box in self.loaded_boxes:
00511 self.loaded_boxes[box].destroy()
00512 self.dialog.destroy()
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 def register_plugin(self, name, func, cb, caption=None):
00524
00525
00526
00527
00528 if caption is None:
00529 caption = "%s %s" % (name.capitalize(), _("Preferences"))
00530 for plugin in self.plugins:
00531 if plugin['name'] == name:
00532 self.pyjama.Events.raise_event("error", None, "You tried to add a plugin named '%s' to the preferences dialog. A plugin with this name is already existant." % name)
00533 return
00534 ret = {"name":name, "func":func, "callback":cb, "caption":caption}
00535 self.plugins.append(ret)
00536 return ret
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 def register_module(self, name, func, cb, caption=None):
00547
00548
00549
00550
00551 if caption is None:
00552 caption = "%s %s" % (name.capitalize(), _("Preferences"))
00553 for module in self.modules:
00554 if module['name'] == name:
00555 self.pyjama.Events.raise_event("error", None, "You tried to add a module named '%s' to the preferences dialog. A module with this name is already existant." % name)
00556 return
00557 ret = {"name":name, "func":func, "callback":cb, "caption":caption}
00558 self.modules.append(ret)
00559 return ret
00560
00561
00562
00563
00564
00565
00566 def has_preferences(self, name):
00567 for plugin in self.plugins:
00568 if plugin['name'].lower() == name.lower():
00569 return True
00570 return False
00571
00572
00573
00574
00575
00576
00577 def __show_items_pref(self, widget, path):
00578 if path:
00579 iter = widget.get_model().get_iter(path)
00580 else:
00581 return
00582
00583 title = widget.get_model().get_value(iter, 0)
00584
00585
00586
00587 for module in self.modules:
00588 if module['name'] == title:
00589 self.show_box(module)
00590 return
00591 for pref in self.plugins:
00592 if pref['name'] == title:
00593 self.show_box(pref)
00594 return
00595
00596
00597
00598 def find_box(self, name):
00599 for plugin in self.plugins:
00600 if plugin['name'].lower() == name.lower():
00601 self.show_box(plugin)
00602 for module in self.modules:
00603 if module['name'].lower() == name.lower():
00604 self.show_box(module)
00605
00606
00607
00608 def show_box(self, box):
00609 name = box['name']
00610 container = box['func']()
00611 caption = box['caption']
00612
00613 if name == self.currently_shown_box_name:
00614 return
00615 ch = self.viewport.get_child()
00616 if ch:
00617 self.viewport.remove(ch)
00618 if name in self.loaded_boxes:
00619 self.viewport.add(self.loaded_boxes[name])
00620 else:
00621 self.loaded_boxes[name] = container
00622 self.viewport.add(self.loaded_boxes[name])
00623 self.caption.set_markup('<span font_desc="Arial Italic 16" font_weight="bold">%s</span>' % caption)
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 self.currently_shown_box_name = name
00636
00637
00638
00639
00640
00641 def cb_treeview_row_activated(self, treeview, path, view_column):
00642 self.__show_items_pref(treeview, path)
00643
00644 def cb_treeview_button_press(self, widget, event):
00645 path = widget.get_path_at_pos(int(event.x), int(event.y))
00646 if path is not None:
00647 self.__show_items_pref(widget, path[0])
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665