Merge branch 'master' into pieces-progress-bar

This commit is contained in:
Pedro Algarvio 2011-05-28 10:54:03 +01:00
commit ef98d19ed4
22 changed files with 216 additions and 131 deletions

1
create_potfiles_in.py Normal file → Executable file
View file

@ -1,3 +1,4 @@
#!/usr/bin/env python
import os
# Paths to exclude

View file

@ -166,6 +166,18 @@ def get_default_download_dir():
if windows_check():
return os.path.expanduser("~")
else:
from xdg.BaseDirectory import xdg_config_home
userdir_file = os.path.join(xdg_config_home, 'user-dirs.dirs')
try:
for line in open(userdir_file, 'r'):
if not line.startswith('#') and 'XDG_DOWNLOAD_DIR' in line:
download_dir = os.path.expandvars(\
line.partition("=")[2].rstrip().strip('"'))
if os.path.isdir(download_dir):
return download_dir
except IOError:
pass
return os.environ.get("HOME")
def windows_check():

View file

@ -88,7 +88,9 @@ class Core(component.Component):
# Set the user agent
self.settings = lt.session_settings()
self.settings.user_agent = "Deluge %s" % deluge.common.get_version()
self.settings.user_agent = "Deluge/%(deluge_version)s Libtorrent/%(lt_version)s" % \
{ 'deluge_version': deluge.common.get_version(),
'lt_version': self.get_libtorrent_version().rpartition(".")[0] }
# Set session settings
self.settings.send_redundant_have = True

View file

