Rework SubscriptionRequestWindow

This commit is contained in:
Daniel Brötzmann 2019-04-02 19:49:57 +02:00 committed by Philipp Hörist
parent 139156ba5e
commit e83a246703
5 changed files with 233 additions and 183 deletions

View File

@ -1,95 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.1 --> <!-- Generated with glade 3.22.1 -->
<interface> <interface>
<requires lib="gtk+" version="3.12"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkMenu" id="subscription_request_popup_menu"> <object class="GtkImage" id="image1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <property name="icon_name">user-available-symbolic</property>
<object class="GtkMenuItem" id="start_chat_menuitem"> </object>
<property name="visible">True</property> <object class="GtkImage" id="image2">
<property name="can_focus">False</property> <property name="visible">True</property>
<property name="label" translatable="yes">_Start Chat</property> <property name="can_focus">False</property>
<property name="use_underline">True</property> <property name="icon_name">user-info-symbolic</property>
<signal name="activate" handler="on_start_chat_activate" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="information_menuitem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">_Information</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_contact_info_activate" swapped="no"/>
</object>
</child>
</object> </object>
<object class="GtkBox" id="subscription_box"> <object class="GtkBox" id="subscription_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_left">18</property> <property name="halign">start</property>
<property name="margin_right">18</property> <property name="border_width">18</property>
<property name="margin_top">18</property>
<property name="margin_bottom">18</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">5</property> <property name="spacing">6</property>
<child> <child>
<object class="GtkLabel" id="from_label"> <object class="GtkGrid">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="jid_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label">&lt;XMPP address&gt;</property>
<property name="xalign">0</property>
<style>
<class name="large-header"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="request_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label">&lt;subscription request&gt;</property>
<property name="wrap">True</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="subscription_text">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">6</property>
<property name="label">&lt;subscription text&gt;
</property>
<property name="wrap">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<attributes>
<attribute name="style" value="italic"/>
</attributes>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="contact_info_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Contact Information</property>
<property name="valign">center</property>
<property name="image">image2</property>
<signal name="clicked" handler="on_contact_info_button_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="start_chat_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Start Chat</property>
<property name="valign">center</property>
<property name="image">image1</property>
<signal name="clicked" handler="on_start_chat_button_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">0</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="scrolledwindow8"> <object class="GtkSeparator">
<property name="height_request">100</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">False</property>
<property name="border_width">5</property> <property name="margin_top">12</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="message_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="wrap_mode">word</property>
<property name="cursor_visible">False</property>
</object>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">2</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButtonBox" id="hbuttonbox3"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">5</property> <property name="halign">baseline</property>
<property name="margin_top">12</property>
<property name="spacing">12</property> <property name="spacing">12</property>
<property name="layout_style">end</property> <property name="homogeneous">True</property>
<child>
<object class="GtkButton" id="close_button">
<property name="label">_Close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child> <child>
<object class="GtkButton" id="deny_button"> <object class="GtkButton" id="deny_button">
<property name="label" translatable="yes">_Deny</property> <property name="label" translatable="yes">_Deny</property>
@ -97,59 +145,45 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Deny authorization from contact so he or she cannot know when you're connected</property> <property name="tooltip_text" translatable="yes">Deny authorization from contact so the contact cannot know if you are connected</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<signal name="clicked" handler="on_deny_button_clicked" swapped="no"/> <signal name="clicked" handler="on_deny_button_clicked" swapped="no"/>
<style>
<class name="destructive-action"/>
</style>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkMenuButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="popup">subscription_request_popup_menu</property>
<property name="use_popover">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">applications-system-symbolic</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">2</property> <property name="position">0</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="authorize_button"> <object class="GtkButton" id="authorize_button">
<property name="label" translatable="yes">Au_thorize</property> <property name="label" translatable="yes">Ac_cept</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Authorize contact so he or she can know when you're connected</property> <property name="tooltip_text" translatable="yes">Authorize contact so the contact can know if you are connected</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<signal name="clicked" handler="on_authorize_button_clicked" swapped="no"/> <signal name="clicked" handler="on_authorize_button_clicked" swapped="no"/>
<style>
<class name="suggested-action"/>
</style>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">3</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -37,7 +37,6 @@ from gi.repository import Gtk
from gi.repository import Gdk from gi.repository import Gdk
from gi.repository import GLib from gi.repository import GLib
from gajim import vcard
from gajim import dataforms_widget from gajim import dataforms_widget
from gajim.common import ged from gajim.common import ged
@ -53,7 +52,6 @@ from gajim.common.exceptions import GajimGeneralException
# Compat with Gajim 1.0.3 for plugins # Compat with Gajim 1.0.3 for plugins
from gajim.gtk.dialogs import * from gajim.gtk.dialogs import *
from gajim.gtk.add_contact import AddNewContactWindow
from gajim.gtk.util import get_icon_name from gajim.gtk.util import get_icon_name
from gajim.gtk.util import resize_window from gajim.gtk.util import resize_window
from gajim.gtk.util import get_builder from gajim.gtk.util import get_builder
@ -842,89 +840,6 @@ class ChangeStatusMessageDialog(TimeoutDialog):
self.pep_dict['mood_text']) self.pep_dict['mood_text'])
class SubscriptionRequestWindow(Gtk.ApplicationWindow):
def __init__(self, jid, text, account, user_nick=None):
Gtk.ApplicationWindow.__init__(self)
self.set_name('SubscriptionRequest')
self.set_application(app.app)
self.set_show_menubar(False)
self.set_resizable(False)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_title(_('Subscription Request'))
xml = get_builder('subscription_request_window.ui')
self.add(xml.get_object('subscription_box'))
self.jid = jid
self.account = account
self.user_nick = user_nick
if len(app.connections) >= 2:
prompt_text = \
_('Subscription request for account %(account)s from %(jid)s')\
% {'account': account, 'jid': self.jid}
else:
prompt_text = _('Subscription request from %s') % self.jid
from_label = xml.get_object('from_label')
from_label.set_text(prompt_text)
textview = xml.get_object('message_textview')
textview.get_buffer().set_text(text)
self.set_default(xml.get_object('authorize_button'))
xml.connect_signals(self)
self.show_all()
def on_subscription_request_window_destroy(self, widget):
"""
Close window
"""
if self.jid in app.interface.instances[self.account]['sub_request']:
# remove us from open windows
del app.interface.instances[self.account]['sub_request'][self.jid]
def on_close_button_clicked(self, widget):
self.destroy()
def on_authorize_button_clicked(self, widget):
"""
Accept the request
"""
app.connections[self.account].get_module('Presence').subscribed(self.jid)
self.destroy()
contact = app.contacts.get_contact(self.account, self.jid)
if not contact or _('Not in Roster') in contact.groups:
AddNewContactWindow(self.account, self.jid, self.user_nick)
def on_contact_info_activate(self, widget):
"""
Ask vcard
"""
if self.jid in app.interface.instances[self.account]['infos']:
app.interface.instances[self.account]['infos'][self.jid].window.present()
else:
contact = app.contacts.create_contact(jid=self.jid, account=self.account)
app.interface.instances[self.account]['infos'][self.jid] = \
vcard.VcardWindow(contact, self.account)
# Remove jabber page
app.interface.instances[self.account]['infos'][self.jid].xml.\
get_object('information_notebook').remove_page(0)
def on_start_chat_activate(self, widget):
"""
Open chat
"""
app.interface.new_chat_from_jid(self.account, self.jid)
def on_deny_button_clicked(self, widget):
"""
Refuse the request
"""
app.connections[self.account].get_module('Presence').unsubscribed(self.jid)
contact = app.contacts.get_contact(self.account, self.jid)
if contact and _('Not in Roster') in contact.get_shown_groups():
app.interface.roster.remove_contact(self.jid, self.account)
self.destroy()
class SynchroniseSelectAccountDialog: class SynchroniseSelectAccountDialog:
def __init__(self, account): def __init__(self, account):
# 'account' can be None if we are about to create our first one # 'account' can be None if we are about to create our first one

