mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-20 11:35:49 +00:00
Merge branch 'master' into pieces-progress-bar
This commit is contained in:
commit
ef98d19ed4
22 changed files with 216 additions and 131 deletions
1
create_potfiles_in.py
Normal file → Executable file
1
create_potfiles_in.py
Normal file → Executable file
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
|
||||
# Paths to exclude
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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__ = """"""
|
||||
|
|
|
@ -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/*"]}
|
||||
|
||||
|
|
|
@ -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/*"]}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
0
gettextize.sh
Normal file → Executable file
1
msgfmt.py
Normal file → Executable file
1
msgfmt.py
Normal file → Executable 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>
|
||||
|
|
1
setup.py
1
setup.py
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# setup.py
|
||||
#
|
||||
|
|
Loading…
Add table
Reference in a new issue