@ -620,6 +620,13 @@ class Torrent(object):
if distributed_copies < 0:
distributed_copies = 0.0
# Calculate the seeds:peers ratio
if self.status.num_incomplete == 0:
# Use -1.0 to signify infinity
seeds_peers_ratio = -1.0
else:
seeds_peers_ratio = self.status.num_complete / float(self.status.num_incomplete)
full_status = {
"active_time": self.status.active_time,
"all_time_download": self.status.all_time_download,
@ -651,6 +658,7 @@ class Torrent(object):
"remove_at_ratio": self.options["remove_at_ratio"],
"save_path": self.options["download_location"],
"seeding_time": self.status.seeding_time,
"seeds_peers_ratio": seeds_peers_ratio,
"seed_rank": self.status.seed_rank,
"state": self.state,
"stop_at_ratio": self.options["stop_at_ratio"],

View file

@ -384,7 +384,7 @@ class GtkUI(GtkPluginBase):
def create_columns(self, treeView):
rendererToggle = gtk.CellRendererToggle()
column = gtk.TreeViewColumn(
_("Active"), rendererToggle, activatable=True, active=1
_("Active"), rendererToggle, activatable=1, active=1
)
column.set_sort_column_id(1)
treeView.append_column(column)

View file

@ -44,7 +44,7 @@ __plugin_name__ = "AutoAdd"
__author__ = "Chase Sterling, Pedro Algarvio"
__author_email__ = "chase.sterling@gmail.com, pedro@algarvio.me"
__version__ = "1.02"
__url__ = "http://forum.deluge-torrent.org/viewtopic.php?f=9&t=26775"
__url__ = "http://dev.deluge-torrent.org/wiki/Plugins/AutoAdd"
__license__ = "GPLv3"
__description__ = "Monitors folders for .torrent files."
__long_description__ = """"""

View file

@ -39,15 +39,11 @@ __author_email__ = "mvoncken@gmail.com"
__version__ = "0.1"
__url__ = "http://deluge-torrent.org"
__license__ = "GPLv3"
__description__ = "Label plugin."
__description__ = "Allows labels to be assigned to torrents"
__long_description__ = """
Label plugin.
Offers filters on state,tracker and keyword.
adds a tracker column.
future: Real labels.
Allows labels to be assigned to torrents
Also offers filters on state, tracker and keywords
"""
__pkg_data__ = {__plugin_name__.lower(): ["template/*", "data/*"]}

View file

@ -46,10 +46,13 @@ __version__ = "0.1"
__url__ = "http://dev.deluge-torrent.org/"
__license__ = "GPLv3"
__description__ = "Plugin which provides notifications to Deluge."
__long_description__ = __description__ + """\
Email, Popup, Blink and Sound notifications are supported.
The plugin also allows other plugins to make use of itself for their own custom
notifications.
__long_description__ = """
Plugin which provides notifications to Deluge
Email, Popup, Blink and Sound notifications
The plugin also allows other plugins to make
use of itself for their own custom notifications
"""
__pkg_data__ = {__plugin_name__.lower(): ["template/*", "data/*"]}

View file

@ -182,6 +182,13 @@ class DelugeRPCProtocol(Protocol):
exception_cls = getattr(error, request[2])
exception = exception_cls(*request[3], **request[4])
# Ideally we would chain the deferreds instead of instance
# checking just to log them. But, that would mean that any
# errback on the fist deferred should returns it's failure
# so it could pass back to the 2nd deferred on the chain. But,
# that does not always happen.
# So, just do some instance checking and just log rpc error at
# diferent levels.
r = self.__rpc_requests[request_id]
msg = "RPCError Message Received!"
msg += "\n" + "-" * 80

View file

@ -56,11 +56,11 @@ class AboutDialog:
version = deluge.common.get_version()
self.about.set_copyright(u'Copyright \u00A9 2007-2009 Deluge Team')
self.about.set_copyright(u'Copyright \u00A9 2007-2011 Deluge Team')
self.about.set_comments(
"A peer-to-peer file sharing program\nutilizing the Bittorrent "
"protocol.\n\nCore Version: %coreversion%\nlibtorrent version: "
"%ltversion%")
"A peer-to-peer file sharing program\nutilizing the BitTorrent "
"protocol\n\n"
"Client Version: %s\n" % version)
self.about.set_version(version)
self.about.set_authors([
"Current Developers:", "Andrew Resch", "Damien Churchill",
@ -253,17 +253,21 @@ class AboutDialog:
"This program is free software; you can redistribute it and/or "
"modify it under the terms of the GNU General Public License as "
"published by the Free Software Foundation; either version 3 of "
"the License, or (at your option) any later version. This program "
"the License, or (at your option) any later version. \n\n"
"This program "
"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 "
"General Public License for more details. \n\n"
"You should have received "
"a copy of the GNU General Public License along with this program; "
"if not, see <http://www.gnu.org/licenses>. In addition, as a "
"if not, see <http://www.gnu.org/licenses>. \n\n"
"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) "
"all of the code used other than OpenSSL. \n\n"
"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 "
@ -271,7 +275,7 @@ class AboutDialog:
"source files in the program, then also delete it here."
))
self.about.set_website("http://deluge-torrent.org")
self.about.set_website_label("http://deluge-torrent.org")
self.about.set_website_label("www.deluge-torrent.org")
self.about.set_icon(common.get_deluge_icon())
self.about.set_logo(gtk.gdk.pixbuf_new_from_file(
@ -279,6 +283,13 @@ class AboutDialog:
))
if client.connected():
if not client.is_classicmode():
self.about.set_comments(
self.about.get_comments() + "Server Version: %coreversion%\n")
self.about.set_comments(
self.about.get_comments() + "Libtorrent Version: %ltversion%\n")
def on_lt_version(result):
c = self.about.get_comments()
c = c.replace("%ltversion%", result)
@ -290,7 +301,10 @@ class AboutDialog:
self.about.set_comments(c)
client.core.get_libtorrent_version().addCallback(on_lt_version)
client.daemon.info().addCallback(on_info)
if not client.is_classicmode():
client.daemon.info().addCallback(on_info)
else:
client.core.get_libtorrent_version().addCallback(on_lt_version)
def run(self):
self.about.show_all()

View file

@ -74,8 +74,6 @@ class EditTrackersDialog:
"on_button_edit_ok_clicked": self.on_button_edit_ok_clicked,
"on_button_remove_clicked": self.on_button_remove_clicked,
"on_button_down_clicked": self.on_button_down_clicked,
"on_button_ok_clicked": self.on_button_ok_clicked,
"on_button_cancel_clicked": self.on_button_cancel_clicked,
"on_button_add_ok_clicked": self.on_button_add_ok_clicked,
"on_button_add_cancel_clicked": self.on_button_add_cancel_clicked
})
@ -94,7 +92,6 @@ class EditTrackersDialog:
self.dialog.connect("delete-event", self._on_delete_event)
self.dialog.connect("response", self._on_response)
self.changed = False
def run(self):
# Make sure we have a torrent_id.. if not just return
@ -103,7 +100,9 @@ class EditTrackersDialog:
# Get the trackers for this torrent
session = component.get("SessionProxy")
session.get_torrent_status(self.torrent_id, ["trackers"]).addCallback(self._on_get_torrent_status)
session.get_torrent_status(
self.torrent_id, ["trackers"]
).addCallback(self._on_get_torrent_status)
client.force_call()
self.deferred = defer.Deferred()
@ -115,49 +114,50 @@ class EditTrackersDialog:
self.dialog.destroy()
def _on_response(self, widget, response):
self.deferred.callback(response)
if response == 1:
self.trackers = []
def each(model, path, iter, data):
tracker = {}
tracker["tier"] = model.get_value(iter, 0)
tracker["url"] = model.get_value(iter, 1)
self.trackers.append(tracker)
self.liststore.foreach(each, None)
if self.old_trackers != self.trackers:
# Set the torrens trackers
client.core.set_torrent_trackers(self.torrent_id, self.trackers)
self.deferred.callback(gtk.RESPONSE_OK)
else:
self.deferred.callback(gtk.RESPONSE_CANCEL)
else:
self.deferred.callback(gtk.RESPONSE_CANCEL)
self.dialog.destroy()
def _on_get_torrent_status(self, status):
"""Display trackers dialog"""
for tracker in status["trackers"]:
self.old_trackers = list(status["trackers"])
for tracker in self.old_trackers:
self.add_tracker(tracker["tier"], tracker["url"])
self.dialog.show()
def add_tracker(self, tier, url):
"""Adds a tracker to the list"""
self.liststore.append([tier, url])
self.changed = True
def get_selected(self):
"""Returns the selected tracker"""
return self.treeview.get_selection().get_selected()[1]
def on_button_up_clicked(self, widget):
log.debug("on_button_up_clicked")
selected = self.get_selected()
num_rows = self.liststore.iter_n_children(None)
if selected != None and num_rows > 1:
tier = self.liststore.get_value(selected, 0)
new_tier = tier + 1
# Now change the tier for this tracker
self.liststore.set_value(selected, 0, new_tier)
self.changed = True
def on_button_add_clicked(self, widget):
log.debug("on_button_add_clicked")
# Show the add tracker dialog
self.add_tracker_dialog.show()
self.glade.get_widget("textview_trackers").grab_focus()
self.changed = True
def on_button_remove_clicked(self, widget):
log.debug("on_button_remove_clicked")
selected = self.get_selected()
if selected != None:
self.liststore.remove(selected)
self.changed = True
def on_button_edit_clicked(self, widget):
"""edits an existing tracker"""
@ -179,10 +179,9 @@ class EditTrackersDialog:
tracker = self.glade.get_widget("entry_edit_tracker").get_text()
self.liststore.set_value(selected, 1, tracker)
self.edit_tracker_entry.hide()
self.changed = True
def on_button_down_clicked(self, widget):
log.debug("on_button_down_clicked")
def on_button_up_clicked(self, widget):
log.debug("on_button_up_clicked")
selected = self.get_selected()
num_rows = self.liststore.iter_n_children(None)
if selected != None and num_rows > 1:
@ -192,27 +191,16 @@ class EditTrackersDialog:
new_tier = tier - 1
# Now change the tier for this tracker
self.liststore.set_value(selected, 0, new_tier)
self.changed = True
def on_button_ok_clicked(self, widget):
log.debug("on_button_ok_clicked")
self.trackers = []
def each(model, path, iter, data):
tracker = {}
tracker["tier"] = model.get_value(iter, 0)
tracker["url"] = model.get_value(iter, 1)
self.trackers.append(tracker)
self.liststore.foreach(each, None)
# Set the torrens trackers
client.core.set_torrent_trackers(self.torrent_id, self.trackers)
if self.changed:
self.dialog.response(gtk.RESPONSE_OK)
else:
self.dialog.response(gtk.RESPONSE_CANCEL)
def on_button_cancel_clicked(self, widget):
log.debug("on_button_cancel_clicked")
self.dialog.response(gtk.RESPONSE_CANCEL)
def on_button_down_clicked(self, widget):
log.debug("on_button_down_clicked")
selected = self.get_selected()
num_rows = self.liststore.iter_n_children(None)
if selected != None and num_rows > 1:
tier = self.liststore.get_value(selected, 0)
new_tier = tier + 1
# Now change the tier for this tracker
self.liststore.set_value(selected, 0, new_tier)
def on_button_add_ok_clicked(self, widget):
log.debug("on_button_add_ok_clicked")

View file

@ -122,7 +122,8 @@ class FilesTab(Tab):
self._editing_index = None
# Filename column
column = gtk.TreeViewColumn(_("Filename"))
self.filename_column_name = _("Filename")
column = gtk.TreeViewColumn(self.filename_column_name)
render = gtk.CellRendererPixbuf()
column.pack_start(render, False)
column.add_attribute(render, "stock-id", 6)
@ -440,9 +441,8 @@ class FilesTab(Tab):
"""
Go through the tree and update the folder complete percentages.
"""
root = self.treestore.get_iter_root()
if self.treestore[root][5] != -1:
if root is None or self.treestore[root][5] != -1:
return
def get_completed_bytes(row):
@ -485,7 +485,10 @@ class FilesTab(Tab):
if self._editing_index == row[5]:
continue
progress_string = "%.2f%%" % (status["file_progress"][index] * 100)
try:
progress_string = "%.2f%%" % (status["file_progress"][index] * 100)
except IndexError:
continue
if row[2] != progress_string:
row[2] = progress_string
progress_value = status["file_progress"][index] * 100
@ -504,17 +507,15 @@ class FilesTab(Tab):
# We only care about right-clicks
if event.button == 3:
x, y = event.get_coords()
path = self.listview.get_path_at_pos(int(x), int(y))
if not path:
cursor_path = self.listview.get_path_at_pos(int(x), int(y))
if not cursor_path:
return
row = self.treestore.get_iter(path[0])
if self.get_selected_files():
if self.treestore.get_value(row, 5) not in self.get_selected_files():
paths = self.listview.get_selection().get_selected_rows()[1]
if cursor_path[0] not in paths:
row = self.treestore.get_iter(cursor_path[0])
self.listview.get_selection().unselect_all()
self.listview.get_selection().select_iter(row)
else:
self.listview.get_selection().select_iter(row)
for widget in self.file_menu_priority_items:
widget.set_sensitive(not self.__compact)
@ -523,16 +524,25 @@ class FilesTab(Tab):
return True
def _on_key_press_event(self, widget, event):
# Menu key
if gtk.gdk.keyval_name(event.keyval) != "Menu":
return
if not self.get_selected_files():
keyname = gtk.gdk.keyval_name(event.keyval)
func = getattr(self, 'keypress_' + keyname, None)
selected_rows = self.listview.get_selection().get_selected_rows()[1]
if func and selected_rows:
return func(event)
else:
return
def keypress_Menu(self, event):
self.file_menu.popup(None, None, None, 3, event.time)
return True
def keypress_F2(self, event):
path, col = self.listview.get_cursor()
for column in self.listview.get_columns():
if column.get_title() == self.filename_column_name:
self.listview.set_cursor(path, column, True)
return True
def _on_menuitem_open_file_activate(self, menuitem):
self._on_row_activated(None, None, None)

View file

@ -40,6 +40,7 @@ import gtk.glade
import logging
import pkg_resources
import glib
import warnings
import deluge.component as component
import deluge.common
@ -259,7 +260,11 @@ class FilterTreeView(component.Component):
value = model.get_value(row, 1)
label = model.get_value(row, 2)
count = model.get_value(row, 3)
pix = model.get_value(row, 4)
#Supress Warning: g_object_set_qdata: assertion `G_IS_OBJECT (object)' failed
with warnings.catch_warnings():
warnings.simplefilter("ignore")
pix = model.get_value(row, 4)
if pix:
self.renderpix.set_property("visible", True)

View file

@ -37,6 +37,7 @@
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_menuitem_addtorrent_activate"/>
<accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
@ -56,6 +57,7 @@
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_menuitem_createtorrent_activate"/>
<accelerator key="N" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
@ -80,6 +82,7 @@
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_menuitem_quitdaemon_activate"/>
<accelerator key="Q" modifiers="GDK_SHIFT_MASK|GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image3">
<property name="visible">True</property>
@ -131,6 +134,7 @@
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="activate" handler="on_menuitem_preferences_activate"/>
<accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/>
</widget>
</child>
<child>
@ -143,6 +147,7 @@
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_menuitem_connectionmanager_activate"/>
<accelerator key="M" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image4">
<property name="visible">True</property>
@ -318,6 +323,7 @@
<property name="use_underline">True</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_menuitem_faq_activate"/>
<accelerator key="F1" signal="activate"/>
<child internal-child="image">
<widget class="GtkImage" id="image6">
<property name="visible">True</property>

View file

@ -274,6 +274,13 @@
<property name="use_underline">True</property>
</widget>
</child>
<child>
<widget class="GtkMenuItem" id="menuitem_change_owner">
<property name="visible">False</property>
<property name="label" translatable="yes">_Change Ownership</property>
<property name="use_underline">True</property>
</widget>
</child>
</widget>
<widget class="GtkMenu" id="queue_torrent_menu">
<property name="visible">True</property>

View file

@ -33,11 +33,13 @@
#
#
import gobject
gobject.set_prgname("deluge")
# Install the twisted reactor
from twisted.internet import gtk2reactor
reactor = gtk2reactor.install()
import gobject
import gettext
import locale
import pkg_resources
@ -114,7 +116,7 @@ DEFAULT_PREFS = {
"interactive_add": True,
"focus_add_dialog": True,
"enable_system_tray": True,
"close_to_tray": True,
"close_to_tray": False,
"start_in_tray": False,
"enable_appindicator": False,
"lock_tray": False,

View file

@ -111,6 +111,15 @@ def cell_data_date_or_never(column, cell, model, row, data):
else:
cell.set_property('text', _("Never"))
def cell_data_speed_limit(column, cell, model, row, data):
"""Display value as a speed, eg. 2 KiB/s"""
speed = model.get_value(row, data)
speed_str = ""
if speed > 0:
speed_str = deluge.common.fspeed(speed * 1024)
cell.set_property('text', speed_str)
class ListViewColumnState:
"""Used for saving/loading column state"""
def __init__(self, name, position, width, visible, sort, sort_order):
@ -435,7 +444,7 @@ class ListView:
def add_column(self, header, render, col_types, hidden, position,
status_field, sortid, text=0, value=0, pixbuf=0, function=None,
column_type=None, sort_func=None, tooltip=None):
column_type=None, sort_func=None, tooltip=None, default=True):
"""Adds a column to the ListView"""
# Add the column types to liststore_columns
column_indices = []
@ -516,10 +525,12 @@ class ListView:
column.get_widget().set_tooltip_markup(tooltip)
# Check for loaded state and apply
column_in_state = False
if self.state != None:
for column_state in self.state:
if header == column_state.name:
# We found a loaded state
column_in_state = True
if column_state.width > 0:
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_fixed_width(column_state.width)
@ -530,7 +541,13 @@ class ListView:
)
column.set_visible(column_state.visible)
position = column_state.position
break
# Set this column to not visible if its not in the state and
# its not supposed to be shown by default
if not column_in_state and not default and not hidden:
column.set_visible(False)
if position is not None:
self.treeview.insert_column(column, position)
else:
@ -546,64 +563,64 @@ class ListView:
def add_text_column(self, header, col_type=str, hidden=False, position=None,
status_field=None, sortid=0, column_type="text",
sort_func=None, tooltip=None):
sort_func=None, tooltip=None, default=True):
"""Add a text column to the listview. Only the header name is required.
"""
render = gtk.CellRendererText()
self.add_column(header, render, col_type, hidden, position,
status_field, sortid, column_type=column_type,
sort_func=sort_func, tooltip=tooltip)
sort_func=sort_func, tooltip=tooltip, default=default)
return True
def add_bool_column(self, header, col_type=bool, hidden=False,
position=None, status_field=None, sortid=0,
column_type="bool", tooltip=None):
column_type="bool", tooltip=None, default=True):
"""Add a bool column to the listview"""
render = gtk.CellRendererToggle()
self.add_column(header, render, col_type, hidden, position,
status_field, sortid, column_type=column_type,
tooltip=tooltip)
tooltip=tooltip, default=default)
def add_func_column(self, header, function, col_types, sortid=0,
hidden=False, position=None, status_field=None,
column_type="func", sort_func=None, tooltip=None):
column_type="func", sort_func=None, tooltip=None, default=True):
"""Add a function column to the listview. Need a header name, the
function and the column types."""
render = gtk.CellRendererText()
self.add_column(header, render, col_types, hidden, position,
status_field, sortid, column_type=column_type,
function=function, sort_func=sort_func, tooltip=tooltip)
function=function, sort_func=sort_func, tooltip=tooltip, default=default)
return True
def add_progress_column(self, header, col_types=[float, str], sortid=0,
hidden=False, position=None, status_field=None,
function=None, column_type="progress",
tooltip=None):
tooltip=None, default=True):
"""Add a progress column to the listview."""
render = gtk.CellRendererProgress()
self.add_column(header, render, col_types, hidden, position,
status_field, sortid, function=function,
column_type=column_type, value=0, text=1,
tooltip=tooltip)
tooltip=tooltip, default=default)
return True
def add_texticon_column(self, header, col_types=[str, str], sortid=1,
hidden=False, position=None, status_field=None,
column_type="texticon", function=None,
tooltip=None):
tooltip=None, default=True):
"""Adds a texticon column to the listview."""
render1 = gtk.CellRendererPixbuf()
render2 = gtk.CellRendererText()
self.add_column(header, (render1, render2), col_types, hidden, position,
status_field, sortid, column_type=column_type,
function=function, pixbuf=0, text=1, tooltip=tooltip)
function=function, pixbuf=0, text=1, tooltip=tooltip, default=default)
return True

View file

@ -102,10 +102,6 @@ class MenuBar(component.Component):
self.torrentmenu = self.torrentmenu_glade.get_widget("torrent_menu")
self.menu_torrent = self.window.main_glade.get_widget("menu_torrent")
self.menuitem_change_owner = gtk.MenuItem(_("Change Ownership"))
self.torrentmenu_glade.get_widget("options_torrent_menu").append(self.menuitem_change_owner)
# Attach the torrent_menu to the Torrent file menu
self.menu_torrent.set_submenu(self.torrentmenu)
@ -209,12 +205,8 @@ class MenuBar(component.Component):
# Show the Torrent menu because we're connected to a host
self.menu_torrent.show()
# Hide the change owner submenu until we get the accounts back from the
# demon.
self.menuitem_change_owner.set_visible(False)
if client.get_auth_level() == deluge.common.AUTH_LEVEL_ADMIN:
# Get Known accounts to allow chaning ownership
# Get known accounts to allow changing ownership
client.core.get_known_accounts().addCallback(
self._on_known_accounts).addErrback(self._on_known_accounts_fail
)
@ -234,7 +226,6 @@ class MenuBar(component.Component):
self.window.main_glade.get_widget("separatormenuitem").hide()
self.window.main_glade.get_widget("menuitem_quitdaemon").hide()
def update_menu(self):
selected = component.get('TorrentView').get_selected_torrents()
if not selected or len(selected) == 0:
@ -531,7 +522,7 @@ class MenuBar(component.Component):
if len(known_accounts) <= 1:
return
self.menuitem_change_owner.set_visible(True)
self.torrentmenu_glade.get_widget("menuitem_change_owner").set_visible(True)
self.change_owner_submenu = gtk.Menu()
self.change_owner_submenu_items = {}
@ -549,13 +540,13 @@ class MenuBar(component.Component):
self.change_owner_submenu.show_all()
self.change_owner_submenu_items[None].set_active(True)
self.change_owner_submenu_items[None].hide()
self.menuitem_change_owner.connect(
self.torrentmenu_glade.get_widget("menuitem_change_owner").connect(
"activate", self._on_change_owner_submenu_active
)
self.menuitem_change_owner.set_submenu(self.change_owner_submenu)
self.torrentmenu_glade.get_widget("menuitem_change_owner").set_submenu(self.change_owner_submenu)
def _on_known_accounts_fail(self, reason):
self.menuitem_change_owner.set_visible(False)
self.torrentmenu_glade.get_widget("menuitem_change_owner").set_visible(False)
def _on_change_owner_submenu_active(self, widget):
log.debug("_on_change_owner_submenu_active")

View file

@ -43,6 +43,7 @@ import gtk.glade
import gettext
import gobject
import logging
import warnings
from urlparse import urlparse
import deluge.common
@ -77,15 +78,19 @@ ICON_STATE = {
"Seeding": icon_seeding,
"Paused": icon_inactive,
"Error": icon_alert,
"Queued": icon_queued
"Queued": icon_queued,
"Checking Resume Data": icon_checking
}
def cell_data_statusicon(column, cell, model, row, data):
"""Display text with an icon"""
try:
icon = ICON_STATE[model.get_value(row, data)]
if cell.get_property("pixbuf") != icon:
cell.set_property("pixbuf", icon)
#Supress Warning: g_object_set_qdata: assertion `G_IS_OBJECT (object)' failed
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if cell.get_property("pixbuf") != icon:
cell.set_property("pixbuf", icon)
except KeyError:
pass
@ -104,8 +109,11 @@ def cell_data_trackericon(column, cell, model, row, data):
else:
icon = create_blank_icon()
if cell.get_property("pixbuf") != icon:
cell.set_property("pixbuf", icon)
#Supress Warning: g_object_set_qdata: assertion `G_IS_OBJECT (object)' failed
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if cell.get_property("pixbuf") != icon:
cell.set_property("pixbuf", icon)
host = model[row][data]
if host:
@ -214,45 +222,51 @@ class TorrentView(listview.ListView, component.Component):
status_field=["total_wanted"])
self.add_func_column(_("Downloaded"), listview.cell_data_size,
[gobject.TYPE_UINT64],
status_field=["all_time_download"])
status_field=["all_time_download"], default=False)
self.add_func_column(_("Uploaded"), listview.cell_data_size,
[gobject.TYPE_UINT64],
status_field=["total_uploaded"])
status_field=["total_uploaded"], default=False)
self.add_progress_column(_("Progress"),
status_field=["progress", "state"],
col_types=[float, str],
function=cell_data_progress)
self.add_func_column(_("Seeders"), listview.cell_data_peer, [int, int],
status_field=["num_seeds", "total_seeds"],
sort_func=seed_peer_column_sort)
sort_func=seed_peer_column_sort, default=False)
self.add_func_column(_("Peers"), listview.cell_data_peer, [int, int],
status_field=["num_peers", "total_peers"],
sort_func=seed_peer_column_sort)
sort_func=seed_peer_column_sort, default=False)
self.add_func_column(_("Seeders") + "/" + _("Peers"), listview.cell_data_ratio, [float],
status_field=["seeds_peers_ratio"], default=False)
self.add_func_column(_("Down Speed"), listview.cell_data_speed, [float],
status_field=["download_payload_rate"])
self.add_func_column(_("Up Speed"), listview.cell_data_speed, [float],
status_field=["upload_payload_rate"])
self.add_func_column(_("Down Limit"), listview.cell_data_speed_limit, [float],
status_field=["max_download_speed"], default=False)
self.add_func_column(_("Up Limit"), listview.cell_data_speed_limit, [float],
status_field=["max_upload_speed"], default=False)
self.add_func_column(_("ETA"), listview.cell_data_time, [int],
status_field=["eta"], sort_func=eta_column_sort)
self.add_func_column(_("Ratio"), listview.cell_data_ratio, [float],
status_field=["ratio"])
status_field=["ratio"], default=False)
self.add_func_column(_("Avail"), listview.cell_data_ratio, [float],
status_field=["distributed_copies"])
status_field=["distributed_copies"], default=False)
self.add_func_column(_("Added"), listview.cell_data_date, [float],
status_field=["time_added"])
status_field=["time_added"], default=False)
self.add_func_column(_("Last Seen Complete"),
listview.cell_data_date_or_never, [float],
status_field=["last_seen_complete"])
status_field=["last_seen_complete"], default=False)
self.add_texticon_column(_("Tracker"),
status_field=["tracker_host", "tracker_host"],
function=cell_data_trackericon)
self.add_text_column(_("Save Path"), status_field=["save_path"])
self.add_text_column(_("Owner"), status_field=["owner"])
self.add_bool_column(_("Public"), status_field=["public"])
function=cell_data_trackericon, default=False)
self.add_text_column(_("Save Path"), status_field=["save_path"], default=False)
self.add_text_column(_("Owner"), status_field=["owner"], default=False)
self.add_bool_column(_("Public"), status_field=["public"], default=False)
self.restore_columns_order_from_state()
self.add_bool_column(_("Shared"), status_field=["shared"],
tooltip=_("Torrent is shared between other Deluge "
"users or not."))
"users or not."), default=False)
# Set filter to None for now
self.filter = None

0
gettextize.sh Normal file → Executable file
View file

1
msgfmt.py Normal file → Executable file
View file

@ -1,3 +1,4 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Lwis <loewis@informatik.hu-berlin.de>
# Plural forms support added by alexander smishlajev <alex@tycobka.lv>

View file

@ -1,3 +1,4 @@
#!/usr/bin/env python
#
# setup.py
#