View File

@ -0,0 +1,101 @@
# This file is part of Gajim.
#
# Gajim 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; version 3 only.
#
# Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from gi.repository import Gtk
from gajim import vcard
from gajim.common import app
from gajim.common.i18n import _
from gajim.gtk.add_contact import AddNewContactWindow
from gajim.gtk.util import get_builder
class SubscriptionRequestWindow(Gtk.ApplicationWindow):
def __init__(self, jid, text, account, user_nick=None):
Gtk.ApplicationWindow.__init__(self)
self.set_name('SubscriptionRequest')
self.set_application(app.app)
self.set_show_menubar(False)
self.set_resizable(False)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_title(_('Subscription Request'))
self._ui = get_builder('subscription_request_window.ui')
self.add(self._ui.subscription_box)
self.jid = jid
self.account = account
self.user_nick = user_nick
self._ui.jid_label.set_text(self.jid)
if len(app.connections) >= 2:
prompt_text = \
_('Subscription request for account %(account)s from %(jid)s')\
% {'account': account, 'jid': self.jid}
else:
prompt_text = _('Subscription request from %s') % self.jid
self._ui.request_label.set_text(prompt_text)
self._ui.subscription_text.set_text(text)
self._ui.connect_signals(self)
self.show_all()
def on_subscription_request_window_destroy(self, widget):
"""
Close window
"""
if self.jid in app.interface.instances[self.account]['sub_request']:
# Remove us from open windows
del app.interface.instances[self.account]['sub_request'][self.jid]
def on_authorize_button_clicked(self, widget):
"""
Accept the request
"""
app.connections[self.account].get_module('Presence').subscribed(self.jid)
self.destroy()
contact = app.contacts.get_contact(self.account, self.jid)
if not contact or _('Not in Roster') in contact.groups:
AddNewContactWindow(self.account, self.jid, self.user_nick)
def on_contact_info_button_clicked(self, widget):
"""
Ask for vCard
"""
if self.jid in app.interface.instances[self.account]['infos']:
app.interface.instances[self.account]['infos'][self.jid].window.present()
else:
contact = app.contacts.create_contact(jid=self.jid, account=self.account)
app.interface.instances[self.account]['infos'][self.jid] = \
vcard.VcardWindow(contact, self.account)
# Remove xmpp page
app.interface.instances[self.account]['infos'][self.jid].xml.\
get_object('information_notebook').remove_page(0)
def on_start_chat_button_clicked(self, widget):
"""
Open chat
"""
app.interface.new_chat_from_jid(self.account, self.jid)
def on_deny_button_clicked(self, widget):
"""
Refuse the request
"""
app.connections[self.account].get_module('Presence').unsubscribed(self.jid)
contact = app.contacts.get_contact(self.account, self.jid)
if contact and _('Not in Roster') in contact.get_shown_groups():
app.interface.roster.remove_contact(self.jid, self.account)
self.destroy()

