[Notifications] Migrate to GTK3

- Switch from pynotify to gi libnotify binding.
  - Ideally would drop libnotify for [GNotification] but requires more
    work with the desktop file needing renamed to DNS format.
    e.g. `org.deluge-torrent.deluge`

[GNotification]: https://developer.gnome.org/GNotification/

Co-authored-by: Calum Lind calumlind+deluge@gmail.com
This commit is contained in:
kbdserver 2018-10-12 10:53:40 +01:00 committed by Calum Lind
parent ed1b2a50fa
commit d879ee06a3
2 changed files with 91 additions and 80 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.0 -->
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy toplevel-contextual -->
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="lower">1</property>
<property name="upper">65535</property>
@ -29,10 +29,13 @@
<object class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<child>
<object class="GtkFrame" id="frame2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_left">9</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
@ -40,6 +43,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<property name="right_padding">10</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
@ -82,6 +86,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_sound_enabled_toggled" swapped="no"/>
</object>
@ -120,6 +125,8 @@
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">5</property>
<property name="xpad">5</property>
<property name="label" translatable="yes">&lt;b&gt;UI Notifications&lt;/b&gt;</property>
<property name="use_markup">True</property>
@ -136,6 +143,9 @@
<object class="GtkFrame" id="frame3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_left">10</property>
<property name="margin_top">7</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
@ -143,6 +153,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<property name="right_padding">10</property>
<child>
<object class="GtkTable" id="prefs_table">
<property name="visible">True</property>
@ -151,15 +162,12 @@
<property name="n_columns">4</property>
<property name="column_spacing">2</property>
<property name="row_spacing">2</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Hostname:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="top_attach">1</property>
@ -172,8 +180,6 @@
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@ -204,8 +210,6 @@
<property name="width_chars">5</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
<property name="adjustment">adjustment1</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
@ -221,8 +225,8 @@
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Username:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="top_attach">2</property>
@ -235,8 +239,6 @@
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@ -249,6 +251,7 @@
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Password:</property>
</object>
<packing>
@ -263,8 +266,6 @@
<property name="visibility">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@ -277,13 +278,14 @@
<object class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="label_xalign">0</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkAlignment" id="alignment4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<property name="bottom_padding">10</property>
<child>
<object class="GtkHBox" id="hbox1">
<property name="visible">True</property>
@ -293,8 +295,6 @@
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="smtp_recipients">
@ -302,6 +302,9 @@
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="enable_grid_lines">horizontal</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
@ -365,7 +368,9 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Recipients&lt;/b&gt;</property>
<property name="margin_bottom">3</property>
<property name="use_markup">True</property>
<property name="ypad">0</property>
</object>
</child>
</object>
@ -380,6 +385,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">start</property>
<property name="draw_indicator">True</property>
<child>
<object class="GtkLabel" id="label9">
@ -394,15 +400,14 @@
<property name="right_attach">4</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_padding">10</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">From:</property>
<property name="justify">right</property>
</object>
<packing>
<property name="top_attach">4</property>
@ -415,8 +420,6 @@
<property name="can_focus">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
@ -446,6 +449,7 @@
<object class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="xpad">5</property>
<property name="label" translatable="yes">&lt;b&gt;Email Notifications&lt;/b&gt;</property>
<property name="use_markup">True</property>
@ -474,6 +478,9 @@
<object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">15</property>
<property name="margin_right">10</property>
<property name="margin_bottom">10</property>
<child>
<placeholder/>
</child>
@ -481,13 +488,14 @@
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTreeView" id="subscriptions_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="enable_grid_lines">horizontal</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
@ -532,16 +540,20 @@
<object class="GtkVBox" id="sounds_page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">15</property>
<property name="margin_right">10</property>
<property name="margin_bottom">10</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkTreeView" id="sounds_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
@ -624,5 +636,8 @@
</child>
</object>
</child>
<child type="titlebar">
<placeholder/>
</child>
</object>
</interface>

View File

