diff --git a/deluge/ui/gtkui/dbusinterface.py b/deluge/ui/gtkui/dbusinterface.py index 0c91a28e7..719489210 100644 --- a/deluge/ui/gtkui/dbusinterface.py +++ b/deluge/ui/gtkui/dbusinterface.py @@ -34,8 +34,9 @@ import sys import os +import gtk +import gobject # Import DBUS -#from dbus import Interface, SessionBus, version import dbus, dbus.service if dbus.version >= (0,41,0) and dbus.version < (0,80,0): @@ -51,8 +52,9 @@ from deluge.log import LOG as log class DbusInterface(dbus.service.Object, component.Component): def __init__(self, args, path="/org/deluge_torrent/Deluge"): - component.Component.__init__(self, "DbusInterface") - + component.Component.__init__(self, "DbusInterface", ["StatusBar"]) + self.queue = [] + self.widgets = None # Check to see if the daemon is already running and if not, start it bus = dbus.SessionBus() obj = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") @@ -79,12 +81,66 @@ class DbusInterface(dbus.service.Object, component.Component): log.debug("Exiting..") sys.exit(0) + # Process the args if any + self.process_args(args) # Register Deluge with Dbus log.info("Registering with DBUS..") bus_name = dbus.service.BusName("org.deluge_torrent.Deluge", bus=dbus.SessionBus()) dbus.service.Object.__init__(self, bus_name, path) + def start(self): + """Called when we connect to a host""" + log.debug("DbusInterface start..") + if len(self.queue) == 0: + return + # Make sure status bar info is showing + self.widgets = None + self.update_status_bar() + + def add_to_queue(self, torrents): + """Adds the list of torrents to the queue""" + # Add to the queue while removing duplicates + self.queue = list(set(self.queue + torrents)) + + # Update the status bar + self.update_status_bar() + + def update_status_bar(self): + """Attempts to update status bar""" + # If there are no queued torrents.. remove statusbar widgets and return + if len(self.queue) == 0: + if self.widgets != None: + for widget in self.widgets: + component.get("StatusBar").remove(widget) + return False + + try: + statusbar = component.get("StatusBar") + except Exception, e: + # The statusbar hasn't been loaded yet, so we'll add a timer to + # update it later. + gobject.timeout_add(100, self.update_status_bar) + return False + + # Set the label text for statusbar + if len(self.queue) > 1: + label = str(len(self.queue)) + _(" Torrents Queued") + else: + label = str(len(self.queue)) + _(" Torrent Queued") + + # Add the statusbar items if needed, or just modify the label if they + # have already been added. + if self.widgets == None: + self.widgets = component.get("StatusBar").add_item( + stock=gtk.STOCK_SORT_DESCENDING, + text=label) + else: + self.widgets[1].set_text(label) + + # We return False so the timer stops + return False + @dbus.service.method("org.deluge_torrent.Deluge", in_signature="as") def process_args(self, args): """Process arguments sent to already running Deluge""" @@ -94,16 +150,20 @@ class DbusInterface(dbus.service.Object, component.Component): for arg in dbus_args: args.append(str(arg)) log.debug("Processing args from other process: %s", args) + if not client.connected(): + # We're not connected so add these to the queue + log.debug("Not connected to host.. Adding to queue.") + self.add_to_queue(args) + return + for arg in args: - # Check to see if we're connected to a host first - if client.connected(): - if deluge.common.is_url(arg): - log.debug("Attempting to add %s from external source..", - arg) - client.add_torrent_url(arg) - else: - # Just a file - log.debug("Attempting to add %s from external source..", - os.path.abspath(arg)) - client.add_torrent_file([os.path.abspath(arg)]) - + if deluge.common.is_url(arg): + log.debug("Attempting to add %s from external source..", + arg) + client.add_torrent_url(arg) + else: + # Just a file + log.debug("Attempting to add %s from external source..", + os.path.abspath(arg)) + client.add_torrent_file([os.path.abspath(arg)]) + diff --git a/deluge/ui/gtkui/glade/queuedtorrents.glade b/deluge/ui/gtkui/glade/queuedtorrents.glade new file mode 100644 index 000000000..dc59ada44 --- /dev/null +++ b/deluge/ui/gtkui/glade/queuedtorrents.glade @@ -0,0 +1,210 @@ + + + + + + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + GTK_WIN_POS_CENTER_ON_PARENT + True + . + GDK_WINDOW_TYPE_HINT_DIALOG + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + + + False + False + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <big><b>Add Queued Torrents</b></big> + True + + + False + False + 1 + + + + + False + False + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_START + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-remove + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-clear + True + 0 + + + + 1 + + + + + False + False + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 11 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Automatically add torrents on connect + 0 + True + + + False + False + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Options + + + label_item + + + + + 3 + + + + + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GTK_BUTTONBOX_END + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-cancel + True + 0 + + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + True + 0 + + + + 1 + + + + + False + GTK_PACK_END + + + + + + diff --git a/deluge/ui/gtkui/statusbar.py b/deluge/ui/gtkui/statusbar.py index ffe36710d..3914a3075 100644 --- a/deluge/ui/gtkui/statusbar.py +++ b/deluge/ui/gtkui/statusbar.py @@ -86,10 +86,44 @@ class StatusBar(component.Component): image = gtk.Image() image.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU) self.hbox.pack_start(image, expand=False, fill=False) - label = gtk.Label("Not connected to daemon..") + label = gtk.Label(_("Not Connected")) self.hbox.pack_start(label, expand=False, fill=False) self.statusbar.show_all() + def add_item(self, image=None, stock=None, text=None): + """Adds an item to the status bar""" + # The return tuple.. we return whatever widgets we add + ret = [] + # Add image from file or stock + if image != None or stock != None: + _image = gtk.Image() + if image != None: + _image.set_from_file(image) + if stock != None: + _image.set_from_stock(stock, gtk.ICON_SIZE_MENU) + self.hbox.pack_start(_image, expand=False, fill=False) + ret.append(_image) + + # Add text + if text != None: + label = gtk.Label(text) + self.hbox.pack_start(label, expand=False, fill=False) + ret.append(label) + + # Show the widgets + for widget in ret: + widget.show() + + # Return the widgets + return tuple(ret) + + def remove_item(self, widget): + """Removes an item from the statusbar""" + try: + self.hbox.remove(widget) + except Exception, e: + log.debug("Unable to remove widget: %s", e) + def clear_statusbar(self): def remove(child): self.hbox.remove(child)