mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-10 11:36:01 +00:00
[GTKUI] Refactor gtk imports and code
* Where possible use 'from gtk import ...', i.e. if repeated often or under 10 individual imports. * Remove osx_check to not show svg. It's only an issue on Windows so should work fine... * Rearrange and deduplicate code into d.u.g.common for getting pixbuf from files. * Use 'from gtk.gdk import...' to make it cleaner to apply GTK3 changes in future. * Move generic icon code from torrent_data_funcs to common. * Fix pylint import warnings and add WindowsError to pylintrc file.
This commit is contained in:
parent
c8e6a4476d
commit
0cdf0230e9
@ -281,7 +281,7 @@ dummy-variables-rgx=_$|dummy
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=_,_n,__request__
|
||||
additional-builtins=_,_n,__request__,WindowsError
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
|
@ -41,7 +41,7 @@ if windows_check():
|
||||
import _winreg
|
||||
try:
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\\7-Zip')
|
||||
except WindowsError: # pylint: disable=undefined-variable
|
||||
except WindowsError:
|
||||
pass
|
||||
else:
|
||||
win_7z_path = os.path.join(_winreg.QueryValueEx(hkey, 'Path')[0], '7z.exe')
|
||||
|
@ -10,9 +10,9 @@
|
||||
import gtk
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import get_pixmap, get_version
|
||||
from deluge.common import get_version
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.gtkui.common import get_deluge_icon
|
||||
from deluge.ui.gtkui.common import get_deluge_icon, get_pixbuf
|
||||
|
||||
|
||||
class AboutDialog(object):
|
||||
@ -247,7 +247,7 @@ class AboutDialog(object):
|
||||
self.about.set_website_label('deluge-torrent.org')
|
||||
|
||||
self.about.set_icon(get_deluge_icon())
|
||||
self.about.set_logo(gtk.gdk.pixbuf_new_from_file(get_pixmap('deluge-about.png')))
|
||||
self.about.set_logo(get_pixbuf('deluge-about.png'))
|
||||
|
||||
if client.connected():
|
||||
if not client.is_standalone():
|
||||
|
@ -15,14 +15,46 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
import gtk
|
||||
from gobject import GError
|
||||
from gtk import SORT_ASCENDING, Menu, MenuItem, RadioMenuItem, SeparatorMenuItem, icon_theme_get_default
|
||||
from gtk.gdk import COLORSPACE_RGB, Pixbuf, pixbuf_new_from_file, pixbuf_new_from_file_at_size
|
||||
|
||||
import deluge.common
|
||||
from deluge.common import get_pixmap, osx_check, windows_check
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def create_blank_pixbuf(size=16):
|
||||
pix = Pixbuf(COLORSPACE_RGB, True, 8, size, size)
|
||||
pix.fill(0x0)
|
||||
return pix
|
||||
|
||||
|
||||
def get_pixbuf(filename):
|
||||
try:
|
||||
return pixbuf_new_from_file(get_pixmap(filename))
|
||||
except GError as ex:
|
||||
log.warning(ex)
|
||||
return create_blank_pixbuf()
|
||||
|
||||
# Status icons.. Create them from file only once to avoid constantly re-creating them.
|
||||
icon_downloading = get_pixbuf('downloading16.png')
|
||||
icon_seeding = get_pixbuf('seeding16.png')
|
||||
icon_inactive = get_pixbuf('inactive16.png')
|
||||
icon_alert = get_pixbuf('alert16.png')
|
||||
icon_queued = get_pixbuf('queued16.png')
|
||||
icon_checking = get_pixbuf('checking16.png')
|
||||
|
||||
|
||||
def get_pixbuf_at_size(filename, size):
|
||||
try:
|
||||
return pixbuf_new_from_file_at_size(get_pixmap(filename), size, size)
|
||||
except GError as ex:
|
||||
# Failed to load the pixbuf (Bad image file), so return a blank pixbuf.
|
||||
log.warning(ex)
|
||||
return create_blank_pixbuf(size)
|
||||
|
||||
|
||||
def get_logo(size):
|
||||
"""A Deluge logo.
|
||||
|
||||
@ -33,12 +65,9 @@ def get_logo(size):
|
||||
gtk.gdk.Pixbuf: deluge logo
|
||||
"""
|
||||
filename = 'deluge.svg'
|
||||
if deluge.common.windows_check() or deluge.common.osx_check():
|
||||
if windows_check():
|
||||
filename = 'deluge.png'
|
||||
try:
|
||||
return gtk.gdk.pixbuf_new_from_file_at_size(deluge.common.get_pixmap(filename), size, size)
|
||||
except GError as ex:
|
||||
log.warning(ex)
|
||||
return get_pixbuf_at_size(filename, size)
|
||||
|
||||
|
||||
def build_menu_radio_list(value_list, callback, pref_value=None, suffix=None, show_notset=False,
|
||||
@ -60,7 +89,7 @@ def build_menu_radio_list(value_list, callback, pref_value=None, suffix=None, sh
|
||||
Returns:
|
||||
gtk.Menu: The menu radio
|
||||
"""
|
||||
menu = gtk.Menu()
|
||||
menu = Menu()
|
||||
group = None
|
||||
|
||||
if pref_value > -1 and pref_value not in value_list:
|
||||
@ -71,7 +100,7 @@ def build_menu_radio_list(value_list, callback, pref_value=None, suffix=None, sh
|
||||
item_text = str(value)
|
||||
if suffix:
|
||||
item_text += ' ' + suffix
|
||||
menuitem = gtk.RadioMenuItem(group=group, label=item_text)
|
||||
menuitem = RadioMenuItem(group=group, label=item_text)
|
||||
group = menuitem
|
||||
if pref_value and value == pref_value:
|
||||
menuitem.set_active(True)
|
||||
@ -80,7 +109,7 @@ def build_menu_radio_list(value_list, callback, pref_value=None, suffix=None, sh
|
||||
menu.append(menuitem)
|
||||
|
||||
if show_notset:
|
||||
menuitem = gtk.RadioMenuItem(group=group, label=notset_label)
|
||||
menuitem = RadioMenuItem(group=group, label=notset_label)
|
||||
menuitem.set_name('unlimited')
|
||||
if pref_value and pref_value < notset_lessthan:
|
||||
menuitem.set_active(True)
|
||||
@ -88,9 +117,9 @@ def build_menu_radio_list(value_list, callback, pref_value=None, suffix=None, sh
|
||||
menu.append(menuitem)
|
||||
|
||||
if show_other:
|
||||
menuitem = gtk.SeparatorMenuItem()
|
||||
menuitem = SeparatorMenuItem()
|
||||
menu.append(menuitem)
|
||||
menuitem = gtk.MenuItem(_('Other...'))
|
||||
menuitem = MenuItem(_('Other...'))
|
||||
menuitem.set_name('other')
|
||||
menuitem.connect('activate', callback)
|
||||
menu.append(menuitem)
|
||||
@ -135,11 +164,11 @@ def get_deluge_icon():
|
||||
Returns:
|
||||
gtk.gdk.Pixbuf: the deluge icon
|
||||
"""
|
||||
if deluge.common.windows_check():
|
||||
if windows_check():
|
||||
return get_logo(32)
|
||||
else:
|
||||
try:
|
||||
icon_theme = gtk.icon_theme_get_default()
|
||||
icon_theme = icon_theme_get_default()
|
||||
return icon_theme.load_icon('deluge', 64, 0)
|
||||
except GError:
|
||||
return get_logo(64)
|
||||
@ -156,12 +185,12 @@ def associate_magnet_links(overwrite=False):
|
||||
bool: True if association was set
|
||||
"""
|
||||
|
||||
if deluge.common.windows_check():
|
||||
if windows_check():
|
||||
import _winreg
|
||||
|
||||
try:
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
except WindowsError: # pylint: disable=undefined-variable
|
||||
except WindowsError:
|
||||
overwrite = True
|
||||
else:
|
||||
_winreg.CloseKey(hkey)
|
||||
@ -170,7 +199,7 @@ def associate_magnet_links(overwrite=False):
|
||||
deluge_exe = os.path.join(os.path.dirname(sys.executable), 'deluge.exe')
|
||||
try:
|
||||
magnet_key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
except WindowsError: # pylint: disable=undefined-variable
|
||||
except WindowsError:
|
||||
# Could not create for all users, falling back to current user
|
||||
magnet_key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, 'Software\\Classes\\Magnet')
|
||||
|
||||
@ -182,7 +211,7 @@ def associate_magnet_links(overwrite=False):
|
||||
_winreg.CloseKey(magnet_key)
|
||||
|
||||
# Don't try associate magnet on OSX see: #2420
|
||||
elif not deluge.common.osx_check():
|
||||
elif not osx_check():
|
||||
# gconf method is only available in a GNOME environment
|
||||
try:
|
||||
import gconf
|
||||
@ -280,7 +309,7 @@ def listview_replace_treestore(listview):
|
||||
treestore.clear()
|
||||
treestore.set_default_sort_func(lambda *args: 0)
|
||||
original_sort = treestore.get_sort_column_id()
|
||||
treestore.set_sort_column_id(-1, gtk.SORT_ASCENDING)
|
||||
treestore.set_sort_column_id(-1, SORT_ASCENDING)
|
||||
|
||||
yield
|
||||
|
||||
|
@ -13,8 +13,8 @@ import gtk
|
||||
from twisted.internet import defer
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import get_pixmap, osx_check, windows_check
|
||||
from deluge.ui.gtkui.common import get_deluge_icon
|
||||
from deluge.common import windows_check
|
||||
from deluge.ui.gtkui.common import get_deluge_icon, get_pixbuf_at_size
|
||||
|
||||
|
||||
class BaseDialog(gtk.Dialog):
|
||||
@ -48,10 +48,9 @@ class BaseDialog(gtk.Dialog):
|
||||
image = gtk.Image()
|
||||
if not gtk.stock_lookup(icon) and (icon.endswith('.svg') or icon.endswith('.png')):
|
||||
# Hack for Windows since it doesn't support svg
|
||||
if icon.endswith('.svg') and (windows_check() or osx_check()):
|
||||
if icon.endswith('.svg') and windows_check():
|
||||
icon = icon.rpartition('.svg')[0] + '16.png'
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(get_pixmap(icon), 32, 32)
|
||||
image.set_from_pixbuf(pixbuf)
|
||||
image.set_from_pixbuf(get_pixbuf_at_size(icon, 32))
|
||||
else:
|
||||
image.set_from_stock(icon, gtk.ICON_SIZE_DIALOG)
|
||||
image.set_alignment(0.5, 0.0)
|
||||
|
@ -14,8 +14,8 @@ import logging
|
||||
import os.path
|
||||
|
||||
import gtk
|
||||
import gtk.gdk
|
||||
from gobject import TYPE_UINT64
|
||||
from gtk.gdk import ACTION_DEFAULT, ACTION_MOVE, BUTTON1_MASK, keyval_name # pylint: disable=ungrouped-imports
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import FILE_PRIORITY, open_file, show_file
|
||||
@ -193,10 +193,8 @@ class FilesTab(Tab):
|
||||
self.listview.connect('button-press-event', self._on_button_press_event)
|
||||
|
||||
self.listview.enable_model_drag_source(
|
||||
gtk.gdk.BUTTON1_MASK,
|
||||
[('text/plain', 0, 0)],
|
||||
gtk.gdk.ACTION_DEFAULT | gtk.gdk.ACTION_MOVE)
|
||||
self.listview.enable_model_drag_dest([('text/plain', 0, 0)], gtk.gdk.ACTION_DEFAULT)
|
||||
BUTTON1_MASK, [('text/plain', 0, 0)], ACTION_DEFAULT | ACTION_MOVE)
|
||||
self.listview.enable_model_drag_dest([('text/plain', 0, 0)], ACTION_DEFAULT)
|
||||
|
||||
self.listview.connect('drag_data_get', self._on_drag_data_get_data)
|
||||
self.listview.connect('drag_data_received', self._on_drag_data_received_data)
|
||||
@ -500,7 +498,7 @@ class FilesTab(Tab):
|
||||
return True
|
||||
|
||||
def _on_key_press_event(self, widget, event):
|
||||
keyname = gtk.gdk.keyval_name(event.keyval)
|
||||
keyname = keyval_name(event.keyval)
|
||||
if keyname is not None:
|
||||
func = getattr(self, 'keypress_' + keyname.lower(), None)
|
||||
selected_rows = self.listview.get_selection().get_selected_rows()[1]
|
||||
|
@ -14,13 +14,14 @@ import os
|
||||
import warnings
|
||||
|
||||
import gtk
|
||||
import pango
|
||||
from gobject import GError
|
||||
from gtk.gdk import Pixbuf
|
||||
from pango import ELLIPSIZE_END
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import TORRENT_STATE, get_pixmap, resource_filename
|
||||
from deluge.common import TORRENT_STATE, resource_filename
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.gtkui.common import get_pixbuf, get_pixbuf_at_size
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -61,7 +62,7 @@ class FilterTreeView(component.Component):
|
||||
|
||||
# Create the treestore
|
||||
# cat, value, label, count, pixmap, visible
|
||||
self.treestore = gtk.TreeStore(str, str, str, int, gtk.gdk.Pixbuf, bool)
|
||||
self.treestore = gtk.TreeStore(str, str, str, int, Pixbuf, bool)
|
||||
|
||||
# Create the column and cells
|
||||
column = gtk.TreeViewColumn('Filters')
|
||||
@ -72,7 +73,7 @@ class FilterTreeView(component.Component):
|
||||
column.add_attribute(self.cell_pix, 'pixbuf', 4)
|
||||
# label cell
|
||||
cell_label = gtk.CellRendererText()
|
||||
cell_label.set_property('ellipsize', pango.ELLIPSIZE_END)
|
||||
cell_label.set_property('ellipsize', ELLIPSIZE_END)
|
||||
column.pack_start(cell_label, expand=True)
|
||||
column.set_cell_data_func(cell_label, self.render_cell_data, None)
|
||||
# count cell
|
||||
@ -242,26 +243,10 @@ class FilterTreeView(component.Component):
|
||||
pix = TRACKER_PIX.get(value, None)
|
||||
|
||||
if pix:
|
||||
try:
|
||||
return gtk.gdk.pixbuf_new_from_file(get_pixmap('%s16.png' % pix))
|
||||
except GError as ex:
|
||||
log.warning(ex)
|
||||
return self.get_transparent_pix(16, 16)
|
||||
|
||||
def get_transparent_pix(self, width, height):
|
||||
pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height)
|
||||
pix.fill(0x0000000)
|
||||
return pix
|
||||
return get_pixbuf('%s16.png' % pix)
|
||||
|
||||
def set_row_image(self, cat, value, filename):
|
||||
pix = None
|
||||
try: # assume we could get trashed images here..
|
||||
pix = gtk.gdk.pixbuf_new_from_file_at_size(filename, 16, 16)
|
||||
except Exception as ex:
|
||||
log.debug(ex)
|
||||
|
||||
if not pix:
|
||||
pix = self.get_transparent_pix(16, 16)
|
||||
pix = get_pixbuf_at_size(filename, 16)
|
||||
row = self.filters[(cat, value)]
|
||||
self.treestore.set_value(row, 4, pix)
|
||||
return False
|
||||
|
@ -6,6 +6,7 @@
|
||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||
# See LICENSE for more details.
|
||||
#
|
||||
# pylint: disable=wrong-import-position
|
||||
|
||||
from __future__ import division
|
||||
|
||||
@ -19,8 +20,9 @@ import pygtk # isort:skip (Required before gtk import).
|
||||
pygtk.require('2.0') # NOQA: E402
|
||||
|
||||
# isort:imports-thirdparty
|
||||
import gtk
|
||||
from gobject import set_prgname
|
||||
from gtk import RESPONSE_OK, RESPONSE_YES
|
||||
from gtk.gdk import WINDOWING, threads_enter, threads_init, threads_leave
|
||||
from twisted.internet import defer, gtk2reactor
|
||||
from twisted.internet.error import ReactorAlreadyInstalledError
|
||||
from twisted.internet.task import LoopingCall
|
||||
@ -33,8 +35,8 @@ except ReactorAlreadyInstalledError as ex:
|
||||
from twisted.internet import reactor
|
||||
|
||||
# isort:imports-firstparty
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
from deluge.common import fsize, fspeed, get_default_download_dir, osx_check, windows_check
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.error import AuthenticationRequired, BadLoginError, DaemonRunningError
|
||||
from deluge.ui.client import client
|
||||
@ -103,11 +105,11 @@ DEFAULT_PREFS = {
|
||||
'autoconnect_host_id': None,
|
||||
'autostart_localhost': False,
|
||||
'autoadd_queued': False,
|
||||
'choose_directory_dialog_path': deluge.common.get_default_download_dir(),
|
||||
'choose_directory_dialog_path': get_default_download_dir(),
|
||||
'show_new_releases': True,
|
||||
'ntf_tray_blink': True,
|
||||
'ntf_sound': False,
|
||||
'ntf_sound_path': deluge.common.get_default_download_dir(),
|
||||
'ntf_sound_path': get_default_download_dir(),
|
||||
'ntf_popup': False,
|
||||
'ntf_email': False,
|
||||
'ntf_email_add': '',
|
||||
@ -144,16 +146,15 @@ class GtkUI(object):
|
||||
log.debug("OS signal 'die' caught with args: %s", args)
|
||||
reactor.stop()
|
||||
|
||||
if deluge.common.windows_check():
|
||||
if windows_check():
|
||||
from win32api import SetConsoleCtrlHandler
|
||||
SetConsoleCtrlHandler(on_die, True)
|
||||
log.debug("Win32 'die' handler registered")
|
||||
elif deluge.common.osx_check():
|
||||
if gtk.gdk.WINDOWING == 'quartz':
|
||||
import gtkosx_application
|
||||
self.osxapp = gtkosx_application.gtkosx_application_get()
|
||||
self.osxapp.connect('NSApplicationWillTerminate', on_die)
|
||||
log.debug("OSX quartz 'die' handler registered")
|
||||
elif osx_check() and WINDOWING == 'quartz':
|
||||
import gtkosx_application
|
||||
self.osxapp = gtkosx_application.gtkosx_application_get()
|
||||
self.osxapp.connect('NSApplicationWillTerminate', on_die)
|
||||
log.debug("OSX quartz 'die' handler registered")
|
||||
|
||||
# Set process name again to fix gtk issue
|
||||
setproctitle(getproctitle())
|
||||
@ -179,7 +180,7 @@ class GtkUI(object):
|
||||
self.ipcinterface = IPCInterface(args.torrents)
|
||||
|
||||
# Initialize gdk threading
|
||||
gtk.gdk.threads_init()
|
||||
threads_init()
|
||||
|
||||
# We make sure that the UI components start once we get a core URI
|
||||
client.set_disconnect_callback(self.__on_disconnect)
|
||||
@ -199,7 +200,7 @@ class GtkUI(object):
|
||||
self.statusbar = StatusBar()
|
||||
self.addtorrentdialog = AddTorrentDialog()
|
||||
|
||||
if deluge.common.osx_check() and gtk.gdk.WINDOWING == 'quartz':
|
||||
if osx_check() and WINDOWING == 'quartz':
|
||||
def nsapp_open_file(osxapp, filename):
|
||||
# Ignore command name which is raised at app launch (python opening main script).
|
||||
if filename == sys.argv[0]:
|
||||
@ -235,11 +236,11 @@ class GtkUI(object):
|
||||
reactor.callWhenRunning(self._on_reactor_start)
|
||||
|
||||
# Initialize gdk threading
|
||||
gtk.gdk.threads_enter()
|
||||
threads_enter()
|
||||
reactor.run()
|
||||
# Reactor is not running. Any async callbacks (Deferreds) can no longer
|
||||
# be processed from this point on.
|
||||
gtk.gdk.threads_leave()
|
||||
threads_leave()
|
||||
|
||||
def shutdown(self, *args, **kwargs):
|
||||
log.debug('GTKUI shutting down...')
|
||||
@ -281,10 +282,9 @@ class GtkUI(object):
|
||||
delta_sent = sent - self.daemon_bps[1]
|
||||
delta_recv = recv - self.daemon_bps[2]
|
||||
self.daemon_bps = (t, sent, recv)
|
||||
sent_rate = deluge.common.fspeed(delta_sent / delta_time)
|
||||
recv_rate = deluge.common.fspeed(delta_recv / delta_time)
|
||||
log.debug('RPC: Sent %s (%s) Recv %s (%s)',
|
||||
deluge.common.fsize(sent), sent_rate, deluge.common.fsize(recv), recv_rate)
|
||||
sent_rate = fspeed(delta_sent / delta_time)
|
||||
recv_rate = fspeed(delta_recv / delta_time)
|
||||
log.debug('RPC: Sent %s (%s) Recv %s (%s)', fsize(sent), sent_rate, fsize(recv), recv_rate)
|
||||
|
||||
def _on_reactor_start(self):
|
||||
log.debug('_on_reactor_start')
|
||||
@ -292,7 +292,7 @@ class GtkUI(object):
|
||||
|
||||
if self.config['standalone']:
|
||||
def on_dialog_response(response):
|
||||
if response != gtk.RESPONSE_YES:
|
||||
if response != RESPONSE_YES:
|
||||
# The user does not want to turn Standalone Mode off, so just quit
|
||||
self.mainwindow.quit()
|
||||
return
|
||||
@ -395,7 +395,7 @@ class GtkUI(object):
|
||||
dialog = AuthenticationDialog(reason.value.message, reason.value.username)
|
||||
|
||||
def dialog_finished(response_id, host, port):
|
||||
if response_id == gtk.RESPONSE_OK:
|
||||
if response_id == RESPONSE_OK:
|
||||
reactor.callLater(
|
||||
0.5, do_connect, try_counter - 1,
|
||||
host, port, dialog.get_username(),
|
||||
@ -425,7 +425,7 @@ class GtkUI(object):
|
||||
break
|
||||
|
||||
if self.config['show_connection_manager_on_start']:
|
||||
if deluge.common.windows_check():
|
||||
if windows_check():
|
||||
# Call to simulate() required to workaround showing daemon status (see #2813)
|
||||
reactor.simulate()
|
||||
self.connectionmanager.show()
|
||||
|
@ -144,8 +144,8 @@ class IPCInterface(component.Component):
|
||||
reactor.run()
|
||||
if self.factory.stop:
|
||||
log.info('Success sending arguments to running Deluge.')
|
||||
import gtk
|
||||
gtk.gdk.notify_startup_complete()
|
||||
from gtk.gdk import notify_startup_complete
|
||||
notify_startup_complete()
|
||||
sys.exit(0)
|
||||
else:
|
||||
if restart_tempfile:
|
||||
|
@ -11,10 +11,11 @@ import logging
|
||||
|
||||
import gtk
|
||||
from gobject import SIGNAL_RUN_LAST, TYPE_NONE, signal_new
|
||||
from gtk.gdk import Event # pylint: disable=ungrouped-imports
|
||||
|
||||
from deluge.ui.gtkui.common import load_pickled_state_file, save_pickled_state_file
|
||||
|
||||
signal_new('button-press-event', gtk.TreeViewColumn, SIGNAL_RUN_LAST, TYPE_NONE, (gtk.gdk.Event,))
|
||||
signal_new('button-press-event', gtk.TreeViewColumn, SIGNAL_RUN_LAST, TYPE_NONE, (Event,))
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -13,12 +13,13 @@ import os.path
|
||||
from hashlib import sha1 as sha
|
||||
|
||||
import gtk
|
||||
from gtk.gdk import ACTION_COPY, WINDOW_STATE_ICONIFIED, WINDOW_STATE_MAXIMIZED, WINDOW_STATE_WITHDRAWN
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet.error import ReactorNotRunning
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
import deluge.ui.gtkui.common
|
||||
from deluge.common import fspeed, resource_filename
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.gtkui.dialogs import PasswordDialog
|
||||
@ -73,27 +74,21 @@ class MainWindow(component.Component):
|
||||
"'component.get(\"MainWindow\").connect_signals()'")
|
||||
self.main_builder.connect_signals = patched_connect_signals
|
||||
|
||||
# Get the gtk builder file for the main window
|
||||
self.main_builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'main_window.ui')))
|
||||
# The new release dialog
|
||||
self.main_builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'main_window.new_release.ui')))
|
||||
# The tabs
|
||||
self.main_builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'main_window.tabs.ui')))
|
||||
# The tabs file menu
|
||||
self.main_builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'main_window.tabs.menu_file.ui')))
|
||||
# The tabs peer menu
|
||||
self.main_builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'main_window.tabs.menu_peer.ui')))
|
||||
# Get Gtk Builder files Main Window, New release dialog, and Tabs.
|
||||
self.main_builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'main_window.ui')))
|
||||
self.main_builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'main_window.new_release.ui')))
|
||||
self.main_builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'main_window.tabs.ui')))
|
||||
self.main_builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'main_window.tabs.menu_file.ui')))
|
||||
self.main_builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'main_window.tabs.menu_peer.ui')))
|
||||
|
||||
self.window = self.main_builder.get_object('main_window')
|
||||
|
||||
self.window.set_icon(deluge.ui.gtkui.common.get_deluge_icon())
|
||||
self.vpaned = self.main_builder.get_object('vpaned')
|
||||
|
||||
self.initial_vpaned_position = self.config['window_pane_position']
|
||||
|
||||
# Load the window state
|
||||
@ -104,7 +99,7 @@ class MainWindow(component.Component):
|
||||
self.is_minimized = False
|
||||
self.restart = False
|
||||
|
||||
self.window.drag_dest_set(gtk.DEST_DEFAULT_ALL, [('text/uri-list', 0, 80)], gtk.gdk.ACTION_COPY)
|
||||
self.window.drag_dest_set(gtk.DEST_DEFAULT_ALL, [('text/uri-list', 0, 80)], ACTION_COPY)
|
||||
|
||||
# Connect events
|
||||
self.window.connect('window-state-event', self.on_window_state_event)
|
||||
@ -252,14 +247,14 @@ class MainWindow(component.Component):
|
||||
self.config['window_height'] = event.height
|
||||
|
||||
def on_window_state_event(self, widget, event):
|
||||
if event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED:
|
||||
if event.changed_mask & WINDOW_STATE_MAXIMIZED:
|
||||
if event.new_window_state & WINDOW_STATE_MAXIMIZED:
|
||||
log.debug('pos: %s', self.window.get_position())
|
||||
self.config['window_maximized'] = True
|
||||
elif not event.new_window_state & gtk.gdk.WINDOW_STATE_WITHDRAWN:
|
||||
elif not event.new_window_state & WINDOW_STATE_WITHDRAWN:
|
||||
self.config['window_maximized'] = False
|
||||
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
if event.changed_mask & WINDOW_STATE_ICONIFIED:
|
||||
if event.new_window_state & WINDOW_STATE_ICONIFIED:
|
||||
log.debug('MainWindow is minimized..')
|
||||
component.pause('TorrentView')
|
||||
component.pause('StatusBar')
|
||||
@ -302,8 +297,8 @@ class MainWindow(component.Component):
|
||||
def update(self):
|
||||
# Update the window title
|
||||
def _on_get_session_status(status):
|
||||
download_rate = deluge.common.fspeed(status['payload_download_rate'], precision=0, shortform=True)
|
||||
upload_rate = deluge.common.fspeed(status['payload_upload_rate'], precision=0, shortform=True)
|
||||
download_rate = fspeed(status['payload_download_rate'], precision=0, shortform=True)
|
||||
upload_rate = fspeed(status['payload_upload_rate'], precision=0, shortform=True)
|
||||
self.window.set_title(_('D: %s U: %s - Deluge' % (download_rate, upload_rate)))
|
||||
if self.config['show_rate_in_title']:
|
||||
client.core.get_session_status(['payload_download_rate',
|
||||
|
@ -7,24 +7,25 @@
|
||||
# See LICENSE for more details.
|
||||
#
|
||||
|
||||
import gtk
|
||||
from gtk import ACCEL_VISIBLE, SeparatorMenuItem, accel_groups_from_object
|
||||
from gtk.gdk import CONTROL_MASK, META_MASK, SHIFT_MASK
|
||||
|
||||
from deluge.configmanager import ConfigManager
|
||||
|
||||
|
||||
def accel_swap(item, group, skey, smod, dkey, dmod):
|
||||
item.remove_accelerator(group, ord(skey), smod)
|
||||
item.add_accelerator('activate', group, ord(dkey), dmod, gtk.ACCEL_VISIBLE)
|
||||
item.add_accelerator('activate', group, ord(dkey), dmod, ACCEL_VISIBLE)
|
||||
|
||||
|
||||
def accel_meta(item, group, key):
|
||||
accel_swap(item, group, key, gtk.gdk.CONTROL_MASK, key, gtk.gdk.META_MASK)
|
||||
accel_swap(item, group, key, CONTROL_MASK, key, META_MASK)
|
||||
|
||||
|
||||
def menubar_osx(gtkui, osxapp):
|
||||
main_builder = gtkui.mainwindow.get_builder()
|
||||
menubar = main_builder.get_object('menubar')
|
||||
group = gtk.accel_groups_from_object(gtkui.mainwindow.get_window())[0]
|
||||
group = accel_groups_from_object(gtkui.mainwindow.get_window())[0]
|
||||
|
||||
config = ConfigManager('gtkui.conf')
|
||||
|
||||
@ -37,8 +38,7 @@ def menubar_osx(gtkui, osxapp):
|
||||
accel_meta(file_items[0], group, 'o')
|
||||
accel_meta(file_items[1], group, 'n')
|
||||
quit_all_item = file_items[3]
|
||||
accel_swap(quit_all_item, group, 'q', gtk.gdk.SHIFT_MASK | gtk.gdk.CONTROL_MASK,
|
||||
'q', gtk.gdk.SHIFT_MASK | gtk.gdk.META_MASK)
|
||||
accel_swap(quit_all_item, group, 'q', SHIFT_MASK | CONTROL_MASK, 'q', SHIFT_MASK | META_MASK)
|
||||
for item in range(2, len(file_items)): # remove quits
|
||||
file_menu.remove(file_items[item])
|
||||
|
||||
@ -46,7 +46,7 @@ def menubar_osx(gtkui, osxapp):
|
||||
edit_menu = menu_widget.get_submenu()
|
||||
edit_items = edit_menu.get_children()
|
||||
pref_item = edit_items[0]
|
||||
accel_swap(pref_item, group, 'p', gtk.gdk.CONTROL_MASK, ',', gtk.gdk.META_MASK)
|
||||
accel_swap(pref_item, group, 'p', CONTROL_MASK, ',', META_MASK)
|
||||
edit_menu.remove(pref_item)
|
||||
|
||||
conn_item = edit_items[1]
|
||||
@ -65,10 +65,10 @@ def menubar_osx(gtkui, osxapp):
|
||||
osxapp.set_menu_bar(menubar)
|
||||
# populate app menu
|
||||
osxapp.insert_app_menu_item(about_item, 0)
|
||||
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 1)
|
||||
osxapp.insert_app_menu_item(SeparatorMenuItem(), 1)
|
||||
osxapp.insert_app_menu_item(pref_item, 2)
|
||||
if not config['standalone']:
|
||||
osxapp.insert_app_menu_item(conn_item, 3)
|
||||
if quit_all_item.get_visible():
|
||||
osxapp.insert_app_menu_item(gtk.SeparatorMenuItem(), 4)
|
||||
osxapp.insert_app_menu_item(SeparatorMenuItem(), 4)
|
||||
osxapp.insert_app_menu_item(quit_all_item, 5)
|
||||
|
@ -7,7 +7,7 @@
|
||||
# See LICENSE for more details.
|
||||
#
|
||||
|
||||
import gtk.gdk
|
||||
from gtk.gdk import keyval_name
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.ui.client import client
|
||||
@ -220,7 +220,7 @@ class OptionsTab(Tab):
|
||||
self.button_apply.set_sensitive(True)
|
||||
|
||||
def _on_key_press_event(self, widget, event):
|
||||
keyname = gtk.gdk.keyval_name(event.keyval).lstrip('KP_').lower()
|
||||
keyname = keyval_name(event.keyval).lstrip('KP_').lower()
|
||||
if keyname.isdigit() or keyname in ['period', 'minus', 'delete', 'backspace']:
|
||||
if not self.button_apply.is_sensitive():
|
||||
self.button_apply.set_sensitive(True)
|
||||
|
@ -14,7 +14,7 @@ import os
|
||||
|
||||
import gtk
|
||||
from gobject import SIGNAL_RUN_FIRST, TYPE_NONE, GObject, type_register
|
||||
from gtk import gdk, keysyms
|
||||
from gtk import gdk, keysyms # pylint: disable=ungrouped-imports
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import resource_filename
|
||||
@ -215,8 +215,8 @@ class ValueList(object):
|
||||
if event.button != 3:
|
||||
# Double clicked a row, set this as the entry value
|
||||
# and close the popup
|
||||
if (double_click and event.type == gtk.gdk._2BUTTON_PRESS) or\
|
||||
(not double_click and event.type == gtk.gdk.BUTTON_PRESS):
|
||||
if (double_click and event.type == gdk._2BUTTON_PRESS) or\
|
||||
(not double_click and event.type == gdk.BUTTON_PRESS):
|
||||
path = self.get_selection_path()
|
||||
if path:
|
||||
self.set_entry_value(path, popdown=True)
|
||||
@ -413,7 +413,7 @@ class StoredValuesList(ValueList):
|
||||
|
||||
"""
|
||||
keyval = event.keyval
|
||||
ctrl = event.get_state() & gtk.gdk.CONTROL_MASK
|
||||
ctrl = event.get_state() & gdk.CONTROL_MASK
|
||||
|
||||
# Edit selected row
|
||||
if (keyval in [keysyms.Left, keysyms.Right, keysyms.space]):
|
||||
@ -422,7 +422,7 @@ class StoredValuesList(ValueList):
|
||||
self.on_edit_path(path, self.tree_column)
|
||||
elif key_is_up_or_down(keyval):
|
||||
# Swap the row value
|
||||
if event.get_state() & gtk.gdk.CONTROL_MASK:
|
||||
if event.get_state() & gdk.CONTROL_MASK:
|
||||
self.handle_list_scroll(_next=key_is_down(keyval),
|
||||
swap=True)
|
||||
else:
|
||||
@ -483,7 +483,7 @@ class CompletionList(ValueList):
|
||||
if ret:
|
||||
return ret
|
||||
keyval = event.keyval
|
||||
ctrl = event.get_state() & gtk.gdk.CONTROL_MASK
|
||||
ctrl = event.get_state() & gdk.CONTROL_MASK
|
||||
if key_is_up_or_down(keyval):
|
||||
self.handle_list_scroll(_next=key_is_down(keyval))
|
||||
return True
|
||||
@ -774,8 +774,8 @@ class StoredValuesPopup(StoredValuesList, PathChooserPopup):
|
||||
Handles scroll events from text entry, toggle button and treeview
|
||||
|
||||
"""
|
||||
swap = event.get_state() & gtk.gdk.CONTROL_MASK
|
||||
scroll_window = event.get_state() & gtk.gdk.SHIFT_MASK
|
||||
swap = event.get_state() & gdk.CONTROL_MASK
|
||||
scroll_window = event.get_state() & gdk.SHIFT_MASK
|
||||
self.handle_list_scroll(_next=event.direction == gdk.SCROLL_DOWN,
|
||||
set_entry=widget != self.treeview, swap=swap, scroll_window=scroll_window)
|
||||
return True
|
||||
@ -1294,7 +1294,7 @@ class PathChooserComboBox(gtk.HBox, StoredValuesPopup, GObject):
|
||||
"""
|
||||
keyval = event.keyval
|
||||
state = event.get_state() & gtk.accelerator_get_default_mod_mask()
|
||||
ctrl = event.get_state() & gtk.gdk.CONTROL_MASK
|
||||
ctrl = event.get_state() & gdk.CONTROL_MASK
|
||||
|
||||
# Select new row with arrow up/down is pressed
|
||||
if key_is_up_or_down(keyval):
|
||||
@ -1458,7 +1458,7 @@ class PathChooserComboBox(gtk.HBox, StoredValuesPopup, GObject):
|
||||
return True
|
||||
else:
|
||||
keyval = event.keyval
|
||||
ctrl = event.get_state() & gtk.gdk.CONTROL_MASK
|
||||
ctrl = event.get_state() & gdk.CONTROL_MASK
|
||||
if ctrl:
|
||||
# Set show/hide hidden files
|
||||
if is_ascii_value(keyval, 'h'):
|
||||
|
@ -11,25 +11,21 @@ import logging
|
||||
import os.path
|
||||
from future_builtins import zip
|
||||
|
||||
import gtk
|
||||
from gtk import (TREE_VIEW_COLUMN_FIXED, Builder, CellRendererPixbuf, CellRendererProgress, CellRendererText, ListStore,
|
||||
TreeViewColumn)
|
||||
from gtk.gdk import Pixbuf, pixbuf_new_from_file
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.countries import COUNTRIES
|
||||
from deluge.ui.gtkui.common import load_pickled_state_file, save_pickled_state_file
|
||||
from deluge.ui.gtkui.common import icon_downloading, icon_seeding, load_pickled_state_file, save_pickled_state_file
|
||||
from deluge.ui.gtkui.torrentdetails import Tab
|
||||
from deluge.ui.gtkui.torrentview_data_funcs import cell_data_speed_down, cell_data_speed_up
|
||||
from deluge.ui.gtkui.torrentview_data_funcs import cell_data_peer_progress, cell_data_speed_down, cell_data_speed_up
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def cell_data_progress(column, cell, model, row, data):
|
||||
value = model.get_value(row, data) * 100
|
||||
cell.set_property('value', value)
|
||||
cell.set_property('text', '%i%%' % value)
|
||||
|
||||
|
||||
class PeersTab(Tab):
|
||||
def __init__(self):
|
||||
Tab.__init__(self)
|
||||
@ -48,18 +44,18 @@ class PeersTab(Tab):
|
||||
self.listview.connect('button-press-event', self._on_button_press_event)
|
||||
self.listview.connect('query-tooltip', self._on_query_tooltip)
|
||||
# country pixbuf, ip, client, downspeed, upspeed, country code, int_ip, seed/peer icon, progress
|
||||
self.liststore = gtk.ListStore(gtk.gdk.Pixbuf, str, str, int, int, str, float, gtk.gdk.Pixbuf, float)
|
||||
self.liststore = ListStore(Pixbuf, str, str, int, int, str, float, Pixbuf, float)
|
||||
self.cached_flag_pixbufs = {}
|
||||
|
||||
self.seed_pixbuf = gtk.gdk.pixbuf_new_from_file(deluge.common.get_pixmap('seeding16.png'))
|
||||
self.peer_pixbuf = gtk.gdk.pixbuf_new_from_file(deluge.common.get_pixmap('downloading16.png'))
|
||||
self.seed_pixbuf = icon_seeding
|
||||
self.peer_pixbuf = icon_downloading
|
||||
|
||||
# key is ip address, item is row iter
|
||||
self.peers = {}
|
||||
|
||||
# Country column
|
||||
column = gtk.TreeViewColumn()
|
||||
render = gtk.CellRendererPixbuf()
|
||||
column = TreeViewColumn()
|
||||
render = CellRendererPixbuf()
|
||||
column.pack_start(render, False)
|
||||
column.add_attribute(render, 'pixbuf', 0)
|
||||
column.set_sort_column_id(5)
|
||||
@ -71,11 +67,11 @@ class PeersTab(Tab):
|
||||
self.listview.append_column(column)
|
||||
|
||||
# Address column
|
||||
column = gtk.TreeViewColumn(_('Address'))
|
||||
render = gtk.CellRendererPixbuf()
|
||||
column = TreeViewColumn(_('Address'))
|
||||
render = CellRendererPixbuf()
|
||||
column.pack_start(render, False)
|
||||
column.add_attribute(render, 'pixbuf', 7)
|
||||
render = gtk.CellRendererText()
|
||||
render = CellRendererText()
|
||||
column.pack_start(render, False)
|
||||
column.add_attribute(render, 'text', 1)
|
||||
column.set_sort_column_id(6)
|
||||
@ -87,8 +83,8 @@ class PeersTab(Tab):
|
||||
self.listview.append_column(column)
|
||||
|
||||
# Client column
|
||||
column = gtk.TreeViewColumn(_('Client'))
|
||||
render = gtk.CellRendererText()
|
||||
column = TreeViewColumn(_('Client'))
|
||||
render = CellRendererText()
|
||||
column.pack_start(render, False)
|
||||
column.add_attribute(render, 'text', 2)
|
||||
column.set_sort_column_id(2)
|
||||
@ -100,10 +96,10 @@ class PeersTab(Tab):
|
||||
self.listview.append_column(column)
|
||||
|
||||
# Progress column
|
||||
column = gtk.TreeViewColumn(_('Progress'))
|
||||
render = gtk.CellRendererProgress()
|
||||
column = TreeViewColumn(_('Progress'))
|
||||
render = CellRendererProgress()
|
||||
column.pack_start(render, True)
|
||||
column.set_cell_data_func(render, cell_data_progress, 8)
|
||||
column.set_cell_data_func(render, cell_data_peer_progress, 8)
|
||||
column.set_sort_column_id(8)
|
||||
column.set_clickable(True)
|
||||
column.set_resizable(True)
|
||||
@ -113,8 +109,8 @@ class PeersTab(Tab):
|
||||
self.listview.append_column(column)
|
||||
|
||||
# Down Speed column
|
||||
column = gtk.TreeViewColumn(_('Down Speed'))
|
||||
render = gtk.CellRendererText()
|
||||
column = TreeViewColumn(_('Down Speed'))
|
||||
render = CellRendererText()
|
||||
column.pack_start(render, False)
|
||||
column.set_cell_data_func(render, cell_data_speed_down, 3)
|
||||
column.set_sort_column_id(3)
|
||||
@ -126,8 +122,8 @@ class PeersTab(Tab):
|
||||
self.listview.append_column(column)
|
||||
|
||||
# Up Speed column
|
||||
column = gtk.TreeViewColumn(_('Up Speed'))
|
||||
render = gtk.CellRendererText()
|
||||
column = TreeViewColumn(_('Up Speed'))
|
||||
render = CellRendererText()
|
||||
column.pack_start(render, False)
|
||||
column.set_cell_data_func(render, cell_data_speed_up, 4)
|
||||
column.set_sort_column_id(4)
|
||||
@ -181,7 +177,7 @@ class PeersTab(Tab):
|
||||
cname = column.get_title()
|
||||
if cname in state['columns']:
|
||||
cstate = state['columns'][cname]
|
||||
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
|
||||
column.set_sizing(TREE_VIEW_COLUMN_FIXED)
|
||||
column.set_fixed_width(cstate['width'] if cstate['width'] > 0 else 10)
|
||||
if state['sort_id'] == index and state['sort_order'] is not None:
|
||||
column.set_sort_indicator(True)
|
||||
@ -220,7 +216,7 @@ class PeersTab(Tab):
|
||||
if country not in self.cached_flag_pixbufs:
|
||||
# We haven't created a pixbuf for this country yet
|
||||
try:
|
||||
self.cached_flag_pixbufs[country] = gtk.gdk.pixbuf_new_from_file(
|
||||
self.cached_flag_pixbufs[country] = pixbuf_new_from_file(
|
||||
deluge.common.resource_filename(
|
||||
'deluge',
|
||||
os.path.join('ui', 'data', 'pixmaps', 'flags', country.lower() + '.png')))
|
||||
@ -330,7 +326,7 @@ class PeersTab(Tab):
|
||||
def _on_menuitem_add_peer_activate(self, menuitem):
|
||||
"""This is a callback for manually adding a peer"""
|
||||
log.debug('on_menuitem_add_peer')
|
||||
builder = gtk.Builder()
|
||||
builder = Builder()
|
||||
builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'connect_peer_dialog.ui')
|
||||
))
|
||||
|
@ -11,27 +11,28 @@ from __future__ import division
|
||||
|
||||
from math import pi
|
||||
|
||||
import gtk
|
||||
import pango
|
||||
import pangocairo
|
||||
from cairo import FORMAT_ARGB32, Context, ImageSurface
|
||||
from gtk import DrawingArea, ProgressBar
|
||||
from gtk.gdk import colormap_get_system
|
||||
from pango import SCALE, WEIGHT_BOLD
|
||||
from pangocairo import CairoContext
|
||||
|
||||
from deluge.configmanager import ConfigManager
|
||||
|
||||
COLOR_STATES = ['missing', 'waiting', 'downloading', 'completed']
|
||||
|
||||
|
||||
class PiecesBar(gtk.DrawingArea):
|
||||
class PiecesBar(DrawingArea):
|
||||
# Draw in response to an expose-event
|
||||
__gsignals__ = {'expose-event': 'override'}
|
||||
|
||||
def __init__(self):
|
||||
gtk.DrawingArea.__init__(self)
|
||||
DrawingArea.__init__(self)
|
||||
# Get progress bar styles, in order to keep font consistency
|
||||
pb = gtk.ProgressBar()
|
||||
pb = ProgressBar()
|
||||
pb_style = pb.get_style()
|
||||
self.text_font = pb_style.font_desc
|
||||
self.text_font.set_weight(pango.WEIGHT_BOLD)
|
||||
self.text_font.set_weight(WEIGHT_BOLD)
|
||||
# Done with the ProgressBar styles, don't keep refs of it
|
||||
del pb, pb_style
|
||||
|
||||
@ -48,7 +49,7 @@ class PiecesBar(gtk.DrawingArea):
|
||||
self.cr = None
|
||||
|
||||
self.connect('size-allocate', self.do_size_allocate_event)
|
||||
self.set_colormap(gtk.gdk.colormap_get_system())
|
||||
self.set_colormap(colormap_get_system())
|
||||
self.show()
|
||||
|
||||
def do_size_allocate_event(self, widget, size):
|
||||
@ -151,14 +152,14 @@ class PiecesBar(gtk.DrawingArea):
|
||||
# Need to recreate the cache drawing
|
||||
self.text_overlay = ImageSurface(FORMAT_ARGB32, self.width, self.height)
|
||||
ctx = Context(self.text_overlay)
|
||||
pg = pangocairo.CairoContext(ctx)
|
||||
pg = CairoContext(ctx)
|
||||
pl = pg.create_layout()
|
||||
pl.set_font_description(self.text_font)
|
||||
pl.set_width(-1) # No text wrapping
|
||||
pl.set_text(self.text)
|
||||
plsize = pl.get_size()
|
||||
text_width = plsize[0] // pango.SCALE
|
||||
text_height = plsize[1] // pango.SCALE
|
||||
text_width = plsize[0] // SCALE
|
||||
text_height = plsize[1] // SCALE
|
||||
area_width_without_text = self.width - text_width
|
||||
area_height_without_text = self.height - text_height
|
||||
ctx.move_to(area_width_without_text // 2, area_height_without_text // 2)
|
||||
|
@ -13,6 +13,7 @@ import os
|
||||
from hashlib import sha1 as sha
|
||||
|
||||
import gtk
|
||||
from gtk.gdk import Color
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
@ -1163,7 +1164,7 @@ class Preferences(component.Component):
|
||||
|
||||
def __set_color(self, state, from_config=False):
|
||||
if from_config:
|
||||
color = gtk.gdk.Color(*self.gtkui_config['pieces_color_%s' % state])
|
||||
color = Color(*self.gtkui_config['pieces_color_%s' % state])
|
||||
log.debug('Setting %r color state from config to %s', state, (color.red, color.green, color.blue))
|
||||
self.builder.get_object('%s_color' % state).set_color(color)
|
||||
else:
|
||||
@ -1178,6 +1179,6 @@ class Preferences(component.Component):
|
||||
|
||||
def __revert_color(self, state, from_config=False):
|
||||
log.debug('Reverting %r color state', state)
|
||||
self.builder.get_object('%s_color' % state).set_color(gtk.gdk.Color(*self.COLOR_DEFAULTS[state]))
|
||||
self.builder.get_object('%s_color' % state).set_color(Color(*self.COLOR_DEFAULTS[state]))
|
||||
self.builder.get_object('revert_color_%s' % state).set_sensitive(False)
|
||||
self.gtkui_config.apply_set_functions('pieces_colors')
|
||||
|
@ -10,8 +10,8 @@
|
||||
import logging
|
||||
import os.path
|
||||
|
||||
import gtk
|
||||
from gobject import timeout_add
|
||||
from gtk import STOCK_SORT_DESCENDING, Builder, CellRendererText, ListStore, TreeViewColumn
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
@ -29,7 +29,7 @@ class QueuedTorrents(component.Component):
|
||||
self.status_item = None
|
||||
|
||||
self.config = ConfigManager('gtkui.conf')
|
||||
self.builder = gtk.Builder()
|
||||
self.builder = Builder()
|
||||
self.builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'queuedtorrents.ui')))
|
||||
self.builder.get_object('chk_autoadd').set_active(self.config['autoadd_queued'])
|
||||
@ -45,10 +45,9 @@ class QueuedTorrents(component.Component):
|
||||
})
|
||||
|
||||
self.treeview = self.builder.get_object('treeview')
|
||||
self.treeview.append_column(
|
||||
gtk.TreeViewColumn(_('Torrent'), gtk.CellRendererText(), text=0))
|
||||
self.treeview.append_column(TreeViewColumn(_('Torrent'), CellRendererText(), text=0))
|
||||
|
||||
self.liststore = gtk.ListStore(str, str)
|
||||
self.liststore = ListStore(str, str)
|
||||
self.treeview.set_model(self.liststore)
|
||||
self.treeview.set_tooltip_column(1)
|
||||
|
||||
@ -120,7 +119,7 @@ class QueuedTorrents(component.Component):
|
||||
# have already been added.
|
||||
if self.status_item is None:
|
||||
self.status_item = component.get('StatusBar').add_item(
|
||||
stock=gtk.STOCK_SORT_DESCENDING,
|
||||
stock=STOCK_SORT_DESCENDING,
|
||||
text=label,
|
||||
callback=self.on_statusbar_click)
|
||||
else:
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
import gtk
|
||||
from gtk import POLICY_AUTOMATIC, Label, ScrolledWindow
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.configmanager import ConfigManager
|
||||
@ -58,10 +58,10 @@ class SideBar(component.Component):
|
||||
"""Adds a tab object to the notebook."""
|
||||
log.debug('add tab: %s', tab_name)
|
||||
self.tabs[tab_name] = widget
|
||||
scrolled = gtk.ScrolledWindow()
|
||||
scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
scrolled = ScrolledWindow()
|
||||
scrolled.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
||||
scrolled.add(widget)
|
||||
self.notebook.insert_page(scrolled, gtk.Label(label), -1)
|
||||
self.notebook.insert_page(scrolled, Label(label), -1)
|
||||
scrolled.show_all()
|
||||
|
||||
self.after_update()
|
||||
|
@ -10,11 +10,11 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
import gtk
|
||||
from gtk import (Builder, RadioMenuItem, status_icon_new_from_icon_name, status_icon_new_from_pixbuf,
|
||||
status_icon_position_menu)
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
from deluge.common import fspeed
|
||||
from deluge.common import fspeed, get_pixmap, osx_check, resource_filename, windows_check
|
||||
from deluge.configmanager import ConfigManager
|
||||
from deluge.ui.client import client
|
||||
from deluge.ui.gtkui import dialogs
|
||||
@ -63,9 +63,9 @@ class SystemTray(component.Component):
|
||||
|
||||
def enable(self):
|
||||
"""Enables the system tray icon."""
|
||||
self.builder = gtk.Builder()
|
||||
self.builder.add_from_file(deluge.common.resource_filename(
|
||||
'deluge.ui.gtkui', os.path.join('glade', 'tray_menu.ui')))
|
||||
self.builder = Builder()
|
||||
self.builder.add_from_file(resource_filename('deluge.ui.gtkui', os.path.join(
|
||||
'glade', 'tray_menu.ui')))
|
||||
|
||||
self.builder.connect_signals({
|
||||
'on_menuitem_show_deluge_activate': self.on_menuitem_show_deluge_activate,
|
||||
@ -103,18 +103,16 @@ class SystemTray(component.Component):
|
||||
|
||||
else:
|
||||
log.debug('Enabling the system tray icon..')
|
||||
if deluge.common.windows_check() or deluge.common.osx_check():
|
||||
self.tray = gtk.status_icon_new_from_pixbuf(get_logo(32))
|
||||
if windows_check():
|
||||
self.tray = status_icon_new_from_pixbuf(get_logo(32))
|
||||
else:
|
||||
self.tray = gtk.status_icon_new_from_icon_name('deluge')
|
||||
self.tray = status_icon_new_from_icon_name('deluge')
|
||||
|
||||
self.tray.connect('activate', self.on_tray_clicked)
|
||||
self.tray.connect('popup-menu', self.on_tray_popup)
|
||||
|
||||
self.builder.get_object('download-limit-image').set_from_file(
|
||||
deluge.common.get_pixmap('downloading16.png'))
|
||||
self.builder.get_object('upload-limit-image').set_from_file(
|
||||
deluge.common.get_pixmap('seeding16.png'))
|
||||
self.builder.get_object('download-limit-image').set_from_file(get_pixmap('downloading16.png'))
|
||||
self.builder.get_object('upload-limit-image').set_from_file(get_pixmap('seeding16.png'))
|
||||
|
||||
client.register_event_handler('ConfigValueChangedEvent', self.config_value_changed)
|
||||
if client.connected():
|
||||
@ -319,8 +317,8 @@ class SystemTray(component.Component):
|
||||
else:
|
||||
self.builder.get_object('menuitem_show_deluge').set_active(False)
|
||||
|
||||
popup_function = gtk.status_icon_position_menu
|
||||
if deluge.common.windows_check() or deluge.common.osx_check():
|
||||
popup_function = status_icon_position_menu
|
||||
if windows_check() or osx_check():
|
||||
popup_function = None
|
||||
button = 0
|
||||
self.tray_menu.popup(None, None, popup_function, button, activate_time, status_icon)
|
||||
@ -353,7 +351,7 @@ class SystemTray(component.Component):
|
||||
self.mainwindow.quit(shutdown=True)
|
||||
|
||||
def on_tray_setbwdown(self, widget, data=None):
|
||||
if isinstance(widget, gtk.RadioMenuItem):
|
||||
if isinstance(widget, RadioMenuItem):
|
||||
# ignore previous radiomenuitem value
|
||||
if not widget.get_active():
|
||||
return
|
||||
@ -362,7 +360,7 @@ class SystemTray(component.Component):
|
||||
'downloading.svg')
|
||||
|
||||
def on_tray_setbwup(self, widget, data=None):
|
||||
if isinstance(widget, gtk.RadioMenuItem):
|
||||
if isinstance(widget, RadioMenuItem):
|
||||
# ignore previous radiomenuitem value
|
||||
if not widget.get_active():
|
||||
return
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
import gtk
|
||||
from gtk import SeparatorToolItem, ToolButton
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.configmanager import ConfigManager
|
||||
@ -71,7 +71,7 @@ class ToolBar(component.Component):
|
||||
|
||||
def add_toolbutton(self, callback, label=None, image=None, stock=None, tooltip=None):
|
||||
"""Adds a toolbutton to the toolbar"""
|
||||
toolbutton = gtk.ToolButton()
|
||||
toolbutton = ToolButton()
|
||||
if stock is not None:
|
||||
toolbutton.set_stock_id(stock)
|
||||
if label is not None:
|
||||
@ -89,7 +89,7 @@ class ToolBar(component.Component):
|
||||
|
||||
def add_separator(self, position=None):
|
||||
"""Adds a separator toolitem"""
|
||||
sep = gtk.SeparatorToolItem()
|
||||
sep = SeparatorToolItem()
|
||||
if position is not None:
|
||||
self.toolbar.insert(sep, position)
|
||||
else:
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
import gtk
|
||||
from gtk import CheckMenuItem, Menu, SeparatorMenuItem
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.ui.client import client
|
||||
@ -266,9 +266,9 @@ class TorrentDetails(component.Component):
|
||||
|
||||
def generate_menu(self):
|
||||
"""Generates the checklist menu for all the tabs and attaches it"""
|
||||
menu = gtk.Menu()
|
||||
menu = Menu()
|
||||
# Create 'All' menuitem and a separator
|
||||
menuitem = gtk.CheckMenuItem(self.translate_tabs['All'], True)
|
||||
menuitem = CheckMenuItem(self.translate_tabs['All'], True)
|
||||
menuitem.set_name('All')
|
||||
|
||||
all_tabs = True
|
||||
@ -281,7 +281,7 @@ class TorrentDetails(component.Component):
|
||||
|
||||
menu.append(menuitem)
|
||||
|
||||
menuitem = gtk.SeparatorMenuItem()
|
||||
menuitem = SeparatorMenuItem()
|
||||
menu.append(menuitem)
|
||||
|
||||
# Create a list in order of tabs to create menu
|
||||
@ -291,7 +291,7 @@ class TorrentDetails(component.Component):
|
||||
menuitem_list.sort()
|
||||
|
||||
for pos, name in menuitem_list:
|
||||
menuitem = gtk.CheckMenuItem(self.translate_tabs[name], True)
|
||||
menuitem = CheckMenuItem(self.translate_tabs[name], True)
|
||||
menuitem.set_name(name)
|
||||
menuitem.set_active(self.tabs[name].is_visible)
|
||||
menuitem.connect('toggled', self._on_menuitem_toggled)
|
||||
|
@ -12,8 +12,9 @@
|
||||
import logging
|
||||
from locale import strcoll
|
||||
|
||||
import gtk
|
||||
from gobject import TYPE_UINT64, idle_add
|
||||
from gtk import ENTRY_ICON_SECONDARY
|
||||
from gtk.gdk import SHIFT_MASK, keyval_name
|
||||
from twisted.internet import reactor
|
||||
|
||||
import deluge.component as component
|
||||
@ -210,7 +211,7 @@ class SearchBox(object):
|
||||
self.search_pending = reactor.callLater(0.7, self.torrentview.update)
|
||||
|
||||
def on_search_torrents_entry_icon_press(self, entry, icon, event):
|
||||
if icon != gtk.ENTRY_ICON_SECONDARY:
|
||||
if icon != ENTRY_ICON_SECONDARY:
|
||||
return
|
||||
self.clear_search()
|
||||
|
||||
@ -705,7 +706,7 @@ class TorrentView(ListView, component.Component):
|
||||
|
||||
# Handle keyboard shortcuts
|
||||
def on_key_press_event(self, widget, event):
|
||||
keyname = gtk.gdk.keyval_name(event.keyval)
|
||||
keyname = keyval_name(event.keyval)
|
||||
if keyname is not None:
|
||||
func = getattr(self, 'keypress_' + keyname.lower(), None)
|
||||
if func:
|
||||
@ -715,7 +716,7 @@ class TorrentView(ListView, component.Component):
|
||||
log.debug('keypress_delete')
|
||||
torrents = self.get_selected_torrents()
|
||||
if torrents:
|
||||
if event.state & gtk.gdk.SHIFT_MASK:
|
||||
if event.get_state() & SHIFT_MASK:
|
||||
RemoveTorrentDialog(torrents, delete_files=True).run()
|
||||
else:
|
||||
RemoveTorrentDialog(torrents).run()
|
||||
|
@ -12,20 +12,10 @@ from __future__ import print_function
|
||||
import warnings
|
||||
from functools import partial
|
||||
|
||||
import gtk
|
||||
from gobject import GError
|
||||
|
||||
import deluge.common as common
|
||||
import deluge.component as component
|
||||
|
||||
# Status icons.. Create them from file only once to avoid constantly
|
||||
# re-creating them.
|
||||
icon_downloading = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('downloading16.png'))
|
||||
icon_seeding = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('seeding16.png'))
|
||||
icon_inactive = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('inactive16.png'))
|
||||
icon_alert = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('alert16.png'))
|
||||
icon_queued = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('queued16.png'))
|
||||
icon_checking = gtk.gdk.pixbuf_new_from_file(common.get_pixmap('checking16.png'))
|
||||
from deluge.ui.gtkui.common import (create_blank_pixbuf, get_pixbuf_at_size, icon_alert, icon_checking,
|
||||
icon_downloading, icon_inactive, icon_queued, icon_seeding)
|
||||
|
||||
# Holds the info for which status icon to display based on TORRENT_STATE
|
||||
ICON_STATE = {
|
||||
@ -58,6 +48,7 @@ func_last_value = {
|
||||
'cell_data_statusicon': None,
|
||||
'cell_data_queue': None,
|
||||
'cell_data_progress': [None, None],
|
||||
'cell_data_peer_progress': None
|
||||
}
|
||||
|
||||
|
||||
@ -84,23 +75,12 @@ def cell_data_statusicon(column, cell, model, row, data):
|
||||
pass
|
||||
|
||||
|
||||
def create_blank_pixbuf():
|
||||
i = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 16, 16)
|
||||
i.fill(0x00000000)
|
||||
return i
|
||||
|
||||
|
||||
def set_icon(icon, cell):
|
||||
if icon:
|
||||
pixbuf = icon.get_cached_icon()
|
||||
def set_tracker_icon(tracker_icon, cell):
|
||||
if tracker_icon:
|
||||
pixbuf = tracker_icon.get_cached_icon()
|
||||
if pixbuf is None:
|
||||
try:
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(icon.get_filename(), 16, 16)
|
||||
except GError:
|
||||
# Failed to load the pixbuf (Bad image file), so set a blank pixbuf
|
||||
pixbuf = create_blank_pixbuf()
|
||||
finally:
|
||||
icon.set_cached_icon(pixbuf)
|
||||
pixbuf = get_pixbuf_at_size(tracker_icon.get_filename(), 16)
|
||||
tracker_icon.set_cached_icon(pixbuf)
|
||||
else:
|
||||
pixbuf = create_blank_pixbuf()
|
||||
|
||||
@ -118,15 +98,15 @@ def cell_data_trackericon(column, cell, model, row, data):
|
||||
if host:
|
||||
if not component.get('TrackerIcons').has(host):
|
||||
# Set blank icon while waiting for the icon to be loaded
|
||||
set_icon(None, cell)
|
||||
set_tracker_icon(None, cell)
|
||||
component.get('TrackerIcons').fetch(host)
|
||||
func_last_value['cell_data_trackericon'] = None
|
||||
else:
|
||||
set_icon(component.get('TrackerIcons').get(host), cell)
|
||||
set_tracker_icon(component.get('TrackerIcons').get(host), cell)
|
||||
# Only set the last value when we have found the icon
|
||||
func_last_value['cell_data_trackericon'] = host
|
||||
else:
|
||||
set_icon(None, cell)
|
||||
set_tracker_icon(None, cell)
|
||||
func_last_value['cell_data_trackericon'] = None
|
||||
|
||||
|
||||
@ -147,6 +127,14 @@ def cell_data_progress(column, cell, model, row, data):
|
||||
cell.set_property('text', textstr)
|
||||
|
||||
|
||||
def cell_data_peer_progress(column, cell, model, row, data):
|
||||
value = model.get_value(row, data) * 100
|
||||
if func_last_value['cell_data_peer_progress'] != value:
|
||||
func_last_value['cell_data_peer_progress'] = value
|
||||
cell.set_property('value', value)
|
||||
cell.set_property('text', '%i%%' % value)
|
||||
|
||||
|
||||
def cell_data_queue(column, cell, model, row, data):
|
||||
value = model.get_value(row, data)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user