@ -17,7 +17,8 @@ from __future__ import unicode_literals
import logging
from os.path import basename
import gtk
from gi import require_version
from gi.repository import Gtk
from twisted.internet import defer
import deluge.common
@ -40,13 +41,12 @@ except ImportError:
SOUND_AVAILABLE = False
try:
import pynotify
POPUP_AVAILABLE = True
if deluge.common.windows_check():
POPUP_AVAILABLE = False
except ImportError:
require_version('Notify', '0.7')
from gi.repository import Notify
except (ValueError, ImportError):
POPUP_AVAILABLE = False
else:
POPUP_AVAILABLE = not deluge.common.windows_check()
DEFAULT_PREFS = {
@ -174,17 +174,13 @@ class GtkUiNotifications(CustomNotifications):
if not self.config['popup_enabled']:
return defer.succeed(_('Popup notification is not enabled.'))
if not POPUP_AVAILABLE:
return defer.fail(_('pynotify is not installed'))
return defer.fail(_('libnotify is not installed'))
if pynotify.init('Deluge'):
icon = gtk.gdk.pixbuf_new_from_file_at_size(
deluge.common.get_pixmap('deluge.svg'), 48, 48
)
self.note = pynotify.Notification(title, message)
self.note.set_icon_from_pixbuf(icon)
if Notify.init('Deluge'):
self.note = Notify.Notification.new(title, message, 'deluge-tray')
self.note.set_hint('desktop-entry', 'deluge')
if not self.note.show():
err_msg = _('pynotify failed to show notification')
err_msg = _('Failed to popup notification')
log.warning(err_msg)
return defer.fail(err_msg)
return defer.succeed(_('Notification popup shown'))
@ -254,7 +250,7 @@ class GtkUI(Gtk3PluginBase, GtkUiNotifications):
self.config = deluge.configmanager.ConfigManager(
'notifications-gtk.conf', DEFAULT_PREFS
)
self.builder = gtk.Builder()
self.builder = Gtk.Builder()
self.builder.add_from_file(get_resource('config.ui'))
self.builder.get_object('smtp_port').set_value(25)
self.prefs = self.builder.get_object('prefs_box')
@ -331,12 +327,12 @@ class GtkUI(Gtk3PluginBase, GtkUiNotifications):
treeview_selection.connect(
'changed', self.on_recipients_treeview_selection_changed
)
self.recipients_model = gtk.ListStore(str, bool)
self.recipients_model = Gtk.ListStore(str, bool)
renderer = gtk.CellRendererText()
renderer = Gtk.CellRendererText()
renderer.connect('edited', self.on_cell_edited, self.recipients_model)
renderer.set_data('recipient', RECIPIENT_FIELD)
column = gtk.TreeViewColumn(
renderer.recipient = RECIPIENT_FIELD
column = Gtk.TreeViewColumn(
'Recipients', renderer, text=RECIPIENT_FIELD, editable=RECIPIENT_EDIT
)
column.set_expand(True)
@ -350,28 +346,28 @@ class GtkUI(Gtk3PluginBase, GtkUiNotifications):
sounds_selection.connect('changed', self.on_sounds_treeview_selection_changed)
self.sounds_treeview.set_tooltip_column(SND_EVENT_DOC)
self.sounds_model = gtk.ListStore(str, str, str, str)
self.sounds_model = Gtk.ListStore(str, str, str, str)
renderer = gtk.CellRendererText()
renderer.set_data('event', SND_EVENT)
column = gtk.TreeViewColumn('Event', renderer, text=SND_EVENT)
renderer = Gtk.CellRendererText()
renderer.event = SND_EVENT
column = Gtk.TreeViewColumn('Event', renderer, text=SND_EVENT)
column.set_expand(True)
self.sounds_treeview.append_column(column)
renderer = gtk.CellRendererText()
renderer.set_data('event_doc', SND_EVENT_DOC)
column = gtk.TreeViewColumn('Doc', renderer, text=SND_EVENT_DOC)
renderer = Gtk.CellRendererText()
renderer.event_doc = SND_EVENT_DOC
column = Gtk.TreeViewColumn('Doc', renderer, text=SND_EVENT_DOC)
column.set_property('visible', False)
self.sounds_treeview.append_column(column)
renderer = gtk.CellRendererText()
renderer.set_data('sound_name', SND_NAME)
column = gtk.TreeViewColumn('Name', renderer, text=SND_NAME)
renderer = Gtk.CellRendererText()
renderer.sound_name = SND_NAME
column = Gtk.TreeViewColumn('Name', renderer, text=SND_NAME)
self.sounds_treeview.append_column(column)
renderer = gtk.CellRendererText()
renderer.set_data('sound_path', SND_PATH)
column = gtk.TreeViewColumn('Path', renderer, text=SND_PATH)
renderer = Gtk.CellRendererText()
renderer.sound_path = SND_PATH
column = Gtk.TreeViewColumn('Path', renderer, text=SND_PATH)
column.set_property('visible', False)
self.sounds_treeview.append_column(column)
@ -385,45 +381,45 @@ class GtkUI(Gtk3PluginBase, GtkUiNotifications):
'changed', self.on_subscriptions_treeview_selection_changed
)
self.subscriptions_treeview.set_tooltip_column(SUB_EVENT_DOC)
self.subscriptions_model = gtk.ListStore(str, str, bool, bool, bool, bool)
self.subscriptions_model = Gtk.ListStore(str, str, bool, bool, bool, bool)
renderer = gtk.CellRendererText()
renderer.set_data('event', SUB_EVENT)
column = gtk.TreeViewColumn('Event', renderer, text=SUB_EVENT)
renderer = Gtk.CellRendererText()
setattr(renderer, 'event', SUB_EVENT)
column = Gtk.TreeViewColumn('Event', renderer, text=SUB_EVENT)
column.set_expand(True)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererText()
renderer.set_data('event_doc', SUB_EVENT)
column = gtk.TreeViewColumn('Doc', renderer, text=SUB_EVENT_DOC)
renderer = Gtk.CellRendererText()
setattr(renderer, 'event_doc', SUB_EVENT)
column = Gtk.TreeViewColumn('Doc', renderer, text=SUB_EVENT_DOC)
column.set_property('visible', False)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle()
renderer = Gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect('toggled', self._on_email_col_toggled)
column = gtk.TreeViewColumn('Email', renderer, active=SUB_NOT_EMAIL)
column = Gtk.TreeViewColumn('Email', renderer, active=SUB_NOT_EMAIL)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle()
renderer = Gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect('toggled', self._on_popup_col_toggled)
column = gtk.TreeViewColumn('Popup', renderer, active=SUB_NOT_POPUP)
column = Gtk.TreeViewColumn('Popup', renderer, active=SUB_NOT_POPUP)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle()
renderer = Gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect('toggled', self._on_blink_col_toggled)
column = gtk.TreeViewColumn('Blink', renderer, active=SUB_NOT_BLINK)
column = Gtk.TreeViewColumn('Blink', renderer, active=SUB_NOT_BLINK)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
renderer = gtk.CellRendererToggle()
renderer = Gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect('toggled', self._on_sound_col_toggled)
column = gtk.TreeViewColumn('Sound', renderer, active=SUB_NOT_SOUND)
column = Gtk.TreeViewColumn('Sound', renderer, active=SUB_NOT_SOUND)
column.set_clickable(True)
self.subscriptions_treeview.append_column(column)
self.subscriptions_treeview.set_model(self.subscriptions_model)
@ -661,19 +657,19 @@ class GtkUI(Gtk3PluginBase, GtkUiNotifications):
model, selected_iter = selection.get_selected()
if selected_iter:
path = model.get(selected_iter, SND_PATH)[0]
dialog = gtk.FileChooserDialog(
dialog = Gtk.FileChooserDialog(
title=_('Choose Sound File'),
buttons=(
gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN,
gtk.RESPONSE_OK,
Gtk.STOCK_CANCEL,
Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN,
Gtk.ResponseType.OK,
),
)
dialog.set_filename(path)
def update_model(response):
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
new_filename = dialog.get_filename()
dialog.destroy()
log.debug(new_filename)