View File

@ -119,6 +119,7 @@ from gajim.gtk.emoji_data import emoji_data
from gajim.gtk.emoji_data import emoji_ascii_data from gajim.gtk.emoji_data import emoji_ascii_data
from gajim.gtk.groupchat_config import GroupchatConfig from gajim.gtk.groupchat_config import GroupchatConfig
from gajim.gtk.filetransfer import FileTransfersWindow from gajim.gtk.filetransfer import FileTransfersWindow
from gajim.gtk.subscription_request import SubscriptionRequestWindow
from gajim.gtk.util import get_show_in_roster from gajim.gtk.util import get_show_in_roster
from gajim.gtk.util import get_show_in_systray from gajim.gtk.util import get_show_in_systray
@ -414,8 +415,8 @@ class Interface:
if obj.jid in self.instances[account]['sub_request']: if obj.jid in self.instances[account]['sub_request']:
self.instances[account]['sub_request'][obj.jid].destroy() self.instances[account]['sub_request'][obj.jid].destroy()
self.instances[account]['sub_request'][obj.jid] = \ self.instances[account]['sub_request'][obj.jid] = \
dialogs.SubscriptionRequestWindow(obj.jid, obj.status, account, SubscriptionRequestWindow(obj.jid, obj.status, account,
obj.user_nick) obj.user_nick)
return return
event = events.SubscriptionRequestEvent(obj.status, obj.user_nick) event = events.SubscriptionRequestEvent(obj.status, obj.user_nick)
@ -1473,8 +1474,7 @@ class Interface:
event = app.events.get_first_event(account, jid, type_) event = app.events.get_first_event(account, jid, type_)
if event is None: if event is None:
return return
dialogs.SubscriptionRequestWindow(jid, event.text, account, SubscriptionRequestWindow(jid, event.text, account, event.nick)
event.nick)
app.events.remove_events(account, jid, event) app.events.remove_events(account, jid, event)
self.roster.draw_contact(jid, account) self.roster.draw_contact(jid, account)
elif type_ == 'unsubscribed': elif type_ == 'unsubscribed':

View File

@ -84,6 +84,7 @@ from gajim.gtk.discovery import ServiceDiscoveryWindow
from gajim.gtk.accounts import AccountsWindow from gajim.gtk.accounts import AccountsWindow
from gajim.gtk.tooltips import RosterTooltip from gajim.gtk.tooltips import RosterTooltip
from gajim.gtk.adhoc_commands import CommandWindow from gajim.gtk.adhoc_commands import CommandWindow
from gajim.gtk.subscription_request import SubscriptionRequestWindow
from gajim.gtk.util import get_icon_name from gajim.gtk.util import get_icon_name
from gajim.gtk.util import resize_window from gajim.gtk.util import resize_window
from gajim.gtk.util import restore_roster_position from gajim.gtk.util import restore_roster_position
@ -1981,8 +1982,7 @@ class RosterWindow:
return True return True
if event.type_ == 'subscription_request': if event.type_ == 'subscription_request':
dialogs.SubscriptionRequestWindow(jid, event.text, account, SubscriptionRequestWindow(jid, event.text, account, event.nick)
event.nick)
app.events.remove_events(account, jid, event) app.events.remove_events(account, jid, event)
return True return True