Change the gtkui to a new component based system.
Properly handle daemon quitting unexpectedly. Many updates to the ConnectionManager.
This commit is contained in:
parent
d5888131a0
commit
c4d4e75667
|
@ -74,7 +74,7 @@ DEFAULT_PREFS = {
|
|||
"max_upload_slots_global": -1,
|
||||
"max_connections_per_torrent": -1,
|
||||
"max_upload_slots_per_torrent": -1,
|
||||
"enabled_plugins": ["Queue"]
|
||||
"enabled_plugins": []
|
||||
}
|
||||
|
||||
class Core(
|
||||
|
|
|
@ -65,7 +65,7 @@ class PluginManagerBase:
|
|||
def shutdown(self):
|
||||
log.debug("PluginManager shutting down..")
|
||||
for plugin in self.plugins.values():
|
||||
plugin.core.shutdown()
|
||||
plugin.disable()
|
||||
del self.plugins
|
||||
|
||||
def __getitem__(self, key):
|
||||
|
@ -113,9 +113,11 @@ class PluginManagerBase:
|
|||
|
||||
def disable_plugin(self, name):
|
||||
"""Disables a plugin"""
|
||||
try:
|
||||
|
||||
self.plugins[name].disable()
|
||||
|
||||
del self.plugins[name]
|
||||
except:
|
||||
log.warning("Unable to disable non-existant plugin %s", name)
|
||||
# except:
|
||||
# log.warning("Unable to disable non-existant plugin %s", name)
|
||||
|
||||
log.info("Plugin %s disabled..", name)
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
import os.path
|
||||
import pickle
|
||||
import socket
|
||||
|
||||
import deluge.xmlrpclib as xmlrpclib
|
||||
|
||||
|
@ -48,17 +49,32 @@ class CoreProxy:
|
|||
self._uri = None
|
||||
self._core = None
|
||||
self._on_new_core_callbacks = []
|
||||
self._on_no_core_callbacks = []
|
||||
|
||||
def connect_on_new_core(self, callback):
|
||||
"""Connect a callback to be called when a new core is connected to."""
|
||||
self._on_new_core_callbacks.append(callback)
|
||||
|
||||
def connect_on_no_core(self, callback):
|
||||
"""Connect a callback to be called when the current core is disconnected
|
||||
from."""
|
||||
self._on_no_core_callbacks.append(callback)
|
||||
|
||||
def set_core_uri(self, uri):
|
||||
log.info("Setting core uri as %s", uri)
|
||||
self._uri = uri
|
||||
if self._uri == None:
|
||||
for callback in self._on_no_core_callbacks:
|
||||
callback()
|
||||
self._core = None
|
||||
else:
|
||||
# Get a new core
|
||||
self.get_core()
|
||||
|
||||
def get_core_uri(self):
|
||||
"""Returns the URI of the core currently being used."""
|
||||
return self._uri
|
||||
|
||||
def get_core(self):
|
||||
if self._core is None and self._uri is not None:
|
||||
log.debug("Creating ServerProxy..")
|
||||
|
@ -88,13 +104,24 @@ def connect_on_new_core(callback):
|
|||
"""Connect a callback whenever a new core is connected to."""
|
||||
return _core.connect_on_new_core(callback)
|
||||
|
||||
def connect_on_no_core(callback):
|
||||
"""Connect a callback whenever the core is disconnected from."""
|
||||
return _core.connect_on_no_core(callback)
|
||||
|
||||
def set_core_uri(uri):
|
||||
"""Sets the core uri"""
|
||||
return _core.set_core_uri(uri)
|
||||
|
||||
def get_core_uri():
|
||||
"""Get the core URI"""
|
||||
return _core.get_core_uri()
|
||||
|
||||
def shutdown():
|
||||
"""Shutdown the core daemon"""
|
||||
try:
|
||||
get_core().shutdown()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def add_torrent_file(torrent_files):
|
||||
"""Adds torrent files to the core
|
||||
|
@ -112,7 +139,11 @@ def add_torrent_file(torrent_files):
|
|||
(path, filename) = os.path.split(torrent_file)
|
||||
fdump = xmlrpclib.Binary(f.read())
|
||||
f.close()
|
||||
try:
|
||||
result = get_core().add_torrent_file(filename, str(), fdump)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
result = False
|
||||
|
||||
if result is False:
|
||||
# The torrent was not added successfully.
|
||||
|
@ -122,7 +153,12 @@ def add_torrent_url(torrent_url):
|
|||
"""Adds torrents to the core via url"""
|
||||
from deluge.common import is_url
|
||||
if is_url(torrent_url):
|
||||
try:
|
||||
result = get_core().add_torrent_url(torrent_url, str())
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
result = False
|
||||
|
||||
if result is False:
|
||||
# The torrent url was not added successfully.
|
||||
log.warning("Torrent %s was not added successfully.", torrent_url)
|
||||
|
@ -132,61 +168,124 @@ def add_torrent_url(torrent_url):
|
|||
def remove_torrent(torrent_ids):
|
||||
"""Removes torrent_ids from the core.. Expects a list of torrent_ids"""
|
||||
log.debug("Attempting to removing torrents: %s", torrent_ids)
|
||||
try:
|
||||
for torrent_id in torrent_ids:
|
||||
get_core().remove_torrent(torrent_id)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def pause_torrent(torrent_ids):
|
||||
"""Pauses torrent_ids"""
|
||||
try:
|
||||
for torrent_id in torrent_ids:
|
||||
get_core().pause_torrent(torrent_id)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def resume_torrent(torrent_ids):
|
||||
"""Resume torrent_ids"""
|
||||
try:
|
||||
for torrent_id in torrent_ids:
|
||||
get_core().resume_torrent(torrent_id)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def force_reannounce(torrent_ids):
|
||||
"""Reannounce to trackers"""
|
||||
try:
|
||||
for torrent_id in torrent_ids:
|
||||
get_core().force_reannounce(torrent_id)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def get_torrent_status(torrent_id, keys):
|
||||
"""Builds the status dictionary and returns it"""
|
||||
try:
|
||||
status = get_core().get_torrent_status(torrent_id, keys)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
return {}
|
||||
return pickle.loads(status.data)
|
||||
|
||||
def get_session_state():
|
||||
return get_core().get_session_state()
|
||||
|
||||
try:
|
||||
state = get_core().get_session_state()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
state = []
|
||||
return state
|
||||
|
||||
def get_config():
|
||||
return get_core().get_config()
|
||||
try:
|
||||
config = get_core().get_config()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
config = {}
|
||||
return config
|
||||
|
||||
def get_config_value(key):
|
||||
return get_core().get_config_value(key)
|
||||
try:
|
||||
config_value = get_core().get_config_value(key)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
config_value = None
|
||||
return config_value
|
||||
|
||||
def set_config(config):
|
||||
if config == {}:
|
||||
return
|
||||
try:
|
||||
get_core().set_config(config)
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
|
||||
def get_listen_port():
|
||||
return int(get_core().get_listen_port())
|
||||
try:
|
||||
port = get_core().get_listen_port()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
port = 0
|
||||
return int(port)
|
||||
|
||||
def get_available_plugins():
|
||||
return get_core().get_available_plugins()
|
||||
try:
|
||||
available = get_core().get_available_plugins()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
available = []
|
||||
return available
|
||||
|
||||
def get_enabled_plugins():
|
||||
return get_core().get_enabled_plugins()
|
||||
try:
|
||||
enabled = get_core().get_enabled_plugins()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
enabled = []
|
||||
return enabled
|
||||
|
||||
def get_download_rate():
|
||||
return get_core().get_download_rate()
|
||||
try:
|
||||
rate = get_core().get_download_rate()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
rate = -1
|
||||
return rate
|
||||
|
||||
def get_upload_rate():
|
||||
return get_core().get_upload_rate()
|
||||
try:
|
||||
rate = get_core().get_upload_rate()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
rate = -1
|
||||
return rate
|
||||
|
||||
def get_num_connections():
|
||||
return get_core().get_num_connections()
|
||||
try:
|
||||
num_connections = get_core().get_num_connections()
|
||||
except (AttributeError, socket.error):
|
||||
set_core_uri(None)
|
||||
num_connections = 0
|
||||
return num_connections
|
||||
|
||||
def open_url_in_browser(url):
|
||||
"""Opens link in the desktop's default browser"""
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
#
|
||||
# component.py
|
||||
#
|
||||
# Copyright (C) 2007 Andrew Resch ('andar') <andrewresch@gmail.com>
|
||||
#
|
||||
# Deluge is free software.
|
||||
#
|
||||
# You may redistribute it and/or modify it under the terms of the
|
||||
# GNU General Public License, as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# deluge 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 deluge. If not, write to:
|
||||
# The Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# In addition, as a special exception, the copyright holders give
|
||||
# permission to link the code of portions of this program with the OpenSSL
|
||||
# library.
|
||||
# You must obey the GNU General Public License in all respects for all of
|
||||
# the code used other than OpenSSL. If you modify file(s) with this
|
||||
# exception, you may extend this exception to your version of the file(s),
|
||||
# but you are not obligated to do so. If you do not wish to do so, delete
|
||||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
import gobject
|
||||
from deluge.log import LOG as log
|
||||
|
||||
COMPONENT_STATE = [
|
||||
"Stopped",
|
||||
"Started"
|
||||
]
|
||||
|
||||
class Component:
|
||||
def __init__(self, name):
|
||||
# Register with the ComponentRegistry
|
||||
register(name, self)
|
||||
self._state = COMPONENT_STATE.index("Stopped")
|
||||
|
||||
def get_state(self):
|
||||
return self._state
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def _start(self):
|
||||
self._state = COMPONENT_STATE.index("Started")
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def _stop(self):
|
||||
self._state = COMPONENT_STATE.index("Stopped")
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
|
||||
class ComponentRegistry:
|
||||
def __init__(self):
|
||||
self.components = {}
|
||||
#self.component_state = {}
|
||||
self.update_timer = None
|
||||
|
||||
def register(self, name, obj):
|
||||
"""Registers a component"""
|
||||
log.debug("Registered %s with ComponentRegistry..", name)
|
||||
self.components[name] = obj
|
||||
|
||||
def get(self, name):
|
||||
"""Returns a reference to the component 'name'"""
|
||||
return self.components[name]
|
||||
|
||||
def start(self, update_interval=1000):
|
||||
"""Starts all components"""
|
||||
for component in self.components.keys():
|
||||
self.components[component].start()
|
||||
self.components[component]._start()
|
||||
|
||||
# Start the update timer
|
||||
self.update_timer = gobject.timeout_add(update_interval, self.update)
|
||||
# Do an update right away
|
||||
self.update()
|
||||
|
||||
def stop(self):
|
||||
"""Stops all components"""
|
||||
for component in self.components.keys():
|
||||
self.components[component].stop()
|
||||
self.components[component]._stop()
|
||||
# Stop the update timer
|
||||
gobject.source_remove(self.update_timer)
|
||||
|
||||
def update(self):
|
||||
"""Updates all components"""
|
||||
for component in self.components.keys():
|
||||
# Only update the component if it's started
|
||||
if self.components[component].get_state() == \
|
||||
COMPONENT_STATE.index("Started"):
|
||||
self.components[component].update()
|
||||
|
||||
return True
|
||||
|
||||
_ComponentRegistry = ComponentRegistry()
|
||||
|
||||
def register(name, obj):
|
||||
"""Registers a UI component with the registry"""
|
||||
_ComponentRegistry.register(name, obj)
|
||||
|
||||
def start():
|
||||
"""Starts all components"""
|
||||
_ComponentRegistry.start()
|
||||
|
||||
def stop():
|
||||
"""Stops all components"""
|
||||
_ComponentRegistry.stop()
|
||||
|
||||
def update():
|
||||
"""Updates all components"""
|
||||
_ComponentRegistry.update()
|
||||
|
||||
def get(component):
|
||||
"""Return a reference to the component"""
|
||||
return _ComponentRegistry.get(component)
|
|
@ -36,6 +36,7 @@ import pkg_resources
|
|||
import gobject
|
||||
import socket
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.xmlrpclib as xmlrpclib
|
||||
import deluge.common
|
||||
import deluge.ui.client as client
|
||||
|
@ -46,14 +47,24 @@ DEFAULT_CONFIG = {
|
|||
"hosts": ["localhost:58846"]
|
||||
}
|
||||
|
||||
class ConnectionManager:
|
||||
def __init__(self, window):
|
||||
HOSTLIST_COL_PIXBUF = 0
|
||||
HOSTLIST_COL_URI = 1
|
||||
HOSTLIST_COL_STATUS = 2
|
||||
|
||||
HOSTLIST_STATUS = [
|
||||
"Offline",
|
||||
"Online",
|
||||
"Connected"
|
||||
]
|
||||
class ConnectionManager(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "ConnectionManager")
|
||||
# Get the glade file for the connection manager
|
||||
self.glade = gtk.glade.XML(
|
||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||
"glade/connection_manager.glade"))
|
||||
|
||||
self.window = window
|
||||
self.window = component.get("MainWindow")
|
||||
self.config = ConfigManager("hostlist.conf", DEFAULT_CONFIG)
|
||||
self.connection_manager = self.glade.get_widget("connection_manager")
|
||||
self.hostlist = self.glade.get_widget("hostlist")
|
||||
|
@ -62,20 +73,21 @@ class ConnectionManager:
|
|||
self.glade.get_widget("image1").set_from_pixbuf(
|
||||
deluge.common.get_logo(32))
|
||||
|
||||
self.liststore = gtk.ListStore(gtk.gdk.Pixbuf, str)
|
||||
self.liststore = gtk.ListStore(gtk.gdk.Pixbuf, str, int)
|
||||
|
||||
# Fill in hosts from config file
|
||||
for host in self.config["hosts"]:
|
||||
row = self.liststore.append()
|
||||
self.liststore.set_value(row, 1, host)
|
||||
self.liststore.set_value(row, HOSTLIST_COL_URI, host)
|
||||
|
||||
# Setup host list treeview
|
||||
self.hostlist.set_model(self.liststore)
|
||||
render = gtk.CellRendererPixbuf()
|
||||
column = gtk.TreeViewColumn("Status", render, pixbuf=0)
|
||||
column = gtk.TreeViewColumn(
|
||||
"Status", render, pixbuf=HOSTLIST_COL_PIXBUF)
|
||||
self.hostlist.append_column(column)
|
||||
render = gtk.CellRendererText()
|
||||
column = gtk.TreeViewColumn("Host", render, text=1)
|
||||
column = gtk.TreeViewColumn("Host", render, text=HOSTLIST_COL_URI)
|
||||
self.hostlist.append_column(column)
|
||||
|
||||
self.glade.signal_autoconnect({
|
||||
|
@ -83,60 +95,126 @@ class ConnectionManager:
|
|||
"on_button_removehost_clicked": self.on_button_removehost_clicked,
|
||||
"on_button_startdaemon_clicked": \
|
||||
self.on_button_startdaemon_clicked,
|
||||
"on_button_cancel_clicked": self.on_button_cancel_clicked,
|
||||
"on_button_close_clicked": self.on_button_close_clicked,
|
||||
"on_button_connect_clicked": self.on_button_connect_clicked,
|
||||
})
|
||||
|
||||
self.connection_manager.connect("delete-event", self.on_delete_event)
|
||||
# Connect to the 'changed' event of TreeViewSelection to get selection
|
||||
# changes.
|
||||
self.hostlist.get_selection().connect("changed",
|
||||
self.on_selection_changed)
|
||||
|
||||
def show(self):
|
||||
self.update_timer = gobject.timeout_add(5000, self.update)
|
||||
self.update()
|
||||
self._update_timer = gobject.timeout_add(5000, self._update)
|
||||
self._update()
|
||||
self.connection_manager.show_all()
|
||||
|
||||
def hide(self):
|
||||
self.connection_manager.hide()
|
||||
gobject.source_remove(self.update_timer)
|
||||
gobject.source_remove(self._update_timer)
|
||||
|
||||
def update(self):
|
||||
def _update(self):
|
||||
"""Updates the host status"""
|
||||
def update_row(model=None, path=None, row=None, columns=None):
|
||||
uri = model.get_value(row, 1)
|
||||
uri = model.get_value(row, HOSTLIST_COL_URI)
|
||||
uri = "http://" + uri
|
||||
online = self.test_online_status(uri)
|
||||
|
||||
if online:
|
||||
image = gtk.STOCK_YES
|
||||
online = HOSTLIST_STATUS.index("Online")
|
||||
else:
|
||||
image = gtk.STOCK_NO
|
||||
online = HOSTLIST_STATUS.index("Offline")
|
||||
|
||||
if uri == current_uri:
|
||||
# We are connected to this host, so lets display the connected
|
||||
# icon.
|
||||
image = gtk.STOCK_CONNECT
|
||||
online = HOSTLIST_STATUS.index("Connected")
|
||||
|
||||
pixbuf = self.connection_manager.render_icon(
|
||||
image, gtk.ICON_SIZE_MENU)
|
||||
|
||||
model.set_value(row, HOSTLIST_COL_PIXBUF, pixbuf)
|
||||
model.set_value(row, HOSTLIST_COL_STATUS, online)
|
||||
|
||||
current_uri = client.get_core_uri()
|
||||
self.liststore.foreach(update_row)
|
||||
# Update the buttons
|
||||
self.update_buttons()
|
||||
return True
|
||||
|
||||
def update_buttons(self):
|
||||
"""Updates the buttons based on selection"""
|
||||
# Get the selected row's URI
|
||||
paths = self.hostlist.get_selection().get_selected_rows()[1]
|
||||
# If nothing is selected, just return
|
||||
if len(paths) < 1:
|
||||
return
|
||||
row = self.liststore.get_iter(paths[0])
|
||||
uri = self.liststore.get_value(row, HOSTLIST_COL_URI)
|
||||
status = self.liststore.get_value(row, HOSTLIST_COL_STATUS)
|
||||
|
||||
# Check to see if a localhost is selected
|
||||
localhost = False
|
||||
if uri.split(":")[0] == "localhost" or uri.split(":")[0] == "127.0.0.1":
|
||||
localhost = True
|
||||
|
||||
# Make actual URI string
|
||||
uri = "http://" + uri
|
||||
|
||||
# See if this is the currently connected URI
|
||||
if status == HOSTLIST_STATUS.index("Connected"):
|
||||
# Display a disconnect button if we're connected to this host
|
||||
self.glade.get_widget("button_connect").set_label("gtk-disconnect")
|
||||
else:
|
||||
self.glade.get_widget("button_connect").set_label("gtk-connect")
|
||||
|
||||
# Update the start daemon button if the selected host is localhost
|
||||
if localhost:
|
||||
# Check to see if the host is online
|
||||
if status == HOSTLIST_STATUS.index("Connected") \
|
||||
or status == HOSTLIST_STATUS.index("Online"):
|
||||
self.glade.get_widget("image_startdaemon").set_from_stock(
|
||||
gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
|
||||
self.glade.get_widget("label_startdaemon").set_text(
|
||||
"_Stop local daemon")
|
||||
else:
|
||||
# The localhost is not online
|
||||
self.glade.get_widget("image_startdaemon").set_from_stock(
|
||||
gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU)
|
||||
self.glade.get_widget("label_startdaemon").set_text(
|
||||
"_Start local daemon")
|
||||
# Make sure label is displayed correctly using mnemonics
|
||||
self.glade.get_widget("label_startdaemon").set_use_underline(
|
||||
True)
|
||||
|
||||
def save(self):
|
||||
"""Save the current host list to file"""
|
||||
def append_row(model=None, path=None, row=None, columns=None):
|
||||
hostlist.append(model.get_value(row, HOSTLIST_COL_URI))
|
||||
|
||||
hostlist = []
|
||||
self.liststore.foreach(append_row, hostlist)
|
||||
self.config["hosts"] = hostlist
|
||||
self.config.save()
|
||||
|
||||
def test_online_status(self, uri):
|
||||
"""Tests the status of URI.. Returns True or False depending on status.
|
||||
"""
|
||||
online = True
|
||||
host = None
|
||||
try:
|
||||
host = xmlrpclib.ServerProxy(uri)
|
||||
host.ping()
|
||||
except socket.error:
|
||||
print "socket.error!"
|
||||
online = False
|
||||
|
||||
print "online: ", online
|
||||
del host
|
||||
|
||||
if online:
|
||||
image = gtk.STOCK_YES
|
||||
else:
|
||||
image = gtk.STOCK_NO
|
||||
|
||||
pixbuf = self.connection_manager.render_icon(
|
||||
image, gtk.ICON_SIZE_MENU)
|
||||
|
||||
model.set_value(row, 0, pixbuf)
|
||||
|
||||
self.liststore.foreach(update_row)
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
"""Save the current host list to file"""
|
||||
def append_row(model=None, path=None, row=None, columns=None):
|
||||
hostlist.append(model.get_value(row, 1))
|
||||
|
||||
hostlist = []
|
||||
self.liststore.foreach(append_row, hostlist)
|
||||
self.config["hosts"] = hostlist
|
||||
self.config.save()
|
||||
return online
|
||||
|
||||
## Callbacks
|
||||
def on_delete_event(self, widget, event):
|
||||
|
@ -165,9 +243,11 @@ class ConnectionManager:
|
|||
port = port_spinbutton.get_value_as_int()
|
||||
hostname = hostname + ":" + str(port)
|
||||
row = self.liststore.append()
|
||||
self.liststore.set_value(row, 1, hostname)
|
||||
self.liststore.set_value(row, HOSTLIST_COL_URI, hostname)
|
||||
# Save the host list to file
|
||||
self.save()
|
||||
# Update the status of the hosts
|
||||
self._update()
|
||||
|
||||
dialog.hide()
|
||||
|
||||
|
@ -184,16 +264,36 @@ class ConnectionManager:
|
|||
def on_button_startdaemon_clicked(self, widget):
|
||||
log.debug("on_button_startdaemon_clicked")
|
||||
|
||||
def on_button_cancel_clicked(self, widget):
|
||||
log.debug("on_button_cancel_clicked")
|
||||
def on_button_close_clicked(self, widget):
|
||||
log.debug("on_button_close_clicked")
|
||||
self.hide()
|
||||
|
||||
def on_button_connect_clicked(self, widget):
|
||||
log.debug("on_button_connect_clicked")
|
||||
paths = self.hostlist.get_selection().get_selected_rows()[1]
|
||||
row = self.liststore.get_iter(paths[0])
|
||||
uri = self.liststore.get_value(row, 1)
|
||||
status = self.liststore.get_value(row, HOSTLIST_COL_STATUS)
|
||||
uri = self.liststore.get_value(row, HOSTLIST_COL_URI)
|
||||
uri = "http://" + uri
|
||||
if status == HOSTLIST_STATUS.index("Connected"):
|
||||
# If we are connected to this host, then we will disconnect.
|
||||
client.set_core_uri(None)
|
||||
self._update()
|
||||
return
|
||||
|
||||
# Test the host to see if it is online or not. We don't use the status
|
||||
# column information because it can be up to 5 seconds out of sync.
|
||||
if not self.test_online_status(uri):
|
||||
log.warning("Host does not appear to be online..")
|
||||
# Update the list to show proper status
|
||||
self._update()
|
||||
return
|
||||
|
||||
# Status is OK, so lets change to this host
|
||||
client.set_core_uri(uri)
|
||||
self.window.start()
|
||||
self.hide()
|
||||
|
||||
def on_selection_changed(self, treeselection):
|
||||
log.debug("on_selection_changed")
|
||||
self.update_buttons()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--Generated with glade3 3.2.2 on Tue Oct 16 23:05:06 2007 by andrew@fragment-->
|
||||
<!--Generated with glade3 3.2.0 on Sat Oct 20 14:16:39 2007 by andrew@delicious-->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="connection_manager">
|
||||
<property name="has_focus">True</property>
|
||||
|
@ -99,7 +99,6 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-add</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_button_addhost_clicked"/>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -111,7 +110,6 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-remove</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_button_removehost_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -130,7 +128,6 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_button_startdaemon_clicked"/>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox4">
|
||||
|
@ -138,14 +135,14 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image2">
|
||||
<widget class="GtkImage" id="image_startdaemon">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-execute</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<widget class="GtkLabel" id="label_startdaemon">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">_Start local daemon</property>
|
||||
|
@ -193,7 +190,6 @@
|
|||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">checkbutton</property>
|
||||
<property name="response_id">0</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
@ -221,15 +217,14 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="button_cancel">
|
||||
<widget class="GtkButton" id="button_close">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="label" translatable="yes">gtk-close</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_button_cancel_clicked"/>
|
||||
<signal name="clicked" handler="on_button_close_clicked"/>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -240,7 +235,6 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-connect</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<signal name="clicked" handler="on_button_connect_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
|
@ -344,7 +338,6 @@
|
|||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
|
|
|
@ -38,7 +38,17 @@ import gettext
|
|||
import locale
|
||||
import pkg_resources
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.ui.client as client
|
||||
from mainwindow import MainWindow
|
||||
from menubar import MenuBar
|
||||
from toolbar import ToolBar
|
||||
from torrentview import TorrentView
|
||||
from torrentdetails import TorrentDetails
|
||||
from preferences import Preferences
|
||||
from systemtray import SystemTray
|
||||
from statusbar import StatusBar
|
||||
from connectionmanager import ConnectionManager
|
||||
from signals import Signals
|
||||
from pluginmanager import PluginManager
|
||||
from deluge.configmanager import ConfigManager
|
||||
|
@ -67,7 +77,7 @@ DEFAULT_PREFS = {
|
|||
"window_pane_position": -1,
|
||||
"tray_download_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
|
||||
"tray_upload_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
|
||||
"enabled_plugins": ["Queue"]
|
||||
"enabled_plugins": []
|
||||
}
|
||||
|
||||
class GtkUI:
|
||||
|
@ -89,8 +99,20 @@ class GtkUI:
|
|||
# Make sure gtkui.conf has at least the defaults set
|
||||
config = ConfigManager("gtkui.conf", DEFAULT_PREFS)
|
||||
|
||||
# Initialize the main window
|
||||
# We make sure that the UI components start once we get a core URI
|
||||
client.connect_on_new_core(component.start)
|
||||
client.connect_on_no_core(component.stop)
|
||||
|
||||
# Initialize various components of the gtkui
|
||||
self.mainwindow = MainWindow()
|
||||
self.menubar = MenuBar()
|
||||
self.toolbar = ToolBar()
|
||||
self.torrentview = TorrentView()
|
||||
self.torrentdetails = TorrentDetails()
|
||||
self.preferences = Preferences()
|
||||
self.systemtray = SystemTray()
|
||||
self.statusbar = StatusBar()
|
||||
self.connectionmanager = ConnectionManager()
|
||||
|
||||
# Start the signal receiver
|
||||
#self.signal_receiver = Signals(self)
|
||||
|
@ -98,8 +120,8 @@ class GtkUI:
|
|||
# Initalize the plugins
|
||||
self.plugins = PluginManager(self)
|
||||
|
||||
# Start the mainwindow and show it
|
||||
#self.mainwindow.start()
|
||||
# Show the connection manager
|
||||
self.connectionmanager.show()
|
||||
|
||||
# Start the gtk main loop
|
||||
gtk.gdk.threads_init()
|
||||
|
@ -113,6 +135,12 @@ class GtkUI:
|
|||
|
||||
# Clean-up
|
||||
del self.mainwindow
|
||||
del self.systemtray
|
||||
del self.menubar
|
||||
del self.toolbar
|
||||
del self.torrentview
|
||||
del self.torrentdetails
|
||||
del self.preferences
|
||||
# del self.signal_receiver
|
||||
del self.plugins
|
||||
del deluge.configmanager
|
||||
|
|
|
@ -38,21 +38,16 @@ import gobject
|
|||
import pkg_resources
|
||||
|
||||
import deluge.ui.client as client
|
||||
import deluge.ui.component as component
|
||||
from deluge.configmanager import ConfigManager
|
||||
from menubar import MenuBar
|
||||
from toolbar import ToolBar
|
||||
from torrentview import TorrentView
|
||||
from torrentdetails import TorrentDetails
|
||||
from preferences import Preferences
|
||||
from systemtray import SystemTray
|
||||
from statusbar import StatusBar
|
||||
from connectionmanager import ConnectionManager
|
||||
|
||||
import deluge.common
|
||||
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class MainWindow:
|
||||
class MainWindow(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "MainWindow")
|
||||
self.config = ConfigManager("gtkui.conf")
|
||||
# Get the glade file for the main window
|
||||
self.main_glade = gtk.glade.XML(
|
||||
|
@ -75,36 +70,11 @@ class MainWindow:
|
|||
self.window.connect("delete-event", self.on_window_delete_event)
|
||||
self.vpaned.connect("notify::position", self.on_vpaned_position_event)
|
||||
|
||||
# Initialize various components of the gtkui
|
||||
self.menubar = MenuBar(self)
|
||||
self.toolbar = ToolBar(self)
|
||||
self.torrentview = TorrentView(self)
|
||||
self.torrentdetails = TorrentDetails(self)
|
||||
self.preferences = Preferences(self)
|
||||
self.systemtray = SystemTray(self)
|
||||
self.statusbar = StatusBar(self)
|
||||
self.connectionmanager = ConnectionManager(self)
|
||||
client.connect_on_new_core(self.start)
|
||||
if not(self.config["start_in_tray"] and \
|
||||
self.config["enable_system_tray"]) and not \
|
||||
self.window.get_property("visible"):
|
||||
log.debug("Showing window")
|
||||
self.show()
|
||||
self.connectionmanager.show()
|
||||
|
||||
def start(self):
|
||||
"""Start the update thread and show the window"""
|
||||
self.torrentview.start()
|
||||
self.update_timer = gobject.timeout_add(1000, self.update)
|
||||
|
||||
def update(self):
|
||||
# Don't update the UI if the the window is minimized.
|
||||
if self.is_minimized == True:
|
||||
return True
|
||||
self.torrentview.update()
|
||||
self.torrentdetails.update()
|
||||
self.statusbar.update()
|
||||
return True
|
||||
|
||||
def show(self):
|
||||
# Load the state prior to showing
|
||||
|
@ -126,17 +96,6 @@ class MainWindow:
|
|||
return self.window.get_property("visible")
|
||||
|
||||
def quit(self):
|
||||
# Stop the update timer from running
|
||||
try:
|
||||
gobject.source_remove(self.update_timer)
|
||||
except:
|
||||
pass
|
||||
del self.systemtray
|
||||
del self.menubar
|
||||
del self.toolbar
|
||||
del self.torrentview
|
||||
del self.torrentdetails
|
||||
del self.preferences
|
||||
del self.config
|
||||
self.hide()
|
||||
gtk.main_quit()
|
||||
|
|
|
@ -36,14 +36,16 @@ pygtk.require('2.0')
|
|||
import gtk, gtk.glade
|
||||
import pkg_resources
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.ui.client as client
|
||||
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class MenuBar:
|
||||
def __init__(self, window):
|
||||
class MenuBar(component.Component):
|
||||
def __init__(self):
|
||||
log.debug("MenuBar init..")
|
||||
self.window = window
|
||||
component.Component.__init__(self, "MenuBar")
|
||||
self.window = component.get("MainWindow")
|
||||
# Get the torrent menu from the glade file
|
||||
torrentmenu_glade = gtk.glade.XML(
|
||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||
|
@ -124,27 +126,27 @@ class MenuBar:
|
|||
## Edit Menu ##
|
||||
def on_menuitem_preferences_activate(self, data=None):
|
||||
log.debug("on_menuitem_preferences_activate")
|
||||
self.window.preferences.show()
|
||||
component.get("Preferences").show()
|
||||
|
||||
def on_menuitem_connectionmanager_activate(self, data=None):
|
||||
log.debug("on_menuitem_connectionmanager_activate")
|
||||
self.window.connectionmanager.show()
|
||||
component.get("ConnectionManager").show()
|
||||
|
||||
## Torrent Menu ##
|
||||
def on_menuitem_pause_activate(self, data=None):
|
||||
log.debug("on_menuitem_pause_activate")
|
||||
client.pause_torrent(
|
||||
self.window.torrentview.get_selected_torrents())
|
||||
component.get("TorrentView").get_selected_torrents())
|
||||
|
||||
def on_menuitem_resume_activate(self, data=None):
|
||||
log.debug("on_menuitem_resume_activate")
|
||||
client.resume_torrent(
|
||||
self.window.torrentview.get_selected_torrents())
|
||||
component.get("TorrentView").get_selected_torrents())
|
||||
|
||||
def on_menuitem_updatetracker_activate(self, data=None):
|
||||
log.debug("on_menuitem_updatetracker_activate")
|
||||
client.force_reannounce(
|
||||
self.window.torrentview.get_selected_torrents())
|
||||
component.get("TorrentView").get_selected_torrents())
|
||||
|
||||
def on_menuitem_edittrackers_activate(self, data=None):
|
||||
log.debug("on_menuitem_edittrackers_activate")
|
||||
|
@ -152,7 +154,7 @@ class MenuBar:
|
|||
def on_menuitem_remove_activate(self, data=None):
|
||||
log.debug("on_menuitem_remove_activate")
|
||||
client.remove_torrent(
|
||||
self.window.torrentview.get_selected_torrents())
|
||||
component.get("TorrentView").get_selected_torrents())
|
||||
|
||||
## View Menu ##
|
||||
def on_menuitem_toolbar_toggled(self, data=None):
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
# this exception statement from your version. If you delete this exception
|
||||
# statement from all source files in the program, then also delete it here.
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.pluginmanagerbase
|
||||
import deluge.ui.client as client
|
||||
from deluge.configmanager import ConfigManager
|
||||
|
@ -58,20 +59,25 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
|
|||
|
||||
def get_torrentview(self):
|
||||
"""Returns a reference to the torrentview component"""
|
||||
return self._gtkui.mainwindow.torrentview
|
||||
#return self._gtkui.mainwindow.torrentview
|
||||
return component.get("TorrentView")
|
||||
|
||||
def get_toolbar(self):
|
||||
"""Returns a reference to the toolbar component"""
|
||||
return self._gtkui.mainwindow.toolbar
|
||||
# return self._gtkui.mainwindow.toolbar
|
||||
return component.get("ToolBar")
|
||||
|
||||
def get_menubar(self):
|
||||
"""Returns a reference to the menubar component"""
|
||||
return self._gtkui.mainwindow.menubar
|
||||
# return self._gtkui.mainwindow.menubar
|
||||
return component.get("MenuBar")
|
||||
|
||||
def get_torrentmenu(self):
|
||||
"""Returns a reference to the torrentmenu component"""
|
||||
return self._gtkui.mainwindow.menubar.torrentmenu
|
||||
# return self._gtkui.mainwindow.menubar.torrentmenu
|
||||
return component.get("MenuBar").torrentmenu
|
||||
|
||||
def get_selected_torrents(self):
|
||||
"""Returns a list of the selected torrent_ids"""
|
||||
return self._gtkui.mainwindow.torrentview.get_selected_torrents()
|
||||
# return self._gtkui.mainwindow.torrentview.get_selected_torrents()
|
||||
return component.get("TorrentView").get_selected_torrents()
|
||||
|
|
|
@ -36,14 +36,16 @@ pygtk.require('2.0')
|
|||
import gtk, gtk.glade
|
||||
import pkg_resources
|
||||
|
||||
import deluge.ui.component as component
|
||||
from deluge.log import LOG as log
|
||||
import deluge.ui.client as client
|
||||
import deluge.common
|
||||
from deluge.configmanager import ConfigManager
|
||||
|
||||
class Preferences:
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
class Preferences(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "Preferences")
|
||||
self.window = component.get("MainWindow")
|
||||
self.glade = gtk.glade.XML(
|
||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||
"glade/preferences_dialog.glade"))
|
||||
|
@ -395,6 +397,10 @@ class Preferences:
|
|||
name = self.plugin_liststore.get_value(row, 0)
|
||||
value = self.plugin_liststore.get_value(row, 1)
|
||||
self.plugin_liststore.set_value(row, 1, not value)
|
||||
if not value:
|
||||
functions.enable_plugin(name)
|
||||
else:
|
||||
functions.disable_plugin(name)
|
||||
|
||||
def on_plugin_selection_changed(self, treeselection):
|
||||
log.debug("on_plugin_selection_changed")
|
||||
|
|
|
@ -33,12 +33,15 @@
|
|||
|
||||
import gtk
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.common
|
||||
import deluge.ui.client as client
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class StatusBar:
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
class StatusBar(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "StatusBar")
|
||||
self.window = component.get("MainWindow")
|
||||
self.statusbar = self.window.main_glade.get_widget("statusbar")
|
||||
|
||||
# Add a HBox to the statusbar after removing the initial label widget
|
||||
|
@ -47,8 +50,13 @@ class StatusBar:
|
|||
frame = self.statusbar.get_children()[0]
|
||||
frame.remove(frame.get_children()[0])
|
||||
frame.add(self.hbox)
|
||||
# Show the not connected status bar
|
||||
self.show_not_connected()
|
||||
|
||||
def start(self):
|
||||
log.debug("StatusBar start..")
|
||||
# Add in images and labels
|
||||
self.clear_statusbar()
|
||||
image = gtk.Image()
|
||||
image.set_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU)
|
||||
self.hbox.pack_start(image, expand=False, fill=False)
|
||||
|
@ -67,10 +75,26 @@ class StatusBar:
|
|||
self.hbox.pack_start(self.label_upload_speed,
|
||||
expand=False, fill=False)
|
||||
|
||||
# Update once before showing
|
||||
# self.update()
|
||||
self.statusbar.show_all()
|
||||
|
||||
def stop(self):
|
||||
# When stopped, we just show the not connected thingy
|
||||
self.show_not_connected()
|
||||
|
||||
def show_not_connected(self):
|
||||
self.clear_statusbar()
|
||||
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..")
|
||||
self.hbox.pack_start(label, expand=False, fill=False)
|
||||
self.statusbar.show_all()
|
||||
|
||||
def clear_statusbar(self):
|
||||
def remove(child):
|
||||
self.hbox.remove(child)
|
||||
self.hbox.foreach(remove)
|
||||
|
||||
def update(self):
|
||||
# Set the max connections label
|
||||
max_connections = client.get_config_value("max_connections_global")
|
||||
|
@ -101,3 +125,4 @@ class StatusBar:
|
|||
self.label_upload_speed.set_text("%s/s (%s)" % (
|
||||
deluge.common.fsize(client.get_upload_rate()),
|
||||
max_upload_speed))
|
||||
|
||||
|
|
|
@ -34,14 +34,16 @@
|
|||
import gtk
|
||||
import pkg_resources
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.ui.client as client
|
||||
import deluge.common
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class SystemTray:
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
class SystemTray(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "SystemTray")
|
||||
self.window = component.get("MainWindow")
|
||||
self.config = ConfigManager("gtkui.conf")
|
||||
self.config.register_set_function("enable_system_tray",
|
||||
self.on_enable_system_tray_set)
|
||||
|
@ -79,6 +81,7 @@ class SystemTray:
|
|||
deluge.common.get_pixmap("seeding16.png"))
|
||||
|
||||
def start(self):
|
||||
log.debug("SystemTray start..")
|
||||
# Build the bandwidth speed limit menus
|
||||
self.build_tray_bwsetsubmenu()
|
||||
|
||||
|
|
|
@ -35,12 +35,14 @@ import pygtk
|
|||
pygtk.require('2.0')
|
||||
import gtk, gtk.glade
|
||||
|
||||
import deluge.ui.component as component
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class ToolBar:
|
||||
def __init__(self, window):
|
||||
class ToolBar(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "ToolBar")
|
||||
log.debug("ToolBar Init..")
|
||||
self.window = window
|
||||
self.window = component.get("MainWindow")
|
||||
self.toolbar = self.window.main_glade.get_widget("toolbar")
|
||||
### Connect Signals ###
|
||||
self.window.main_glade.signal_autoconnect({
|
||||
|
@ -94,34 +96,34 @@ class ToolBar:
|
|||
def on_toolbutton_add_clicked(self, data):
|
||||
log.debug("on_toolbutton_add_clicked")
|
||||
# Use the menubar's callback
|
||||
self.window.menubar.on_menuitem_addtorrent_activate(data)
|
||||
component.get("MenuBar").on_menuitem_addtorrent_activate(data)
|
||||
|
||||
def on_toolbutton_remove_clicked(self, data):
|
||||
log.debug("on_toolbutton_remove_clicked")
|
||||
# Use the menubar's callbacks
|
||||
self.window.menubar.on_menuitem_remove_activate(data)
|
||||
component.get("MenuBar").on_menuitem_remove_activate(data)
|
||||
|
||||
def on_toolbutton_clear_clicked(self, data):
|
||||
log.debug("on_toolbutton_clear_clicked")
|
||||
# Use the menubar's callbacks
|
||||
self.window.menubar.on_menuitem_clear_activate(data)
|
||||
component.get("MenuBar").on_menuitem_clear_activate(data)
|
||||
|
||||
def on_toolbutton_pause_clicked(self, data):
|
||||
log.debug("on_toolbutton_pause_clicked")
|
||||
# Use the menubar's callbacks
|
||||
self.window.menubar.on_menuitem_pause_activate(data)
|
||||
component.get("MenuBar").on_menuitem_pause_activate(data)
|
||||
|
||||
def on_toolbutton_resume_clicked(self, data):
|
||||
log.debug("on_toolbutton_resume_clicked")
|
||||
# Use the menubar's calbacks
|
||||
self.window.menubar.on_menuitem_resume_activate(data)
|
||||
component.get("MenuBar").on_menuitem_resume_activate(data)
|
||||
|
||||
def on_toolbutton_preferences_clicked(self, data):
|
||||
log.debug("on_toolbutton_preferences_clicked")
|
||||
# Use the menubar's callbacks
|
||||
self.window.menubar.on_menuitem_preferences_activate(data)
|
||||
component.get("MenuBar").on_menuitem_preferences_activate(data)
|
||||
|
||||
def on_toolbutton_plugins_clicked(self, data):
|
||||
log.debug("on_toolbutton_plugins_clicked")
|
||||
# Use the menubar's callbacks
|
||||
self.window.menubar.on_menuitem_preferences_activate(data)
|
||||
component.get("MenuBar").on_menuitem_preferences_activate(data)
|
||||
|
|
|
@ -38,13 +38,15 @@ pygtk.require('2.0')
|
|||
import gtk, gtk.glade
|
||||
import gettext
|
||||
|
||||
import deluge.ui.component as component
|
||||
import deluge.ui.client as client
|
||||
import deluge.common
|
||||
from deluge.log import LOG as log
|
||||
|
||||
class TorrentDetails:
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
class TorrentDetails(component.Component):
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "TorrentDetails")
|
||||
self.window = component.get("MainWindow")
|
||||
glade = self.window.main_glade
|
||||
|
||||
self.notebook = glade.get_widget("torrent_info")
|
||||
|
@ -71,12 +73,16 @@ class TorrentDetails:
|
|||
self.eta = glade.get_widget("summary_eta")
|
||||
self.torrent_path = glade.get_widget("summary_torrent_path")
|
||||
|
||||
def stop(self):
|
||||
self.clear()
|
||||
|
||||
def update(self):
|
||||
# Only update if this page is showing
|
||||
if self.notebook.page_num(self.details_tab) is \
|
||||
self.notebook.get_current_page():
|
||||
# Get the first selected torrent
|
||||
selected = self.window.torrentview.get_selected_torrents()
|
||||
#selected = self.window.torrentview.get_selected_torrents()
|
||||
selected = component.get("TorrentView").get_selected_torrents()
|
||||
|
||||
# Only use the first torrent in the list or return if None selected
|
||||
if selected is not None:
|
||||
|
@ -154,3 +160,4 @@ class TorrentDetails:
|
|||
self.tracker_status.set_text("")
|
||||
self.next_announce.set_text("")
|
||||
self.eta.set_text("")
|
||||
self.torrent_path.set_text("")
|
||||
|
|
|
@ -40,6 +40,7 @@ import gettext
|
|||
import gobject
|
||||
|
||||
import deluge.common
|
||||
import deluge.ui.component as component
|
||||
import deluge.ui.client as client
|
||||
from deluge.log import LOG as log
|
||||
import deluge.ui.gtkui.listview as listview
|
||||
|
@ -96,10 +97,11 @@ def cell_data_progress(column, cell, model, row, data):
|
|||
textstr = textstr + " %.2f%%" % value
|
||||
cell.set_property("text", textstr)
|
||||
|
||||
class TorrentView(listview.ListView):
|
||||
class TorrentView(listview.ListView, component.Component):
|
||||
"""TorrentView handles the listing of torrents."""
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
def __init__(self):
|
||||
component.Component.__init__(self, "TorrentView")
|
||||
self.window = component.get("MainWindow")
|
||||
# Call the ListView constructor
|
||||
listview.ListView.__init__(self,
|
||||
self.window.main_glade.get_widget("torrent_view"))
|
||||
|
@ -171,6 +173,11 @@ class TorrentView(listview.ListView):
|
|||
for torrent_id in session_state:
|
||||
self.add_row(torrent_id)
|
||||
|
||||
def stop(self):
|
||||
"""Stops the torrentview"""
|
||||
# We need to clear the liststore
|
||||
self.liststore.clear()
|
||||
|
||||
def update(self, columns=None):
|
||||
"""Update the view. If columns is not None, it will attempt to only
|
||||
update those columns selected.
|
||||
|
@ -294,12 +301,12 @@ class TorrentView(listview.ListView):
|
|||
# We only care about right-clicks
|
||||
if event.button == 3:
|
||||
# Show the Torrent menu from the MenuBar
|
||||
torrentmenu = self.window.menubar.torrentmenu
|
||||
torrentmenu = component.get("MenuBar").torrentmenu
|
||||
torrentmenu.popup(None, None, None, event.button, event.time)
|
||||
|
||||
def on_selection_changed(self, treeselection):
|
||||
"""This callback is know when the selection has changed."""
|
||||
log.debug("on_selection_changed")
|
||||
self.window.torrentdetails.update()
|
||||
component.get("TorrentDetails").update()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue