mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-25 09:35:16 +00:00
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_upload_slots_global": -1,
|
||||||
"max_connections_per_torrent": -1,
|
"max_connections_per_torrent": -1,
|
||||||
"max_upload_slots_per_torrent": -1,
|
"max_upload_slots_per_torrent": -1,
|
||||||
"enabled_plugins": ["Queue"]
|
"enabled_plugins": []
|
||||||
}
|
}
|
||||||
|
|
||||||
class Core(
|
class Core(
|
||||||
|
@ -65,7 +65,7 @@ class PluginManagerBase:
|
|||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
log.debug("PluginManager shutting down..")
|
log.debug("PluginManager shutting down..")
|
||||||
for plugin in self.plugins.values():
|
for plugin in self.plugins.values():
|
||||||
plugin.core.shutdown()
|
plugin.disable()
|
||||||
del self.plugins
|
del self.plugins
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
@ -113,9 +113,11 @@ class PluginManagerBase:
|
|||||||
|
|
||||||
def disable_plugin(self, name):
|
def disable_plugin(self, name):
|
||||||
"""Disables a plugin"""
|
"""Disables a plugin"""
|
||||||
try:
|
|
||||||
|
self.plugins[name].disable()
|
||||||
|
|
||||||
del self.plugins[name]
|
del self.plugins[name]
|
||||||
except:
|
# except:
|
||||||
log.warning("Unable to disable non-existant plugin %s", name)
|
# log.warning("Unable to disable non-existant plugin %s", name)
|
||||||
|
|
||||||
log.info("Plugin %s disabled..", name)
|
log.info("Plugin %s disabled..", name)
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import pickle
|
import pickle
|
||||||
|
import socket
|
||||||
|
|
||||||
import deluge.xmlrpclib as xmlrpclib
|
import deluge.xmlrpclib as xmlrpclib
|
||||||
|
|
||||||
@ -48,17 +49,32 @@ class CoreProxy:
|
|||||||
self._uri = None
|
self._uri = None
|
||||||
self._core = None
|
self._core = None
|
||||||
self._on_new_core_callbacks = []
|
self._on_new_core_callbacks = []
|
||||||
|
self._on_no_core_callbacks = []
|
||||||
|
|
||||||
def connect_on_new_core(self, callback):
|
def connect_on_new_core(self, callback):
|
||||||
"""Connect a callback to be called when a new core is connected to."""
|
"""Connect a callback to be called when a new core is connected to."""
|
||||||
self._on_new_core_callbacks.append(callback)
|
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):
|
def set_core_uri(self, uri):
|
||||||
log.info("Setting core uri as %s", uri)
|
log.info("Setting core uri as %s", uri)
|
||||||
self._uri = 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
|
# Get a new core
|
||||||
self.get_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):
|
def get_core(self):
|
||||||
if self._core is None and self._uri is not None:
|
if self._core is None and self._uri is not None:
|
||||||
log.debug("Creating ServerProxy..")
|
log.debug("Creating ServerProxy..")
|
||||||
@ -88,13 +104,24 @@ def connect_on_new_core(callback):
|
|||||||
"""Connect a callback whenever a new core is connected to."""
|
"""Connect a callback whenever a new core is connected to."""
|
||||||
return _core.connect_on_new_core(callback)
|
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):
|
def set_core_uri(uri):
|
||||||
"""Sets the core uri"""
|
"""Sets the core uri"""
|
||||||
return _core.set_core_uri(uri)
|
return _core.set_core_uri(uri)
|
||||||
|
|
||||||
|
def get_core_uri():
|
||||||
|
"""Get the core URI"""
|
||||||
|
return _core.get_core_uri()
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
"""Shutdown the core daemon"""
|
"""Shutdown the core daemon"""
|
||||||
|
try:
|
||||||
get_core().shutdown()
|
get_core().shutdown()
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def add_torrent_file(torrent_files):
|
def add_torrent_file(torrent_files):
|
||||||
"""Adds torrent files to the core
|
"""Adds torrent files to the core
|
||||||
@ -112,7 +139,11 @@ def add_torrent_file(torrent_files):
|
|||||||
(path, filename) = os.path.split(torrent_file)
|
(path, filename) = os.path.split(torrent_file)
|
||||||
fdump = xmlrpclib.Binary(f.read())
|
fdump = xmlrpclib.Binary(f.read())
|
||||||
f.close()
|
f.close()
|
||||||
|
try:
|
||||||
result = get_core().add_torrent_file(filename, str(), fdump)
|
result = get_core().add_torrent_file(filename, str(), fdump)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
result = False
|
||||||
|
|
||||||
if result is False:
|
if result is False:
|
||||||
# The torrent was not added successfully.
|
# The torrent was not added successfully.
|
||||||
@ -122,7 +153,12 @@ def add_torrent_url(torrent_url):
|
|||||||
"""Adds torrents to the core via url"""
|
"""Adds torrents to the core via url"""
|
||||||
from deluge.common import is_url
|
from deluge.common import is_url
|
||||||
if is_url(torrent_url):
|
if is_url(torrent_url):
|
||||||
|
try:
|
||||||
result = get_core().add_torrent_url(torrent_url, str())
|
result = get_core().add_torrent_url(torrent_url, str())
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
result = False
|
||||||
|
|
||||||
if result is False:
|
if result is False:
|
||||||
# The torrent url was not added successfully.
|
# The torrent url was not added successfully.
|
||||||
log.warning("Torrent %s was not added successfully.", torrent_url)
|
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):
|
def remove_torrent(torrent_ids):
|
||||||
"""Removes torrent_ids from the core.. Expects a list of torrent_ids"""
|
"""Removes torrent_ids from the core.. Expects a list of torrent_ids"""
|
||||||
log.debug("Attempting to removing torrents: %s", torrent_ids)
|
log.debug("Attempting to removing torrents: %s", torrent_ids)
|
||||||
|
try:
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
get_core().remove_torrent(torrent_id)
|
get_core().remove_torrent(torrent_id)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def pause_torrent(torrent_ids):
|
def pause_torrent(torrent_ids):
|
||||||
"""Pauses torrent_ids"""
|
"""Pauses torrent_ids"""
|
||||||
|
try:
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
get_core().pause_torrent(torrent_id)
|
get_core().pause_torrent(torrent_id)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def resume_torrent(torrent_ids):
|
def resume_torrent(torrent_ids):
|
||||||
"""Resume torrent_ids"""
|
"""Resume torrent_ids"""
|
||||||
|
try:
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
get_core().resume_torrent(torrent_id)
|
get_core().resume_torrent(torrent_id)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def force_reannounce(torrent_ids):
|
def force_reannounce(torrent_ids):
|
||||||
"""Reannounce to trackers"""
|
"""Reannounce to trackers"""
|
||||||
|
try:
|
||||||
for torrent_id in torrent_ids:
|
for torrent_id in torrent_ids:
|
||||||
get_core().force_reannounce(torrent_id)
|
get_core().force_reannounce(torrent_id)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def get_torrent_status(torrent_id, keys):
|
def get_torrent_status(torrent_id, keys):
|
||||||
"""Builds the status dictionary and returns it"""
|
"""Builds the status dictionary and returns it"""
|
||||||
|
try:
|
||||||
status = get_core().get_torrent_status(torrent_id, keys)
|
status = get_core().get_torrent_status(torrent_id, keys)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
return {}
|
||||||
return pickle.loads(status.data)
|
return pickle.loads(status.data)
|
||||||
|
|
||||||
def get_session_state():
|
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():
|
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):
|
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):
|
def set_config(config):
|
||||||
if config == {}:
|
if config == {}:
|
||||||
return
|
return
|
||||||
|
try:
|
||||||
get_core().set_config(config)
|
get_core().set_config(config)
|
||||||
|
except (AttributeError, socket.error):
|
||||||
|
set_core_uri(None)
|
||||||
|
|
||||||
def get_listen_port():
|
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():
|
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():
|
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():
|
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():
|
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():
|
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):
|
def open_url_in_browser(url):
|
||||||
"""Opens link in the desktop's default browser"""
|
"""Opens link in the desktop's default browser"""
|
||||||
|
131
deluge/ui/component.py
Normal file
131
deluge/ui/component.py
Normal file
@ -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 gobject
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.xmlrpclib as xmlrpclib
|
import deluge.xmlrpclib as xmlrpclib
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
@ -46,14 +47,24 @@ DEFAULT_CONFIG = {
|
|||||||
"hosts": ["localhost:58846"]
|
"hosts": ["localhost:58846"]
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConnectionManager:
|
HOSTLIST_COL_PIXBUF = 0
|
||||||
def __init__(self, window):
|
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
|
# Get the glade file for the connection manager
|
||||||
self.glade = gtk.glade.XML(
|
self.glade = gtk.glade.XML(
|
||||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||||
"glade/connection_manager.glade"))
|
"glade/connection_manager.glade"))
|
||||||
|
|
||||||
self.window = window
|
self.window = component.get("MainWindow")
|
||||||
self.config = ConfigManager("hostlist.conf", DEFAULT_CONFIG)
|
self.config = ConfigManager("hostlist.conf", DEFAULT_CONFIG)
|
||||||
self.connection_manager = self.glade.get_widget("connection_manager")
|
self.connection_manager = self.glade.get_widget("connection_manager")
|
||||||
self.hostlist = self.glade.get_widget("hostlist")
|
self.hostlist = self.glade.get_widget("hostlist")
|
||||||
@ -62,20 +73,21 @@ class ConnectionManager:
|
|||||||
self.glade.get_widget("image1").set_from_pixbuf(
|
self.glade.get_widget("image1").set_from_pixbuf(
|
||||||
deluge.common.get_logo(32))
|
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
|
# Fill in hosts from config file
|
||||||
for host in self.config["hosts"]:
|
for host in self.config["hosts"]:
|
||||||
row = self.liststore.append()
|
row = self.liststore.append()
|
||||||
self.liststore.set_value(row, 1, host)
|
self.liststore.set_value(row, HOSTLIST_COL_URI, host)
|
||||||
|
|
||||||
# Setup host list treeview
|
# Setup host list treeview
|
||||||
self.hostlist.set_model(self.liststore)
|
self.hostlist.set_model(self.liststore)
|
||||||
render = gtk.CellRendererPixbuf()
|
render = gtk.CellRendererPixbuf()
|
||||||
column = gtk.TreeViewColumn("Status", render, pixbuf=0)
|
column = gtk.TreeViewColumn(
|
||||||
|
"Status", render, pixbuf=HOSTLIST_COL_PIXBUF)
|
||||||
self.hostlist.append_column(column)
|
self.hostlist.append_column(column)
|
||||||
render = gtk.CellRendererText()
|
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.hostlist.append_column(column)
|
||||||
|
|
||||||
self.glade.signal_autoconnect({
|
self.glade.signal_autoconnect({
|
||||||
@ -83,60 +95,126 @@ class ConnectionManager:
|
|||||||
"on_button_removehost_clicked": self.on_button_removehost_clicked,
|
"on_button_removehost_clicked": self.on_button_removehost_clicked,
|
||||||
"on_button_startdaemon_clicked": \
|
"on_button_startdaemon_clicked": \
|
||||||
self.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,
|
"on_button_connect_clicked": self.on_button_connect_clicked,
|
||||||
})
|
})
|
||||||
|
|
||||||
self.connection_manager.connect("delete-event", self.on_delete_event)
|
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):
|
def show(self):
|
||||||
self.update_timer = gobject.timeout_add(5000, self.update)
|
self._update_timer = gobject.timeout_add(5000, self._update)
|
||||||
self.update()
|
self._update()
|
||||||
self.connection_manager.show_all()
|
self.connection_manager.show_all()
|
||||||
|
|
||||||
def hide(self):
|
def hide(self):
|
||||||
self.connection_manager.hide()
|
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"""
|
"""Updates the host status"""
|
||||||
def update_row(model=None, path=None, row=None, columns=None):
|
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
|
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
|
online = True
|
||||||
host = None
|
host = None
|
||||||
try:
|
try:
|
||||||
host = xmlrpclib.ServerProxy(uri)
|
host = xmlrpclib.ServerProxy(uri)
|
||||||
host.ping()
|
host.ping()
|
||||||
except socket.error:
|
except socket.error:
|
||||||
print "socket.error!"
|
|
||||||
online = False
|
online = False
|
||||||
|
|
||||||
print "online: ", online
|
|
||||||
del host
|
del host
|
||||||
|
|
||||||
if online:
|
return 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()
|
|
||||||
|
|
||||||
## Callbacks
|
## Callbacks
|
||||||
def on_delete_event(self, widget, event):
|
def on_delete_event(self, widget, event):
|
||||||
@ -165,9 +243,11 @@ class ConnectionManager:
|
|||||||
port = port_spinbutton.get_value_as_int()
|
port = port_spinbutton.get_value_as_int()
|
||||||
hostname = hostname + ":" + str(port)
|
hostname = hostname + ":" + str(port)
|
||||||
row = self.liststore.append()
|
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
|
# Save the host list to file
|
||||||
self.save()
|
self.save()
|
||||||
|
# Update the status of the hosts
|
||||||
|
self._update()
|
||||||
|
|
||||||
dialog.hide()
|
dialog.hide()
|
||||||
|
|
||||||
@ -184,16 +264,36 @@ class ConnectionManager:
|
|||||||
def on_button_startdaemon_clicked(self, widget):
|
def on_button_startdaemon_clicked(self, widget):
|
||||||
log.debug("on_button_startdaemon_clicked")
|
log.debug("on_button_startdaemon_clicked")
|
||||||
|
|
||||||
def on_button_cancel_clicked(self, widget):
|
def on_button_close_clicked(self, widget):
|
||||||
log.debug("on_button_cancel_clicked")
|
log.debug("on_button_close_clicked")
|
||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
def on_button_connect_clicked(self, widget):
|
def on_button_connect_clicked(self, widget):
|
||||||
log.debug("on_button_connect_clicked")
|
log.debug("on_button_connect_clicked")
|
||||||
paths = self.hostlist.get_selection().get_selected_rows()[1]
|
paths = self.hostlist.get_selection().get_selected_rows()[1]
|
||||||
row = self.liststore.get_iter(paths[0])
|
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
|
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)
|
client.set_core_uri(uri)
|
||||||
self.window.start()
|
self.window.start()
|
||||||
self.hide()
|
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"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
<!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>
|
<glade-interface>
|
||||||
<widget class="GtkDialog" id="connection_manager">
|
<widget class="GtkDialog" id="connection_manager">
|
||||||
<property name="has_focus">True</property>
|
<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="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="label" translatable="yes">gtk-add</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
|
||||||
<signal name="clicked" handler="on_button_addhost_clicked"/>
|
<signal name="clicked" handler="on_button_addhost_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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="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="label" translatable="yes">gtk-remove</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
|
||||||
<signal name="clicked" handler="on_button_removehost_clicked"/>
|
<signal name="clicked" handler="on_button_removehost_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
@ -130,7 +128,6 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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"/>
|
<signal name="clicked" handler="on_button_startdaemon_clicked"/>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkHBox" id="hbox4">
|
<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="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
<property name="spacing">2</property>
|
<property name="spacing">2</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImage" id="image2">
|
<widget class="GtkImage" id="image_startdaemon">
|
||||||
<property name="visible">True</property>
|
<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="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>
|
<property name="stock">gtk-execute</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label5">
|
<widget class="GtkLabel" id="label_startdaemon">
|
||||||
<property name="visible">True</property>
|
<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="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>
|
<property name="label" translatable="yes">_Start local daemon</property>
|
||||||
@ -193,7 +190,6 @@
|
|||||||
<property name="can_focus">True</property>
|
<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="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="label" translatable="yes">checkbutton</property>
|
||||||
<property name="response_id">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</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="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>
|
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkButton" id="button_cancel">
|
<widget class="GtkButton" id="button_close">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">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="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="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
<signal name="clicked" handler="on_button_close_clicked"/>
|
||||||
<signal name="clicked" handler="on_button_cancel_clicked"/>
|
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<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="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="label" translatable="yes">gtk-connect</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
|
||||||
<signal name="clicked" handler="on_button_connect_clicked"/>
|
<signal name="clicked" handler="on_button_connect_clicked"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<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="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-cancel</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="response_id">0</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -38,7 +38,17 @@ import gettext
|
|||||||
import locale
|
import locale
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
|
import deluge.ui.client as client
|
||||||
from mainwindow import MainWindow
|
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 signals import Signals
|
||||||
from pluginmanager import PluginManager
|
from pluginmanager import PluginManager
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
@ -67,7 +77,7 @@ DEFAULT_PREFS = {
|
|||||||
"window_pane_position": -1,
|
"window_pane_position": -1,
|
||||||
"tray_download_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
|
"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],
|
"tray_upload_speed_list" : [5.0, 10.0, 30.0, 80.0, 300.0],
|
||||||
"enabled_plugins": ["Queue"]
|
"enabled_plugins": []
|
||||||
}
|
}
|
||||||
|
|
||||||
class GtkUI:
|
class GtkUI:
|
||||||
@ -89,8 +99,20 @@ class GtkUI:
|
|||||||
# Make sure gtkui.conf has at least the defaults set
|
# Make sure gtkui.conf has at least the defaults set
|
||||||
config = ConfigManager("gtkui.conf", DEFAULT_PREFS)
|
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.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
|
# Start the signal receiver
|
||||||
#self.signal_receiver = Signals(self)
|
#self.signal_receiver = Signals(self)
|
||||||
@ -98,8 +120,8 @@ class GtkUI:
|
|||||||
# Initalize the plugins
|
# Initalize the plugins
|
||||||
self.plugins = PluginManager(self)
|
self.plugins = PluginManager(self)
|
||||||
|
|
||||||
# Start the mainwindow and show it
|
# Show the connection manager
|
||||||
#self.mainwindow.start()
|
self.connectionmanager.show()
|
||||||
|
|
||||||
# Start the gtk main loop
|
# Start the gtk main loop
|
||||||
gtk.gdk.threads_init()
|
gtk.gdk.threads_init()
|
||||||
@ -113,6 +135,12 @@ class GtkUI:
|
|||||||
|
|
||||||
# Clean-up
|
# Clean-up
|
||||||
del self.mainwindow
|
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.signal_receiver
|
||||||
del self.plugins
|
del self.plugins
|
||||||
del deluge.configmanager
|
del deluge.configmanager
|
||||||
|
@ -38,21 +38,16 @@ import gobject
|
|||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
|
import deluge.ui.component as component
|
||||||
from deluge.configmanager import ConfigManager
|
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
|
import deluge.common
|
||||||
|
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class MainWindow:
|
class MainWindow(component.Component):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
component.Component.__init__(self, "MainWindow")
|
||||||
self.config = ConfigManager("gtkui.conf")
|
self.config = ConfigManager("gtkui.conf")
|
||||||
# Get the glade file for the main window
|
# Get the glade file for the main window
|
||||||
self.main_glade = gtk.glade.XML(
|
self.main_glade = gtk.glade.XML(
|
||||||
@ -75,36 +70,11 @@ class MainWindow:
|
|||||||
self.window.connect("delete-event", self.on_window_delete_event)
|
self.window.connect("delete-event", self.on_window_delete_event)
|
||||||
self.vpaned.connect("notify::position", self.on_vpaned_position_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 \
|
if not(self.config["start_in_tray"] and \
|
||||||
self.config["enable_system_tray"]) and not \
|
self.config["enable_system_tray"]) and not \
|
||||||
self.window.get_property("visible"):
|
self.window.get_property("visible"):
|
||||||
log.debug("Showing window")
|
log.debug("Showing window")
|
||||||
self.show()
|
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):
|
def show(self):
|
||||||
# Load the state prior to showing
|
# Load the state prior to showing
|
||||||
@ -126,17 +96,6 @@ class MainWindow:
|
|||||||
return self.window.get_property("visible")
|
return self.window.get_property("visible")
|
||||||
|
|
||||||
def quit(self):
|
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
|
del self.config
|
||||||
self.hide()
|
self.hide()
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
@ -36,14 +36,16 @@ pygtk.require('2.0')
|
|||||||
import gtk, gtk.glade
|
import gtk, gtk.glade
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
|
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class MenuBar:
|
class MenuBar(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
log.debug("MenuBar init..")
|
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
|
# Get the torrent menu from the glade file
|
||||||
torrentmenu_glade = gtk.glade.XML(
|
torrentmenu_glade = gtk.glade.XML(
|
||||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||||
@ -124,27 +126,27 @@ class MenuBar:
|
|||||||
## Edit Menu ##
|
## Edit Menu ##
|
||||||
def on_menuitem_preferences_activate(self, data=None):
|
def on_menuitem_preferences_activate(self, data=None):
|
||||||
log.debug("on_menuitem_preferences_activate")
|
log.debug("on_menuitem_preferences_activate")
|
||||||
self.window.preferences.show()
|
component.get("Preferences").show()
|
||||||
|
|
||||||
def on_menuitem_connectionmanager_activate(self, data=None):
|
def on_menuitem_connectionmanager_activate(self, data=None):
|
||||||
log.debug("on_menuitem_connectionmanager_activate")
|
log.debug("on_menuitem_connectionmanager_activate")
|
||||||
self.window.connectionmanager.show()
|
component.get("ConnectionManager").show()
|
||||||
|
|
||||||
## Torrent Menu ##
|
## Torrent Menu ##
|
||||||
def on_menuitem_pause_activate(self, data=None):
|
def on_menuitem_pause_activate(self, data=None):
|
||||||
log.debug("on_menuitem_pause_activate")
|
log.debug("on_menuitem_pause_activate")
|
||||||
client.pause_torrent(
|
client.pause_torrent(
|
||||||
self.window.torrentview.get_selected_torrents())
|
component.get("TorrentView").get_selected_torrents())
|
||||||
|
|
||||||
def on_menuitem_resume_activate(self, data=None):
|
def on_menuitem_resume_activate(self, data=None):
|
||||||
log.debug("on_menuitem_resume_activate")
|
log.debug("on_menuitem_resume_activate")
|
||||||
client.resume_torrent(
|
client.resume_torrent(
|
||||||
self.window.torrentview.get_selected_torrents())
|
component.get("TorrentView").get_selected_torrents())
|
||||||
|
|
||||||
def on_menuitem_updatetracker_activate(self, data=None):
|
def on_menuitem_updatetracker_activate(self, data=None):
|
||||||
log.debug("on_menuitem_updatetracker_activate")
|
log.debug("on_menuitem_updatetracker_activate")
|
||||||
client.force_reannounce(
|
client.force_reannounce(
|
||||||
self.window.torrentview.get_selected_torrents())
|
component.get("TorrentView").get_selected_torrents())
|
||||||
|
|
||||||
def on_menuitem_edittrackers_activate(self, data=None):
|
def on_menuitem_edittrackers_activate(self, data=None):
|
||||||
log.debug("on_menuitem_edittrackers_activate")
|
log.debug("on_menuitem_edittrackers_activate")
|
||||||
@ -152,7 +154,7 @@ class MenuBar:
|
|||||||
def on_menuitem_remove_activate(self, data=None):
|
def on_menuitem_remove_activate(self, data=None):
|
||||||
log.debug("on_menuitem_remove_activate")
|
log.debug("on_menuitem_remove_activate")
|
||||||
client.remove_torrent(
|
client.remove_torrent(
|
||||||
self.window.torrentview.get_selected_torrents())
|
component.get("TorrentView").get_selected_torrents())
|
||||||
|
|
||||||
## View Menu ##
|
## View Menu ##
|
||||||
def on_menuitem_toolbar_toggled(self, data=None):
|
def on_menuitem_toolbar_toggled(self, data=None):
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
# this exception statement from your version. If you delete this exception
|
# this exception statement from your version. If you delete this exception
|
||||||
# statement from all source files in the program, then also delete it here.
|
# statement from all source files in the program, then also delete it here.
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.pluginmanagerbase
|
import deluge.pluginmanagerbase
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
@ -58,20 +59,25 @@ class PluginManager(deluge.pluginmanagerbase.PluginManagerBase):
|
|||||||
|
|
||||||
def get_torrentview(self):
|
def get_torrentview(self):
|
||||||
"""Returns a reference to the torrentview component"""
|
"""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):
|
def get_toolbar(self):
|
||||||
"""Returns a reference to the toolbar component"""
|
"""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):
|
def get_menubar(self):
|
||||||
"""Returns a reference to the menubar component"""
|
"""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):
|
def get_torrentmenu(self):
|
||||||
"""Returns a reference to the torrentmenu component"""
|
"""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):
|
def get_selected_torrents(self):
|
||||||
"""Returns a list of the selected torrent_ids"""
|
"""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 gtk, gtk.glade
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
import deluge.common
|
import deluge.common
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
|
|
||||||
class Preferences:
|
class Preferences(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
self.window = window
|
component.Component.__init__(self, "Preferences")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
self.glade = gtk.glade.XML(
|
self.glade = gtk.glade.XML(
|
||||||
pkg_resources.resource_filename("deluge.ui.gtkui",
|
pkg_resources.resource_filename("deluge.ui.gtkui",
|
||||||
"glade/preferences_dialog.glade"))
|
"glade/preferences_dialog.glade"))
|
||||||
@ -395,6 +397,10 @@ class Preferences:
|
|||||||
name = self.plugin_liststore.get_value(row, 0)
|
name = self.plugin_liststore.get_value(row, 0)
|
||||||
value = self.plugin_liststore.get_value(row, 1)
|
value = self.plugin_liststore.get_value(row, 1)
|
||||||
self.plugin_liststore.set_value(row, 1, not value)
|
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):
|
def on_plugin_selection_changed(self, treeselection):
|
||||||
log.debug("on_plugin_selection_changed")
|
log.debug("on_plugin_selection_changed")
|
||||||
|
@ -33,12 +33,15 @@
|
|||||||
|
|
||||||
import gtk
|
import gtk
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class StatusBar:
|
class StatusBar(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
self.window = window
|
component.Component.__init__(self, "StatusBar")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
self.statusbar = self.window.main_glade.get_widget("statusbar")
|
self.statusbar = self.window.main_glade.get_widget("statusbar")
|
||||||
|
|
||||||
# Add a HBox to the statusbar after removing the initial label widget
|
# 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 = self.statusbar.get_children()[0]
|
||||||
frame.remove(frame.get_children()[0])
|
frame.remove(frame.get_children()[0])
|
||||||
frame.add(self.hbox)
|
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
|
# Add in images and labels
|
||||||
|
self.clear_statusbar()
|
||||||
image = gtk.Image()
|
image = gtk.Image()
|
||||||
image.set_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU)
|
image.set_from_stock(gtk.STOCK_NETWORK, gtk.ICON_SIZE_MENU)
|
||||||
self.hbox.pack_start(image, expand=False, fill=False)
|
self.hbox.pack_start(image, expand=False, fill=False)
|
||||||
@ -67,10 +75,26 @@ class StatusBar:
|
|||||||
self.hbox.pack_start(self.label_upload_speed,
|
self.hbox.pack_start(self.label_upload_speed,
|
||||||
expand=False, fill=False)
|
expand=False, fill=False)
|
||||||
|
|
||||||
# Update once before showing
|
|
||||||
# self.update()
|
|
||||||
self.statusbar.show_all()
|
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):
|
def update(self):
|
||||||
# Set the max connections label
|
# Set the max connections label
|
||||||
max_connections = client.get_config_value("max_connections_global")
|
max_connections = client.get_config_value("max_connections_global")
|
||||||
@ -101,3 +125,4 @@ class StatusBar:
|
|||||||
self.label_upload_speed.set_text("%s/s (%s)" % (
|
self.label_upload_speed.set_text("%s/s (%s)" % (
|
||||||
deluge.common.fsize(client.get_upload_rate()),
|
deluge.common.fsize(client.get_upload_rate()),
|
||||||
max_upload_speed))
|
max_upload_speed))
|
||||||
|
|
||||||
|
@ -34,14 +34,16 @@
|
|||||||
import gtk
|
import gtk
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
import deluge.common
|
import deluge.common
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class SystemTray:
|
class SystemTray(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
self.window = window
|
component.Component.__init__(self, "SystemTray")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
self.config = ConfigManager("gtkui.conf")
|
self.config = ConfigManager("gtkui.conf")
|
||||||
self.config.register_set_function("enable_system_tray",
|
self.config.register_set_function("enable_system_tray",
|
||||||
self.on_enable_system_tray_set)
|
self.on_enable_system_tray_set)
|
||||||
@ -79,6 +81,7 @@ class SystemTray:
|
|||||||
deluge.common.get_pixmap("seeding16.png"))
|
deluge.common.get_pixmap("seeding16.png"))
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
log.debug("SystemTray start..")
|
||||||
# Build the bandwidth speed limit menus
|
# Build the bandwidth speed limit menus
|
||||||
self.build_tray_bwsetsubmenu()
|
self.build_tray_bwsetsubmenu()
|
||||||
|
|
||||||
|
@ -35,12 +35,14 @@ import pygtk
|
|||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk, gtk.glade
|
import gtk, gtk.glade
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class ToolBar:
|
class ToolBar(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
|
component.Component.__init__(self, "ToolBar")
|
||||||
log.debug("ToolBar Init..")
|
log.debug("ToolBar Init..")
|
||||||
self.window = window
|
self.window = component.get("MainWindow")
|
||||||
self.toolbar = self.window.main_glade.get_widget("toolbar")
|
self.toolbar = self.window.main_glade.get_widget("toolbar")
|
||||||
### Connect Signals ###
|
### Connect Signals ###
|
||||||
self.window.main_glade.signal_autoconnect({
|
self.window.main_glade.signal_autoconnect({
|
||||||
@ -94,34 +96,34 @@ class ToolBar:
|
|||||||
def on_toolbutton_add_clicked(self, data):
|
def on_toolbutton_add_clicked(self, data):
|
||||||
log.debug("on_toolbutton_add_clicked")
|
log.debug("on_toolbutton_add_clicked")
|
||||||
# Use the menubar's callback
|
# 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):
|
def on_toolbutton_remove_clicked(self, data):
|
||||||
log.debug("on_toolbutton_remove_clicked")
|
log.debug("on_toolbutton_remove_clicked")
|
||||||
# Use the menubar's callbacks
|
# 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):
|
def on_toolbutton_clear_clicked(self, data):
|
||||||
log.debug("on_toolbutton_clear_clicked")
|
log.debug("on_toolbutton_clear_clicked")
|
||||||
# Use the menubar's callbacks
|
# 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):
|
def on_toolbutton_pause_clicked(self, data):
|
||||||
log.debug("on_toolbutton_pause_clicked")
|
log.debug("on_toolbutton_pause_clicked")
|
||||||
# Use the menubar's callbacks
|
# 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):
|
def on_toolbutton_resume_clicked(self, data):
|
||||||
log.debug("on_toolbutton_resume_clicked")
|
log.debug("on_toolbutton_resume_clicked")
|
||||||
# Use the menubar's calbacks
|
# 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):
|
def on_toolbutton_preferences_clicked(self, data):
|
||||||
log.debug("on_toolbutton_preferences_clicked")
|
log.debug("on_toolbutton_preferences_clicked")
|
||||||
# Use the menubar's callbacks
|
# 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):
|
def on_toolbutton_plugins_clicked(self, data):
|
||||||
log.debug("on_toolbutton_plugins_clicked")
|
log.debug("on_toolbutton_plugins_clicked")
|
||||||
# Use the menubar's callbacks
|
# 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 gtk, gtk.glade
|
||||||
import gettext
|
import gettext
|
||||||
|
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
import deluge.common
|
import deluge.common
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
|
||||||
class TorrentDetails:
|
class TorrentDetails(component.Component):
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
self.window = window
|
component.Component.__init__(self, "TorrentDetails")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
glade = self.window.main_glade
|
glade = self.window.main_glade
|
||||||
|
|
||||||
self.notebook = glade.get_widget("torrent_info")
|
self.notebook = glade.get_widget("torrent_info")
|
||||||
@ -71,12 +73,16 @@ class TorrentDetails:
|
|||||||
self.eta = glade.get_widget("summary_eta")
|
self.eta = glade.get_widget("summary_eta")
|
||||||
self.torrent_path = glade.get_widget("summary_torrent_path")
|
self.torrent_path = glade.get_widget("summary_torrent_path")
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.clear()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
# Only update if this page is showing
|
# Only update if this page is showing
|
||||||
if self.notebook.page_num(self.details_tab) is \
|
if self.notebook.page_num(self.details_tab) is \
|
||||||
self.notebook.get_current_page():
|
self.notebook.get_current_page():
|
||||||
# Get the first selected torrent
|
# 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
|
# Only use the first torrent in the list or return if None selected
|
||||||
if selected is not None:
|
if selected is not None:
|
||||||
@ -154,3 +160,4 @@ class TorrentDetails:
|
|||||||
self.tracker_status.set_text("")
|
self.tracker_status.set_text("")
|
||||||
self.next_announce.set_text("")
|
self.next_announce.set_text("")
|
||||||
self.eta.set_text("")
|
self.eta.set_text("")
|
||||||
|
self.torrent_path.set_text("")
|
||||||
|
@ -40,6 +40,7 @@ import gettext
|
|||||||
import gobject
|
import gobject
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
|
import deluge.ui.component as component
|
||||||
import deluge.ui.client as client
|
import deluge.ui.client as client
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
import deluge.ui.gtkui.listview as listview
|
import deluge.ui.gtkui.listview as listview
|
||||||
@ -96,10 +97,11 @@ def cell_data_progress(column, cell, model, row, data):
|
|||||||
textstr = textstr + " %.2f%%" % value
|
textstr = textstr + " %.2f%%" % value
|
||||||
cell.set_property("text", textstr)
|
cell.set_property("text", textstr)
|
||||||
|
|
||||||
class TorrentView(listview.ListView):
|
class TorrentView(listview.ListView, component.Component):
|
||||||
"""TorrentView handles the listing of torrents."""
|
"""TorrentView handles the listing of torrents."""
|
||||||
def __init__(self, window):
|
def __init__(self):
|
||||||
self.window = window
|
component.Component.__init__(self, "TorrentView")
|
||||||
|
self.window = component.get("MainWindow")
|
||||||
# Call the ListView constructor
|
# Call the ListView constructor
|
||||||
listview.ListView.__init__(self,
|
listview.ListView.__init__(self,
|
||||||
self.window.main_glade.get_widget("torrent_view"))
|
self.window.main_glade.get_widget("torrent_view"))
|
||||||
@ -171,6 +173,11 @@ class TorrentView(listview.ListView):
|
|||||||
for torrent_id in session_state:
|
for torrent_id in session_state:
|
||||||
self.add_row(torrent_id)
|
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):
|
def update(self, columns=None):
|
||||||
"""Update the view. If columns is not None, it will attempt to only
|
"""Update the view. If columns is not None, it will attempt to only
|
||||||
update those columns selected.
|
update those columns selected.
|
||||||
@ -294,12 +301,12 @@ class TorrentView(listview.ListView):
|
|||||||
# We only care about right-clicks
|
# We only care about right-clicks
|
||||||
if event.button == 3:
|
if event.button == 3:
|
||||||
# Show the Torrent menu from the MenuBar
|
# 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)
|
torrentmenu.popup(None, None, None, event.button, event.time)
|
||||||
|
|
||||||
def on_selection_changed(self, treeselection):
|
def on_selection_changed(self, treeselection):
|
||||||
"""This callback is know when the selection has changed."""
|
"""This callback is know when the selection has changed."""
|
||||||
log.debug("on_selection_changed")
|
log.debug("on_selection_changed")
|
||||||
self.window.torrentdetails.update()
|
component.get("TorrentDetails").update()
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user