Description: port radiotray to GTK-3 and GStreamer 1.0 This patch switch radiotray to GTK-3 and Gstreamer 1.0 from upstream repository. Forwarded: no Author: Carlos Ribeyro Last-Update: 2015-10-18 --- radiotray.orig/data/bookmarks.xml +++ radiotray/data/bookmarks.xml @@ -9,14 +9,14 @@ - + - + - + @@ -30,21 +30,22 @@ - - - + + + + - - + + @@ -64,6 +65,7 @@ + Index: radiotray/data/plugins/HelloWorldPlugin.py =================================================================== --- radiotray.orig/data/plugins/HelloWorldPlugin.py +++ radiotray/data/plugins/HelloWorldPlugin.py @@ -20,7 +20,7 @@ from events.EventSubscriber import EventSubscriber from events.EventManager import EventManager from Plugin import Plugin -import gtk +from gi.repository import Gtk import time # Basic example of a plugin Index: radiotray/data/plugins/HistoryPlugin.py =================================================================== --- radiotray.orig/data/plugins/HistoryPlugin.py +++ radiotray/data/plugins/HistoryPlugin.py @@ -20,7 +20,7 @@ from events.EventSubscriber import EventSubscriber from events.EventManager import EventManager from Plugin import Plugin -import gtk +from gi.repository import Gtk from lib import utils from lib.common import SYSTEM_PLUGIN_PATH, USER_PLUGIN_PATH import os @@ -72,5 +72,9 @@ class HistoryPlugin(Plugin): self.window.hide() return True + def on_delete_event(self, widget, event, data=None): + self.window.hide() + return True + def hasMenuItem(self): return True Index: radiotray/data/plugins/NotificationPlugin.py =================================================================== --- radiotray.orig/data/plugins/NotificationPlugin.py +++ radiotray/data/plugins/NotificationPlugin.py @@ -20,9 +20,10 @@ from Plugin import Plugin -import gtk -import gobject -import pynotify +from gi.repository import Gtk +from gi.repository import GObject +from gi.repository import Notify +from gi.repository import GdkPixbuf from lib.common import APP_ICON, APPNAME from events.EventManager import EventManager @@ -61,18 +62,18 @@ class NotificationPlugin(Plugin): if self.notif == None: - if pynotify.init(APPNAME): - self.notif = pynotify.Notification(title, message) - self.notif.set_urgency(pynotify.URGENCY_LOW) + if Notify.init(APPNAME): + self.notif = Notify.Notification.new(title, message, None) + self.notif.set_urgency(Notify.Urgency.LOW) self.set_icon(data) - self.notif.set_timeout(pynotify.EXPIRES_DEFAULT) + self.notif.set_timeout(Notify.EXPIRES_DEFAULT) self.notif.show() else: self.log.error('Error: there was a problem initializing the pynotify module') else: self.set_icon(data) - self.notif.update(title, message) + self.notif.update(title, message, None) self.notif.show() @@ -81,12 +82,12 @@ class NotificationPlugin(Plugin): if('icon' in data.keys()): try: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(data['icon'], 48, 48) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(data['icon'], 48, 48) self.notif.set_icon_from_pixbuf(pixbuf) except Exception, e: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(APP_ICON, 48, 48) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(APP_ICON, 48, 48) self.notif.set_icon_from_pixbuf(pixbuf) print e else: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(APP_ICON, 48, 48) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(APP_ICON, 48, 48) self.notif.set_icon_from_pixbuf(pixbuf) Index: radiotray/data/plugins/SleepTimerPlugin.py =================================================================== --- radiotray.orig/data/plugins/SleepTimerPlugin.py +++ radiotray/data/plugins/SleepTimerPlugin.py @@ -19,8 +19,8 @@ ########################################################################## from Plugin import Plugin -import gtk -import gobject +from gi.repository import Gtk +from gi.repository import GObject from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF class SleepTimerPlugin(Plugin): @@ -38,7 +38,7 @@ class SleepTimerPlugin(Plugin): self.cfgProvider = cfgProvider self.mediator = mediator self.tooltip = tooltip - self.menuItem = gtk.CheckMenuItem(self.getName(), False) + self.menuItem = Gtk.CheckMenuItem(self.getName(), False) self.menuItem.connect('activate', self.on_menu) self.menuItem.show() @@ -108,19 +108,19 @@ class SleepTimerPlugin(Plugin): def populate_tooltip(self): if self.sleep_timer_id != None: - return _("Sleep: %smin") % str(self.min_to_sleep) + return _("Sleep: %s min") % str(self.min_to_sleep) else: return None def start_sleep_timer(self, interval, display_msg): - self.sleep_timer_id = gobject.timeout_add(interval*60000, self.on_sleep_timer) + self.sleep_timer_id = GObject.timeout_add(60000, self.on_sleep_timer) self.min_to_sleep = interval self.min_to_sleep_selected = interval if display_msg: self.eventManagerWrapper.notify(_("Sleep Timer"), _("%s minute sleep timer started") % str(interval)) def stop_sleep_timer(self, display_msg): - gobject.source_remove(self.sleep_timer_id) + GObject.source_remove(self.sleep_timer_id) self.sleep_timer_id = None if display_msg: self.eventManagerWrapper.notify(_("Sleep Timer"), _("Sleep timer stopped")) @@ -128,15 +128,15 @@ class SleepTimerPlugin(Plugin): def get_sleep_timer_value(self, default_value): - #gtk.gdk.threads_enter() + #Gdk.threads_enter() - dialog = gtk.Dialog(_("Edit Sleep Timer"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + dialog = Gtk.Dialog(_("Edit Sleep Timer"), None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)) - entry = gtk.Entry(4) + entry = Gtk.Entry(4) entry.set_text(str(default_value)) - hbox = gtk.HBox() - hbox.pack_start(gtk.Label(_("Minutes:")), False, 5, 5) + hbox = Gtk.HBox() + hbox.pack_start(Gtk.Label(_("Minutes:", True, True, 0)), False, 5, 5) hbox.pack_end(entry, True, True, 5) dialog.vbox.pack_end(hbox, True, True, 20) dialog.set_icon_from_file(APP_ICON_ON) @@ -146,13 +146,13 @@ class SleepTimerPlugin(Plugin): sleep_timer_value = 0 - if ret == gtk.RESPONSE_ACCEPT: + if ret == Gtk.ResponseType.ACCEPT: if entry.get_text().isdigit(): sleep_timer_value = int(entry.get_text()) dialog.destroy() - #gtk.gdk.threads_leave() + #Gdk.threads_leave() return sleep_timer_value def on_menu(self, data): Index: radiotray/data/plugins/StationSwitcher.plugin =================================================================== --- /dev/null +++ radiotray/data/plugins/StationSwitcher.plugin @@ -0,0 +1,6 @@ +[RadioTrayPlugin] +name=StationSwitcher +desc=Allows cycling through stations +script=StationSwitcherPlugin.py +class=StationSwitcherPlugin +author=Mark F Index: radiotray/data/plugins/StationSwitcherPlugin.py =================================================================== --- /dev/null +++ radiotray/data/plugins/StationSwitcherPlugin.py @@ -0,0 +1,115 @@ +########################################################################## +# Copyright 2009 Carlos Ribeiro +# +# This file is part of Radio Tray +# +# Radio Tray is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 1 of the License, or +# (at your option) any later version. +# +# Radio Tray is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radio Tray. If not, see . +# +########################################################################## + +# author Mark F Jan 2013 +from Plugin import Plugin +from gi.repository import Gtk +import random + +class StationSwitcherPlugin(Plugin): + + # Set by parent Plugin.py + # self.name = name + # self.eventManagerWrapper = eventManagerWrapper + # self.eventSubscriber = eventSubscriber + # self.provider = provider + # self.cfgProvider = cfgProvider + # self.mediator = mediator + # self.tooltip = tooltip + + def __init__(self): + super(StationSwitcherPlugin, self).__init__() + self.shuffle = False # way to set this property from RadioTray not implemented yet + + def getName(self): + return self.name + + def activate(self): + # only Next >> button added to avoid cluttering menu. Play previous can be triggered using other means + nextMenuItem = Gtk.MenuItem("Next >>") + + # locate the turn on/off menu item and add next button after + i = 0 + insertIndex = 0 + for child in self.tooltip.gui.radioMenu.get_children(): + if not isinstance(child, Gtk.SeparatorMenuItem): + if child.get_label().startswith("Turn"): + insertIndex = i+1 + break + # break statement is required due to bug/feature in Gtk. Examining MenuItem labels on 'separators' causes + # them not to be displayed correctly. If gui classes are modified to use SeparatorMenuItem break can be removed + i+=1 + + self.tooltip.gui.radioMenu.insert(nextMenuItem,insertIndex) + nextMenuItem.connect('activate', self.on_next) + nextMenuItem.show() + + def on_next(self,data): + self.playNextRadio() + + def playPreviousRadio(self): + self.mediator.play(self.getPreviousRadio()) + + def playNextRadio(self): + self.mediator.play(self.getNextRadio()) + + def getNextRadio(self): + if self.shuffle: return self.getRandomRadio() + + allRadios = self.provider.listRadioNames() + lastStation = self.mediator.cfg_provider.getConfigValue("last_station") + lastStationIndex = allRadios.index(lastStation) + + if lastStationIndex==len(allRadios)-1: nextStationIndex=0 + else: nextStationIndex=lastStationIndex+1 + + return allRadios[nextStationIndex] + + def getPreviousRadio(self): + if self.shuffle: return self.getRandomRadio() + + allRadios = self.provider.listRadioNames() + lastStation = self.mediator.cfg_provider.getConfigValue("last_station") + lastStationIndex = allRadios.index(lastStation) + + if lastStationIndex==0: previousStationIndex=len(allRadios)-1 + else: previousStationIndex=lastStationIndex-1 + + return allRadios[previousStationIndex] + + def getRandomRadio(self): + + allRadios = self.provider.listRadioNames() + lastStation = self.mediator.cfg_provider.getConfigValue("last_station") + lastStationIndex = allRadios.index(lastStation) + + randomStationIndex = lastStationIndex + while (randomStationIndex==lastStationIndex): + randomStationIndex = random.randint(0, len(allRadios)-1) + + return allRadios[randomStationIndex] + + def hasMenuItem(self): + return False + + def on_menu(self, data): + #plugin config gui goes here. Need to add option for random station select + print "" + Index: radiotray/data/plugins/history.glade =================================================================== --- radiotray.orig/data/plugins/history.glade +++ radiotray/data/plugins/history.glade @@ -3,37 +3,23 @@ + False 5 Song History 320 260 True normal + True + False 2 - - - True - True - automatic - automatic - - - True - True - False - - - - - 1 - - True + False end @@ -44,8 +30,9 @@ True True True + False True - + False @@ -56,10 +43,31 @@ False + True end 0 + + + True + True + automatic + automatic + + + True + True + False + + + + + True + True + 1 + + Index: radiotray/radiotray =================================================================== --- radiotray.orig/radiotray +++ radiotray/radiotray @@ -4,12 +4,12 @@ import sys,os from os.path import dirname, join, pardir try: - from radiotray import radiotray + from radiotray import radiotray_runner except ImportError: basedir = os.path.dirname(os.path.realpath(__file__)) workdir = join(basedir,'src') sys.path.insert(0, workdir) os.chdir(workdir) - import radiotray + import radiotray_runner -radiotray.main(sys.argv[1:]) +radiotray_runner.main(sys.argv[1:]) Index: radiotray/src/AppIndicatorGui.py =================================================================== --- radiotray.orig/src/AppIndicatorGui.py +++ radiotray/src/AppIndicatorGui.py @@ -20,10 +20,10 @@ import sys from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF, APP_INDICATOR_ICON_CONNECT, IMAGE_PATH try: - import gtk - import gtk.glade - import gobject -except: + from gi.repository import Gtk + #import Gtk.glade +except Exception as e: + print e sys.exit(1) import textwrap import logging @@ -36,110 +36,113 @@ class AppIndicatorGui: self.mediator = mediator self.cfg_provider = cfg_provider self.provider = provider + self.menu_plugins_item = None self.log = logging.getLogger('radiotray') def buildMenu(self): - try: - import appindicator - self.app_indicator = appindicator.Indicator(APPNAME, APP_INDICATOR_ICON_OFF , appindicator.CATEGORY_APPLICATION_STATUS) - self.app_indicator.set_status(appindicator.STATUS_ACTIVE) + try: + from gi.repository import AppIndicator3 + self.app_indicator = AppIndicator3.Indicator.new(APPNAME, APP_INDICATOR_ICON_OFF , AppIndicator3.IndicatorCategory.APPLICATION_STATUS) + self.app_indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) except Exception as e: self.log.debug(e) self.log.warn("Failed to create an Application Indicator!") self.app_indicator = None + return self.app_indicator.set_icon_theme_path(IMAGE_PATH) self.turnOnOff = None self.metadata_menu_item = None self.perferences_submenu = None - self.preferences_menu = None - self.radioMenu = gtk.Menu() + self.preferences_menu = None + self.radioMenu = Gtk.Menu() self.build_app_indicator_menu(self.radioMenu) self.app_indicator.set_menu(self.radioMenu) self.handler.updateTooltip() + try: + self.app_indicator.connect("scroll-event", self.app_indicator_scroll) + except: + # not available in this version of app indicator + self.log.info("App indicator scroll events are not available.") + def build_app_indicator_menu(self, menu): - # config menu - if self.turnOnOff == None: + # config menu + if self.turnOnOff == None: if not self.mediator.context.station: - self.turnOnOff = gtk.MenuItem(_("Turned Off"), False) + self.turnOnOff = Gtk.MenuItem(_("Turned Off")) self.turnOnOff.set_sensitive(False) else: - self.turnOnOff = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False) + self.turnOnOff = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station) self.turnOnOff.set_sensitive(True) - + self.turnOnOff.connect('activate', self.handler.on_turn_on_off) - - + # stream metadata info if self.metadata_menu_item == None: - self.metadata_menu_item = gtk.MenuItem("Idle", False) + self.metadata_menu_item = Gtk.MenuItem("Idle") self.metadata_menu_item.set_sensitive(False) - - # if self.sleep_timer_menu_item == None: - # self.sleep_timer_menu_item = gtk.CheckMenuItem(_("Sleep Timer")) - + + # if self.sleep_timer_menu_item == None: + # self.sleep_timer_menu_item = Gtk.CheckMenuItem(_("Sleep Timer")) + if self.preferences_menu == None: - self.preferences_menu = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES) - - menu_config_radios = gtk.MenuItem(_("Configure Radios...")) - menu_reload_bookmarks = gtk.MenuItem(_("Reload Bookmarks")) - menu_config_plugin = gtk.MenuItem(_("Configure Plugins...")) + self.preferences_menu = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_PREFERENCES, None) + self.preferences_menu.set_always_show_image(True) + + menu_config_radios = Gtk.MenuItem(_("Configure Radios...")) + menu_reload_bookmarks = Gtk.MenuItem(_("Reload Bookmarks")) + menu_config_plugin = Gtk.MenuItem(_("Configure Plugins...")) #Check bookmarks file status menu_config_radios.set_sensitive(self.provider.isBookmarkWritable()) - # build - menu.append(self.turnOnOff) - menu.append(gtk.MenuItem()) + # build + menu.append(self.turnOnOff) + menu.append(Gtk.MenuItem()) menu.append(self.metadata_menu_item) - menu.append(gtk.MenuItem()) - + menu.append(Gtk.MenuItem()) + self.provider.walk_bookmarks(self.group_callback, self.bookmark_callback, menu) - + menu_config_radios.connect('activate', self.handler.on_preferences) menu_reload_bookmarks.connect('activate', self.handler.reload_bookmarks) menu_config_plugin.connect('activate', self.handler.on_plugin_preferences) - - - menu.append(gtk.MenuItem()) - + + + menu.append(Gtk.MenuItem()) + # build preferences menu.append(self.preferences_menu) - - if self.perferences_submenu == None: - self.perferences_submenu = gtk.Menu() - self.preferences_menu.set_submenu(self.perferences_submenu) - #self.perferences_submenu.append(gtk.MenuItem()) + + if self.perferences_submenu == None: + self.perferences_submenu = Gtk.Menu() + self.preferences_menu.set_submenu(self.perferences_submenu) + #self.perferences_submenu.append(Gtk.MenuItem()) self.perferences_submenu.append(menu_config_radios) self.perferences_submenu.append(menu_reload_bookmarks) # plugins submenu - menu_plugins_item = gtk.MenuItem("Plugins", False) - self.menu_plugins = gtk.Menu() - self.menu_plugins.append(menu_config_plugin) - self.menu_plugins.append(gtk.MenuItem()) #add separator - menu_plugins_item.set_submenu(self.menu_plugins) + if self.menu_plugins_item == None: + self.menu_plugins_item = Gtk.MenuItem("Plugins") + self.menu_plugins = Gtk.Menu() + self.menu_plugins.append(menu_config_plugin) + self.menu_plugins.append(Gtk.MenuItem()) #add separator + self.menu_plugins_item.set_submenu(self.menu_plugins) - menu.append(menu_plugins_item) + menu.append(self.menu_plugins_item) - menu_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT) - menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT) + menu_about = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_ABOUT, None) + menu_quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None) menu_quit.connect('activate', self.handler.on_quit) menu_about.connect('activate', self.handler.on_about) menu.append(menu_about) menu.append(menu_quit) menu.show_all() - - try: - self.app_indicator.connect("scroll-event", self.app_indicator_scroll) - except: - # not available in this version of app indicator - self.log.info("App indicator scroll events are not available.") def app_indicator_scroll(self, indicator, delta, direction): @@ -159,26 +162,26 @@ class AppIndicatorGui: def group_callback(self, group_name, user_data): new_user_data = None - + if group_name != 'root': - group = gtk.MenuItem(group_name, False) - user_data.append(group) - new_user_data = gtk.Menu() + group = Gtk.MenuItem(group_name) + user_data.append(group) + new_user_data = Gtk.Menu() group.set_submenu(new_user_data) else: new_user_data = self.radioMenu - + return new_user_data def bookmark_callback(self, radio_name, user_data): if radio_name.startswith("[separator-"): - separator = gtk.MenuItem() + separator = Gtk.MenuItem() user_data.append(separator) separator.show() - else: - radio = gtk.MenuItem(radio_name, False) + else: + radio = Gtk.MenuItem(radio_name) radio.show() radio.connect('activate', self.handler.on_start, radio_name) user_data.append(radio) @@ -193,9 +196,9 @@ class AppIndicatorGui: station = data['station'] self.turnOnOff.set_label(C_('Turns off the current radio.', 'Turn Off "%s"') % station) self.turnOnOff.set_sensitive(True) - + self.app_indicator.set_icon(APP_INDICATOR_ICON_ON) - + elif(state == 'paused'): if not self.mediator.context.station: self.turnOnOff.set_label(_('Turned Off')) @@ -203,9 +206,9 @@ class AppIndicatorGui: else: self.turnOnOff.set_label(_('Turn On "%s"' % self.mediator.context.station)) self.turnOnOff.set_sensitive(True) - + self.app_indicator.set_icon(APP_INDICATOR_ICON_OFF) - + elif(state == 'connecting'): station = data['station'] self.turnOnOff.set_sensitive(True) @@ -223,15 +226,15 @@ class AppIndicatorGui: if (self.mediator.getContext().state == 'playing'): if(songInfo): - otherInfo = "(vol: %s%%)" % (volume) - + otherInfo = "(vol: %s%%)" % (volume) + # don't break volume info... text = textwrap.wrap(songInfo, 30) if (30 - len(text[-1])) >= (len(otherInfo)+1): text[-1] += " " + otherInfo else: text.append(otherInfo) - + return "\n".join(text) else: return C_("Playing status tooltip information", "Playing (vol: %s%%)") % (volume) Index: radiotray/src/AudioPlayerGStreamer.py =================================================================== --- radiotray.orig/src/AudioPlayerGStreamer.py +++ radiotray/src/AudioPlayerGStreamer.py @@ -18,10 +18,21 @@ # ########################################################################## import sys, os -import pygtk, gtk, gobject -import pygst -pygst.require("0.10") -import gst +try: + import gi + gi.require_version("Gtk", "3.0") + gi.require_version('Gst', '1.0') +except: + pass +try: + from gi.repository import Gtk + from gi.repository import GObject + GObject.threads_init() + from gi.repository import Gst + Gst.init(None) +except Exception as e: + print e + from StreamDecoder import StreamDecoder from lib.common import USER_AGENT from events.EventManager import EventManager @@ -40,11 +51,13 @@ class AudioPlayerGStreamer: self.log = logging.getLogger('radiotray') # init player - self.souphttpsrc = gst.element_factory_make("souphttpsrc", "source") + self.log.debug("Initializing gstreamer...") + self.souphttpsrc = Gst.ElementFactory.make("souphttpsrc", "source") self.souphttpsrc.set_property("user-agent", USER_AGENT) - self.player = gst.element_factory_make("playbin2", "player") - fakesink = gst.element_factory_make("fakesink", "fakesink") + self.log.debug("Loading playbin..."); + self.player = Gst.ElementFactory.make("playbin", "player") + fakesink = Gst.ElementFactory.make("fakesink", "fakesink") self.player.set_property("video-sink", fakesink) #buffer size @@ -60,6 +73,8 @@ class AudioPlayerGStreamer: bus.add_signal_watch() bus.connect("message", self.on_message) + self.log.debug("GStreamer initialized.") + def start(self, uri): urlInfo = self.decoder.getMediaStreamInfo(uri) @@ -103,10 +118,10 @@ class AudioPlayerGStreamer: def playStream(self, uri): self.player.set_property("uri", uri) - self.player.set_state(gst.STATE_PAUSED) # buffer before starting playback + self.player.set_state(Gst.State.PAUSED) # buffer before starting playback def stop(self): - self.player.set_state(gst.STATE_NULL) + self.player.set_state(Gst.State.NULL) self.eventManager.notify(EventManager.STATE_CHANGED, {'state':'paused'}) def volume_up(self, volume_increment): @@ -120,30 +135,30 @@ class AudioPlayerGStreamer: def on_message(self, bus, message): t = message.type - stru = message.structure + stru = message.get_structure() if(stru != None): name = stru.get_name() if(name == 'redirect'): - slef.log.info("redirect received") - self.player.set_state(gst.STATE_NULL) + self.log.info("redirect received") + self.player.set_state(Gst.State.NULL) stru.foreach(self.redirect, None) - if t == gst.MESSAGE_EOS: + if t == Gst.MessageType.EOS: self.log.debug("Received MESSAGE_EOS") - self.player.set_state(gst.STATE_NULL) + self.player.set_state(Gst.State.NULL) self.playNextStream() - elif t == gst.MESSAGE_BUFFERING: - percent = message.structure['buffer-percent'] + elif t == Gst.MessageType.BUFFERING: + percent = message.parse_buffering() if percent < 100: self.log.debug("Buffering %s" % percent) - self.player.set_state(gst.STATE_PAUSED) + self.player.set_state(Gst.State.PAUSED) else: - self.player.set_state(gst.STATE_PLAYING) - elif t == gst.MESSAGE_ERROR: + self.player.set_state(Gst.State.PLAYING) + elif t == Gst.MessageType.ERROR: self.log.debug("Received MESSAGE_ERROR") - self.player.set_state(gst.STATE_NULL) + self.player.set_state(Gst.State.NULL) err, debug = message.parse_error() self.log.warn(err) self.log.warn(debug) @@ -153,15 +168,15 @@ class AudioPlayerGStreamer: else: self.eventManager.notify(EventManager.STATION_ERROR, {'error':debug}) - elif t == gst.MESSAGE_STATE_CHANGED: + elif t == Gst.MessageType.STATE_CHANGED: oldstate, newstate, pending = message.parse_state_changed() self.log.debug(("Received MESSAGE_STATE_CHANGED (%s -> %s)") % (oldstate, newstate)) - if newstate == gst.STATE_PLAYING: + if newstate == Gst.State.PLAYING: self.retrying = False station = self.mediator.getContext().station self.eventManager.notify(EventManager.STATE_CHANGED, {'state':'playing', 'station':station}) - elif oldstate == gst.STATE_PLAYING and newstate == gst.STATE_PAUSED: + elif oldstate == Gst.State.PLAYING and newstate == Gst.State.PAUSED: self.log.info("Received PAUSE state.") if self.retrying == False: @@ -172,22 +187,35 @@ class AudioPlayerGStreamer: - elif t == gst.MESSAGE_TAG: + elif t == Gst.MessageType.TAG: taglist = message.parse_tag() - #if there is no song information, there's no point in triggering song change event - if('artist' in taglist.keys() or 'title' in taglist.keys()): - station = self.mediator.getContext().station - metadata = {} + #for (tag, value) in taglist.items(): + # print "TT: " + tag + " - " + value - for key in taglist.keys(): - metadata[key] = taglist[key] + (present, value) = taglist.get_string('title') + if present: + metadata = {} + station = self.mediator.getContext().station + metadata['title'] = value metadata['station'] = station - + self.eventManager.notify(EventManager.SONG_CHANGED, metadata) + #if there is no song information, there's no point in triggering song change event + #if('artist' in taglist.keys() or 'title' in taglist.keys()): + # station = self.mediator.getContext().station + # metadata = {} + + # for key in taglist.keys(): + # metadata[key] = taglist[key] + + # metadata['station'] = station + + # self.eventManager.notify(EventManager.SONG_CHANGED, metadata) + return True def redirect(self, name, value, data): Index: radiotray/src/BookmarkConfiguration.py =================================================================== --- radiotray.orig/src/BookmarkConfiguration.py +++ radiotray/src/BookmarkConfiguration.py @@ -18,18 +18,19 @@ # ########################################################################## import sys +import pdb try: - import pygtk - pygtk.require("2.0") + import gi + gi.require_version("Gtk", "3.0") except: pass try: - import gtk - import gtk.glade - import gobject + from gi.repository import Gtk, Gdk + #import Gtk.glade import os -except: +except Exception as e: + print e sys.exit(1) from XmlDataProvider import XmlDataProvider @@ -39,8 +40,9 @@ from lib import i18n import uuid import logging -drop_yes = ("drop_yes", gtk.TARGET_SAME_WIDGET, 0) -drop_no = ("drop_no", gtk.TARGET_SAME_WIDGET, 0) +drop_yes = [Gtk.TargetEntry.new(target = "drop_yes", flags = Gtk.TargetFlags.SAME_WIDGET, info = 0)] +drop_no = [Gtk.TargetEntry.new(target = "drop_no", flags = Gtk.TargetFlags.SAME_WIDGET, info = 0)] +targets = [('data',Gtk.TargetFlags.SAME_APP,0)] class BookmarkConfiguration(object): @@ -92,23 +94,23 @@ class BookmarkConfiguration(object): self.load_data() # config tree ui - cell = gtk.CellRendererText() - tvcolumn = gtk.TreeViewColumn(_('Radio Name'), cell) + cell = Gtk.CellRendererText() + tvcolumn = Gtk.TreeViewColumn(_('Radio Name'), cell) self.list.append_column(tvcolumn) tvcolumn.add_attribute(cell, 'text', 0) # config combo ui - cell2 = gtk.CellRendererText() + cell2 = Gtk.CellRendererText() self.parentGroup.pack_start(cell2, True) self.parentGroup.add_attribute(cell2, 'text', 0) # config add radio group combo ui - cell4 = gtk.CellRendererText() + cell4 = Gtk.CellRendererText() self.radioGroup.pack_start(cell4, True) self.radioGroup.add_attribute(cell4, 'text', 0) # separator new group combo ui - cell3 = gtk.CellRendererText() + cell3 = Gtk.CellRendererText() self.sepGroup.pack_start(cell3, True) self.sepGroup.add_attribute(cell3, 'text', 0) @@ -128,12 +130,14 @@ class BookmarkConfiguration(object): self.wTree.connect_signals(self) # enable drag and drop support - self.list.enable_model_drag_source( - gtk.gdk.BUTTON1_MASK, [drop_yes], gtk.gdk.ACTION_MOVE) - self.list.enable_model_drag_dest( - [drop_yes], gtk.gdk.ACTION_MOVE) - self.list.connect("drag-data-received", self.onDragDataReceived) - self.list.connect("drag-motion", self.onDragMotion) + self.list.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.MOVE) + self.list.enable_model_drag_dest([], Gdk.DragAction.MOVE) + print "config" + self.list.drag_dest_add_text_targets() + self.list.drag_source_add_text_targets() + + self.list.connect("drag_data_received", self.onDragDataReceived) + self.list.connect("drag_data_get", self.onDataGet) # Connect row activation with bookmarks conf self.list.connect("row-activated", self.on_row_activated) @@ -141,7 +145,7 @@ class BookmarkConfiguration(object): def load_data(self): # the meaning of the three columns is: description, id, type - treestore = gtk.TreeStore(str, str, str) + treestore = Gtk.TreeStore(str, str, str) root = self.dataProvider.getRootGroup() self.add_group_data(root, None, treestore) self.list.set_model(treestore) @@ -152,17 +156,19 @@ class BookmarkConfiguration(object): def checkSanity(self, model, source, target): source_path = model.get_path(source) target_path = model.get_path(target) - if target_path[0:len(source_path)] == source_path: + if target_path[0:len(source_path)] == list(source_path): return False else: return True #drag and drop support def checkParentability(self, model, target, drop_position): - if (drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE - or drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER) \ - and (model.get_value(target, 2) == self.RADIO_TYPE or model.get_value(target, 2) == self.SEPARATOR_TYPE): - return False + + if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER): + if(model.get_value(target, 2) == self.RADIO_TYPE or model.get_value(target, 2) == self.SEPARATOR_TYPE): + return False + else: + return True else: return True @@ -174,27 +180,45 @@ class BookmarkConfiguration(object): #drag and drop support def copyRow(self, treeview, model, source, target, drop_position): - - source_row = model[source] - if drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE: - new = model.prepend(target, source_row) - elif drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER: - new = model.append(target, source_row) - elif drop_position == gtk.TREE_VIEW_DROP_BEFORE: - new = model.insert_before(None, target, source_row) - elif drop_position == gtk.TREE_VIEW_DROP_AFTER: - new = model.insert_after(None, target, source_row) + + #source_is_expanded = treeview.row_expanded(model.get_path(source)) + new = None + + if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE) or (drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER): + new = model.append(target, model[source][:]) + + elif drop_position == Gtk.TreeViewDropPosition.BEFORE: + parent = model.iter_parent(target) + new = model.insert_before(parent, target, model[source][:]) + + elif drop_position == Gtk.TreeViewDropPosition.AFTER: + parent = model.iter_parent(target) + new = model.insert_after(parent, target, model[source][:]) + + else: + print "No data copied!" + return - for n in range(model.iter_n_children(source)): - child = model.iter_nth_child(source, n) - self.copyRow(treeview, model, child, new, - gtk.TREE_VIEW_DROP_INTO_OR_BEFORE) + nrChild = range(model.iter_n_children(source)) + while(model.iter_n_children(source) > 0): + child = model.iter_nth_child(source, 0) + self.copyRow(treeview, model, child, new, Gtk.TreeViewDropPosition.INTO_OR_BEFORE) + + model.remove(source) + - source_is_expanded = treeview.row_expanded(model.get_path(source)) - if source_is_expanded: - self.expandToPath(treeview, model.get_path(new)) + + #if source_is_expanded: + # self.expandToPath(treeview, model.get_path(new)) + def onDataGet(self, widget, context, selection, info, time): + treeselection = widget.get_selection() + model, iter = treeselection.get_selected() + data = model.get_value(iter, 0) + selection.set(selection.get_target(), 8, data) + return + #drag and drop support def onDragDataReceived(self, treeview, drag_context, x, y, selection_data, info, eventtime): @@ -208,13 +232,17 @@ class BookmarkConfiguration(object): target = model.get_iter(target_path) sourceName = model.get_value(source,1) targetName = model.get_value(target,1) + + print "source: " + sourceName + " , target: " + targetName; is_sane = self.checkSanity(model, source, target) is_parentable = self.checkParentability(model, target, drop_position) + if is_sane and is_parentable: + self.copyRow(treeview, model, source, target, drop_position) - if (drop_position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE - or drop_position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER): + if (drop_position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE + or drop_position == Gtk.TreeViewDropPosition.INTO_OR_AFTER): treeview.expand_row(target_path, False) drag_context.finish(True, True, eventtime) @@ -223,21 +251,6 @@ class BookmarkConfiguration(object): drag_context.finish(False, False, eventtime) - #drag and drop support - def onDragMotion(self, treeview, drag_context, x, y, eventtime): - try: - target_path, drop_position = treeview.get_dest_row_at_pos(x, y) - model, source = treeview.get_selection().get_selected() - target = model.get_iter(target_path) - except: - return - is_sane = self.checkSanity(model, source, target) - is_parentable = self.checkParentability(model, target, drop_position) - if is_sane and is_parentable: - treeview.enable_model_drag_dest([drop_yes], gtk.gdk.ACTION_MOVE) - else: - treeview.enable_model_drag_dest([drop_no], gtk.gdk.ACTION_MOVE) - @@ -278,7 +291,7 @@ class BookmarkConfiguration(object): self.radioGroupLabel.show() # populate groups - liststore = gtk.ListStore(str) + liststore = Gtk.ListStore(str) for group in self.dataProvider.listGroupNames(): liststore.append([group]) @@ -327,7 +340,7 @@ class BookmarkConfiguration(object): selectedName = model.get_value(iter,1) selectedType = model.get_value(iter, 2) - liststore = gtk.ListStore(str) + liststore = Gtk.ListStore(str) for group in self.dataProvider.listGroupNames(): liststore.append([group]) @@ -456,11 +469,11 @@ class BookmarkConfiguration(object): # if separator then just remove it if not separatorFlag.startswith("[separator-"): - confirmation = gtk.MessageDialog( + confirmation = Gtk.MessageDialog( self.window, - gtk.DIALOG_MODAL, - gtk.MESSAGE_QUESTION, - gtk.BUTTONS_YES_NO, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, _("Are you sure you want to delete \"%s\"?") % selectedRadioName ) @@ -490,7 +503,7 @@ class BookmarkConfiguration(object): # close the window and quit def on_delete_event(self, widget, event, data=None): if self.standalone: - gtk.main_quit() + Gtk.main_quit() return False def on_nameEntry_activated(self, widget): @@ -509,7 +522,7 @@ class BookmarkConfiguration(object): self.groupNameEntry.grab_focus() # populate parent groups - liststore = gtk.ListStore(str) + liststore = Gtk.ListStore(str) for group in self.dataProvider.listGroupNames(): liststore.append([group]) Index: radiotray/src/GuiChooserConfiguration.py =================================================================== --- radiotray.orig/src/GuiChooserConfiguration.py +++ radiotray/src/GuiChooserConfiguration.py @@ -20,16 +20,16 @@ import sys try: - import pygtk - pygtk.require("2.0") + import gi + gi.require_version("Gtk", "3.0") except: pass try: - import gtk - import gtk.glade - import gobject + from gi.repository import Gtk + #import Gtk.glade import os -except: +except Exception as e: + print e sys.exit(1) from lib.common import APP_ICON_ON Index: radiotray/src/NotificationManager.py =================================================================== --- radiotray.orig/src/NotificationManager.py +++ radiotray/src/NotificationManager.py @@ -30,22 +30,23 @@ class NotificationManager(object): self.eventManagerWrapper = eventManagerWrapper self.log = logging.getLogger('radiotray') self.lastState = None - + def on_state_changed(self, data): - + state = data['state'] - + if(state == 'playing' and state != self.lastState): station = data['station'] - self.lastState = state self.eventManagerWrapper.notify(_('Radio Tray Playing'), station) - + self.lastState = state + + def on_song_changed(self, data): - + self.log.debug(data) - + station = data['station'] msgTitle = "%s - %s" % (APPNAME , station) msg = None @@ -53,7 +54,7 @@ class NotificationManager(object): if('artist' in data.keys() and 'title' in data.keys()): artist = data['artist'] title = data['title'] - msg = "%s - %s" % (artist, title) + msg = "%s - %s" % (artist, title) elif('artist' in data.keys()): msg = data['artist'] elif('title' in data.keys()): @@ -70,24 +71,24 @@ class NotificationManager(object): try: f.write(pix) except Exception, e: - log.warn('Error saving icon') + self.log.warn('Error saving icon') finally: f.close() self.eventManagerWrapper.notify_icon(msgTitle, msg, ICON_FILE) - + except Exception, e: traceback.print_exc() self.eventManagerWrapper.notify(msgTitle, msg) else: self.eventManagerWrapper.notify(msgTitle, msg) - + def on_station_error(self, data): - + self.eventManagerWrapper.notify(_('Radio Error'), str(data['error'])) def on_bookmarks_reloaded(self, data): self.eventManagerWrapper.notify(_("Bookmarks Reloaded"), _("Bookmarks Reloaded")) - - + + Index: radiotray/src/Plugin.py =================================================================== --- radiotray.orig/src/Plugin.py +++ radiotray/src/Plugin.py @@ -19,7 +19,7 @@ ########################################################################## import threading -import gtk +from gi.repository import Gtk import logging # This class should be extended by plugins implementations @@ -38,7 +38,7 @@ class Plugin(threading.Thread): self.cfgProvider = cfgProvider self.mediator = mediator self.tooltip = tooltip - self.menuItem = gtk.MenuItem(self.getName(), False) + self.menuItem = Gtk.MenuItem(self.getName()) self.menuItem.connect('activate', self.on_menu) self.menuItem.show() Index: radiotray/src/PluginConfiguration.py =================================================================== --- radiotray.orig/src/PluginConfiguration.py +++ radiotray/src/PluginConfiguration.py @@ -20,19 +20,20 @@ import sys try: - import pygtk - pygtk.require("2.0") + import gi + gi.require_version("Gtk", "3.0") except: pass try: - import gtk - import gtk.glade - import gobject + from gi.repository import Gtk + #import Gtk.glade + from gi.repository import GObject + GObject.threads_init() import os from lib import utils from lib.common import APP_ICON_ON -except: - sys.exit(1) +except Exception as e: + print e import logging class PluginConfiguration(object): @@ -58,17 +59,17 @@ class PluginConfiguration(object): # config plugins view - cell1 = gtk.CellRendererToggle() + cell1 = Gtk.CellRendererToggle() cell1.set_property('activatable', True) cell1.set_activatable(True) - cell1.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE) + cell1.set_property('mode', Gtk.CellRendererMode.ACTIVATABLE) cell1.connect( 'toggled', self.on_toggle, liststore ) - tvcolumn1 = gtk.TreeViewColumn(_('Active'), cell1) + tvcolumn1 = Gtk.TreeViewColumn(_('Active'), cell1) tvcolumn1.add_attribute( cell1, "active", 0) - cell2 = gtk.CellRendererText() - tvcolumn2 = gtk.TreeViewColumn(_('Name'), cell2, text=1) + cell2 = Gtk.CellRendererText() + tvcolumn2 = Gtk.TreeViewColumn(_('Name'), cell2, text=1) self.list.append_column(tvcolumn1) self.list.append_column(tvcolumn2) @@ -88,7 +89,7 @@ class PluginConfiguration(object): # self.cfgProvider.setConfigValue('active_plugins' - liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING) + liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING) plugins = self.pluginManager.getPlugins() for p in plugins: Index: radiotray/src/RadioTray.py =================================================================== --- radiotray.orig/src/RadioTray.py +++ radiotray/src/RadioTray.py @@ -73,6 +73,7 @@ class RadioTray(object): # tooltip manager tooltipManager = TooltipManager() + self.logger.debug("Tooltip manager initialized.") # chooser if(url == '--config'): @@ -82,7 +83,7 @@ class RadioTray(object): url = None # load gui self.systray = SysTray(self.mediator, self.provider, self.cfg_provider, self.default_cfg_provider, eventManager, tooltipManager) - + self.logger.debug("GUI initialized") # notification manager Index: radiotray/src/SysTray.py =================================================================== --- radiotray.orig/src/SysTray.py +++ radiotray/src/SysTray.py @@ -20,17 +20,19 @@ import sys,os import time try: - import pygtk - pygtk.require("2.1") - import gtk -except: + import gi + gi.require_version("Gtk", "3.0") + from gi.repository import Gtk + from gi.repository import Gdk +except Exception as e: + print e pass -try: - import gtk - import gtk.glade - import gobject -except: - sys.exit(1) +#try: + #from gi.repository import Gtk + #import Gtk.glade +#except Exception as e: +# print e +# sys.exit(1) from AudioPlayerGStreamer import AudioPlayerGStreamer from XmlDataProvider import XmlDataProvider @@ -46,7 +48,6 @@ from SysTrayGui import SysTrayGui from AppIndicatorGui import AppIndicatorGui from TooltipManager import TooltipManager from Context import Context -from glib import glib_version import dbus import textwrap @@ -96,7 +97,7 @@ class SysTray(object): # execute gui chooser try: - import appindicator + from gi.repository import AppIndicator3 self.gui_engine = self.cfg_provider.getConfigValue("gui_engine") if(self.gui_engine == None): self.gui_engine = default_cfg_provider.getConfigValue("gui_engine") @@ -114,7 +115,6 @@ class SysTray(object): - if self.gui_engine == "appindicator": self.app_indicator_enabled = True else: @@ -138,10 +138,10 @@ class SysTray(object): ###### Action Events ####### def scroll(self,widget, event): - if event.direction == gtk.gdk.SCROLL_UP: + if event.direction == Gdk.ScrollDirection.UP: self.mediator.volume_up() - if event.direction == gtk.gdk.SCROLL_DOWN: + if event.direction == Gdk.ScrollDirection.DOWN: self.mediator.volume_down() def volume_up(self, menu_item): self.mediator.volume_up() @@ -155,7 +155,7 @@ class SysTray(object): def on_quit(self, data): self.log.info('Exiting...') - gtk.main_quit() + Gtk.main_quit() def on_about(self, data): about_dialog(parent=None) @@ -183,13 +183,10 @@ class SysTray(object): def run(self): - if glib_version < (2, 41, 0): - gtk.gdk.threads_init() - gtk.main() + Gdk.threads_init() + Gtk.main() - - def reload_bookmarks(self, data): self.provider.loadFromFile() Index: radiotray/src/SysTrayGui.py =================================================================== --- radiotray.orig/src/SysTrayGui.py +++ radiotray/src/SysTrayGui.py @@ -18,16 +18,16 @@ # ########################################################################## try: - import pygtk - pygtk.require("2.1") - import gtk + import gi + pyGtk.require("2.1") + from gi.repository import Gtk except: pass try: - import gtk - import gtk.glade - import gobject -except: + from gi.repository import Gtk + #import Gtk.glade +except Exception as e: + print e sys.exit(1) from lib.common import APPNAME, APPVERSION, APP_ICON_ON, APP_ICON_OFF, APP_ICON_CONNECT, APP_INDICATOR_ICON_ON, APP_INDICATOR_ICON_OFF @@ -46,17 +46,17 @@ class SysTrayGui: def buildMenu(self): # radios menu - self.radioMenu = gtk.Menu() + self.radioMenu = Gtk.Menu() if not self.mediator.context.station: - self.turnOnOff = gtk.MenuItem(_("Turned Off"), False) - self.turnOnOff2 = gtk.MenuItem(_("Turned Off"), False) + self.turnOnOff = Gtk.MenuItem(_("Turned Off"), False) + self.turnOnOff2 = Gtk.MenuItem(_("Turned Off"), False) self.turnOnOff.set_sensitive(False) self.turnOnOff2.set_sensitive(False) else: - self.turnOnOff = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False) + self.turnOnOff = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False) self.turnOnOff.set_sensitive(True) - self.turnOnOff2 = gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False) + self.turnOnOff2 = Gtk.MenuItem(_('Turn On "%s"') % self.mediator.context.station, False) self.turnOnOff2.set_sensitive(True) self.turnOnOff.connect('activate', self.handler.on_turn_on_off) @@ -64,34 +64,34 @@ class SysTrayGui: self.update_radios() # config menu - self.menu = gtk.Menu() - self.turnOnOff2 = gtk.MenuItem(_("Turned Off")) + self.menu = Gtk.Menu() + self.turnOnOff2 = Gtk.MenuItem(_("Turned Off")) self.turnOnOff2.connect('activate', self.handler.on_turn_on_off) self.turnOnOff2.set_sensitive(False) - separator = gtk.MenuItem() - menu_item1 = gtk.MenuItem(_("Configure Radios...")) + separator = Gtk.MenuItem() + menu_item1 = Gtk.MenuItem(_("Configure Radios...")) #Check bookmarks file status menu_item1.set_sensitive(self.provider.isBookmarkWritable()) - menu_item4 = gtk.MenuItem(_("Reload Bookmarks")) - menu_item3 = gtk.ImageMenuItem(gtk.STOCK_ABOUT) - menu_item2 = gtk.ImageMenuItem(gtk.STOCK_QUIT) + menu_item4 = Gtk.MenuItem(_("Reload Bookmarks")) + menu_item3 = Gtk.ImageMenuItem(Gtk.STOCK_ABOUT) + menu_item2 = Gtk.ImageMenuItem(Gtk.STOCK_QUIT) self.menu.append(self.turnOnOff2) self.menu.append(separator) self.menu.append(menu_item1) # plugins sub-menu - menu_plugins_item = gtk.MenuItem("Plugins", False) - self.menu_plugins = gtk.Menu() + menu_plugins_item = Gtk.MenuItem("Plugins", False) + self.menu_plugins = Gtk.Menu() menu_plugins_item.set_submenu(self.menu_plugins) - menu_item5 = gtk.MenuItem(_("Configure Plugins...")) + menu_item5 = Gtk.MenuItem(_("Configure Plugins...")) self.menu_plugins.append(menu_item5) - self.menu_plugins.append(gtk.MenuItem()) #add separator + self.menu_plugins.append(Gtk.MenuItem()) #add separator self.menu.append(menu_plugins_item) self.menu.append(menu_item4) - self.menu.append(gtk.MenuItem()) + self.menu.append(Gtk.MenuItem()) self.menu.append(menu_item3) self.menu.append(menu_item2) menu_item1.show() @@ -112,7 +112,7 @@ class SysTrayGui: self.menu.show_all() - self.icon = gtk.status_icon_new_from_file(APP_ICON_OFF) + self.icon = Gtk.status_icon_new_from_file(APP_ICON_OFF) self.icon.set_tooltip_markup(_("Idle (vol: %s%%)") % (self.mediator.getVolume())) self.icon.connect('button_press_event', self.button_press) self.icon.connect('scroll_event', self.handler.scroll) @@ -121,7 +121,7 @@ class SysTrayGui: def button_press(self,widget,event): if(event.button == 1): - self.radioMenu.popup(None, None, gtk.status_icon_position_menu, 0, event.get_time(), widget) + self.radioMenu.popup(None, None, Gtk.status_icon_position_menu, 0, event.get_time(), widget) elif (event.button == 2): if (self.mediator.getContext().state == 'playing'): self.mediator.stop() @@ -129,7 +129,7 @@ class SysTrayGui: if self.mediator.getContext().station: self.mediator.play(self.mediator.getContext().station) else: - self.menu.popup(None, None, gtk.status_icon_position_menu, 2, event.get_time(), widget) + self.menu.popup(None, None, Gtk.status_icon_position_menu, 2, event.get_time(), widget) def update_radios(self): @@ -141,7 +141,7 @@ class SysTrayGui: self.radioMenu.append(self.turnOnOff) self.turnOnOff.show() - separator = gtk.MenuItem() + separator = Gtk.MenuItem() self.radioMenu.append(separator) separator.show() @@ -155,9 +155,9 @@ class SysTrayGui: new_user_data = None if group_name != 'root': - group = gtk.MenuItem(group_name, False) + group = Gtk.MenuItem(group_name, False) user_data.append(group) - new_user_data = gtk.Menu() + new_user_data = Gtk.Menu() group.set_submenu(new_user_data) else: new_user_data = self.radioMenu @@ -168,11 +168,11 @@ class SysTrayGui: def bookmark_callback(self, radio_name, user_data): if radio_name.startswith("[separator-"): - separator = gtk.MenuItem() + separator = Gtk.MenuItem() user_data.append(separator) separator.show() else: - radio = gtk.MenuItem(radio_name, False) + radio = Gtk.MenuItem(radio_name, False) radio.show() radio.connect('activate', self.handler.on_start, radio_name) user_data.append(radio) Index: radiotray/src/XmlDataProvider.py =================================================================== --- radiotray.orig/src/XmlDataProvider.py +++ radiotray/src/XmlDataProvider.py @@ -20,7 +20,7 @@ ########################################################################## import os from lxml import etree -import gtk +from gi.repository import Gtk import logging class XmlDataProvider: @@ -317,13 +317,13 @@ class XmlDataProvider: index = itemTarget.getparent().index(itemTarget) - if (position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE or position == gtk.TREE_VIEW_DROP_INTO_OR_AFTER): + if (position == Gtk.TreeViewDropPosition.INTO_OR_BEFORE or position == Gtk.TreeViewDropPosition.INTO_OR_AFTER): itemTarget.append(itemToMove) - elif position == gtk.TREE_VIEW_DROP_BEFORE: + elif position == Gtk.TreeViewDropPosition.BEFORE: itemTarget.getparent().insert(index, itemToMove) - elif position == gtk.TREE_VIEW_DROP_AFTER: + elif position == Gtk.TreeViewDropPosition.AFTER: itemTarget.getparent().insert(index+1, itemToMove) self.log.debug('%s moved with success', str(source)) Index: radiotray/src/about.py =================================================================== --- radiotray.orig/src/about.py +++ radiotray/src/about.py @@ -1,29 +1,29 @@ # -*- coding: utf-8 -*- -import gtk +from gi.repository import Gtk, GObject, Gdk, GdkPixbuf from lib import i18n import lib.common as common def on_email(about, mail): - gtk.show_uri(gtk.gdk.Screen(), "mailto:%s" % mail, 0L) + Gtk.show_uri(Gdk.Screen(), "mailto:%s" % mail, 0L) def on_url(about, link): - gtk.show_uri(gtk.gdk.Screen(), link, 0L) + Gtk.show_uri(Gdk.Screen(), link, 0L) -gtk.about_dialog_set_email_hook(on_email) -gtk.about_dialog_set_url_hook(on_url) +#Gtk.about_dialog_set_email_hook(on_email) +#Gtk.about_dialog_set_url_hook(on_url) TRANSLATORS = _("translator-credits") -class AboutDialog(gtk.AboutDialog): +class AboutDialog(Gtk.AboutDialog): def __init__(self, parent = None): - gtk.AboutDialog.__init__(self) + GObject.GObject.__init__(self) self.set_icon_from_file(common.APP_ICON) self.set_name(common.APPNAME) self.set_version(common.APPVERSION) self.set_copyright(common.COPYRIGHTS) - self.set_logo(gtk.gdk.pixbuf_new_from_file(common.APP_ICON)) + self.set_logo(GdkPixbuf.Pixbuf.new_from_file(common.APP_ICON)) self.set_translator_credits(TRANSLATORS) self.set_license(common.LICENSE) self.set_website(common.WEBSITE) Index: radiotray/src/lib/i18n.py =================================================================== --- radiotray.orig/src/lib/i18n.py +++ radiotray/src/lib/i18n.py @@ -12,7 +12,8 @@ try: from gettext import gettext as _, ngettext gettext.install(program, unicode=True) gettext.textdomain(program) - locale.textdomain(program) + if hasattr(locale, 'textdomain'): + locale.textdomain(program) def C_(ctx, s): """Provide qualified translatable strings via context. Index: radiotray/src/lib/utils.py =================================================================== --- radiotray.orig/src/lib/utils.py +++ radiotray/src/lib/utils.py @@ -20,15 +20,15 @@ from os.path import exists, join try: - import pygtk - pygtk.require("2.0") + import gi + gi.require_version("Gtk", "3.0") import dbus import dbus.service except: pass try: - import gtk + from gi.repository import Gtk except ImportError, e: print str(e) raise SystemExit @@ -36,7 +36,7 @@ except ImportError, e: def load_ui_file(name): import common - ui = gtk.Builder() + ui = Gtk.Builder() ui.add_from_file(join(common.DEFAULT_CFG_PATH, name)) return ui Index: radiotray/src/radiotray.py =================================================================== --- radiotray.orig/src/radiotray.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import dbus -import sys, os, string -from RadioTray import RadioTray -from dbus import DBusException -from dbus.mainloop.glib import threads_init - -threads_init() -current_path = os.path.realpath(__file__) -basedir = os.path.dirname(os.path.realpath(__file__)) -if not os.path.exists(os.path.join(basedir, "radiotray.py")): - if os.path.exists(os.path.join(os.getcwd(), "radiotray.py")): - basedir = os.getcwd() -sys.path.insert(0, basedir) -os.chdir(basedir) - -def main(argv): - if(len(argv) == 1): - print "Trying to load URL: " + argv[0] - - try: - bus = dbus.SessionBus() - radiotray = bus.get_object('net.sourceforge.radiotray', '/net/sourceforge/radiotray') - - - if argv[0] == '--config': - print "Radio Tray already running." - else: - print "Setting current radio through DBus..." - - playUrl = radiotray.get_dbus_method('playUrl', 'net.sourceforge.radiotray') - playUrl(argv[0]) - - except DBusException: - RadioTray(argv[0]) - else: - RadioTray() - -if __name__ == "__main__": - main(sys.argv[1:]) Index: radiotray/src/radiotray_runner.py =================================================================== --- /dev/null +++ radiotray/src/radiotray_runner.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +import dbus +import sys, os, string +from RadioTray import RadioTray +from dbus import DBusException +from dbus.mainloop.glib import threads_init + +threads_init() +current_path = os.path.realpath(__file__) +basedir = os.path.dirname(os.path.realpath(__file__)) +if not os.path.exists(os.path.join(basedir, "radiotray.py")): + if os.path.exists(os.path.join(os.getcwd(), "radiotray.py")): + basedir = os.getcwd() +sys.path.insert(0, basedir) +os.chdir(basedir) + +def main(argv): + if(len(argv) == 1): + print "Trying to load URL: " + argv[0] + + try: + bus = dbus.SessionBus() + radiotray = bus.get_object('net.sourceforge.radiotray', '/net/sourceforge/radiotray') + + + if argv[0] == '--config': + print "Radio Tray already running." + else: + print "Setting current radio through DBus..." + + playUrl = radiotray.get_dbus_method('playUrl', 'net.sourceforge.radiotray') + playUrl(argv[0]) + + except DBusException: + RadioTray(argv[0]) + else: + RadioTray() + +if __name__ == "__main__": + main(sys.argv[1:])