Commit 7e3d67e7 authored by Daniel Brötzmann's avatar Daniel Brötzmann Committed by Philipp Hörist

Groupchat: Integrate Kick, Ban, and Destroy into GroupchatControl

parent 3745f883
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkDialog" id="destroy_muc_dialog">
<property name="width_request">250</property>
<property name="can_focus">False</property>
<property name="border_width">18</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="type_hint">dialog</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label">_Cancel</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>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="destroy_button">
<property name="label">_Destroy</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<style>
<class name="destructive-action"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label_header">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Destroy this group chat permanently?</property>
<property name="use_markup">True</property>
<property name="wrap">True</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="GtkExpander" id="reason_expander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_top">6</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkEntry" id="reason_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_top">6</property>
<property name="activates_default">True</property>
<property name="placeholder_text" translatable="yes">Reason...</property>
<property name="show_emoji_icon">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="alt_venue_label">
<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" translatable="yes">Where participants should go (optional)</property>
<property name="wrap">True</property>
<property name="xalign">0</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="alt_venue_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="placeholder_text" translatable="yes">Alternate venue...</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Reason and alternate venue (optional)</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">reason_entry</property>
<signal name="mnemonic-activate" handler="_on_reason_mnemonic_activate" swapped="no"/>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="icon_name">user-trash-symbolic</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
This diff is collapsed.
......@@ -74,8 +74,6 @@
from gajim.gtk.dialogs import DialogButton
from gajim.gtk.dialogs import NewConfirmationCheckDialog
from gajim.gtk.dialogs import ErrorDialog
from gajim.gtk.dialogs import DestroyMucDialog
from gajim.gtk.dialogs import InputDialog
from gajim.gtk.dialogs import NewConfirmationDialog
from gajim.gtk.filechoosers import AvatarChooserDialog
from gajim.gtk.add_contact import AddNewContactWindow
......@@ -676,24 +674,36 @@ def _on_information(self, action, param):
self._subject_data.user_timestamp)
self._show_page('muc-info')
def _on_destroy_room(self, action, param):
def _on_confirm(reason, jid):
if jid:
# Test jid
try:
jid = helpers.parse_jid(jid)
except Exception:
ErrorDialog(
_('Invalid group chat XMPP Address'),
_('The group chat XMPP Address has not allowed characters.'))
return
self._wait_for_destruction = True
con = app.connections[self.account]
con.get_module('MUC').destroy(self.room_jid, reason, jid)
def _on_destroy_room(self, _action, _param):
self.xml.destroy_reason_entry.grab_focus()
self.xml.destroy_button.grab_default()
self._show_page('destroy')
# Ask for a reason (and an alternate venue)
DestroyMucDialog(self.room_jid, destroy_handler=_on_confirm)
def _on_destroy_alternate_changed(self, entry, _param):
jid = entry.get_text()
if jid:
try:
jid = helpers.validate_jid(jid)
except Exception:
icon = 'dialog-warning-symbolic'
text = _('Invalid XMPP Address')
self.xml.destroy_alternate_entry.set_icon_from_icon_name(
Gtk.EntryIconPosition.SECONDARY, icon)
self.xml.destroy_alternate_entry.set_icon_tooltip_text(
Gtk.EntryIconPosition.SECONDARY, text)
self.xml.destroy_button.set_sensitive(False)
return
self.xml.destroy_alternate_entry.set_icon_from_icon_name(
Gtk.EntryIconPosition.SECONDARY, None)
self.xml.destroy_button.set_sensitive(True)
def _on_destroy_confirm(self, _button):
reason = self.xml.destroy_reason_entry.get_text()
jid = self.xml.destroy_alternate_entry.get_text()
self._wait_for_destruction = True
con = app.connections[self.account]
con.get_module('MUC').destroy(self.room_jid, reason, jid)
self._show_page('groupchat')
def _on_configure_room(self, _action, _param):
win = app.get_app_window('GroupchatConfig', self.account, self.room_jid)
......@@ -2497,19 +2507,6 @@ def on_list_treeview_row_collapsed(self, widget, iter_, path):
model = widget.get_model()
model[iter_][Column.IMG] = get_icon_name('closed')
def kick(self, widget, nick):
"""
Kick a user
"""
def on_ok(reason):
con = app.connections[self.account]
con.get_module('MUC').set_role(self.room_jid, nick, 'none', reason)
# ask for reason
InputDialog(_('Kicking %s') % nick,
_('You may specify a reason below:'), ok_handler=on_ok,
transient_for=self.parent_win.window)
def mk_menu(self, event, iter_):
"""
Make contact's popup menu
......@@ -2537,7 +2534,7 @@ def mk_menu(self, event, iter_):
(user_affiliation.is_member and target_affiliation in (Affiliation.ADMIN,
Affiliation.OWNER)) or (user_affiliation.is_none and not target_affiliation.is_none):
item.set_sensitive(False)
id_ = item.connect('activate', self.kick, nick)
id_ = item.connect('activate', self._on_kick_participant, nick)
self.handlers[id_] = item
item = xml.get_object('voice_checkmenuitem')
......@@ -2565,7 +2562,7 @@ def mk_menu(self, event, iter_):
(target_affiliation in (Affiliation.ADMIN, Affiliation.OWNER) and\
not user_affiliation.is_owner):
item.set_sensitive(False)
id_ = item.connect('activate', self.ban, jid)
id_ = item.connect('activate', self._on_ban_participant, jid)
self.handlers[id_] = item
item = xml.get_object('member_checkmenuitem')
......@@ -2793,23 +2790,35 @@ def revoke_moderator(self, widget, nick):
con = app.connections[self.account]
con.get_module('MUC').set_role(self.room_jid, nick, 'participant')
def ban(self, widget, jid):
"""
Ban a user
"""
def on_ok(reason):
con = app.connections[self.account]
con.get_module('MUC').set_affiliation(
self.room_jid,
{jid: {'affiliation': 'outcast',
'reason': reason}})
def _on_kick_participant(self, _widget, nick):
self._kick_nick = nick
self.xml.kick_label.set_text(_('Kick %s' % nick))
self.xml.kick_reason_entry.grab_focus()
self.xml.kick_participant_button.grab_default()
self._show_page('kick')
def _on_kick_participant_clicked(self, _button):
reason = self.xml.kick_reason_entry.get_text()
con = app.connections[self.account]
con.get_module('MUC').set_role(
self.room_jid, self._kick_nick, 'none', reason)
self._show_page('groupchat')
# to ban we know the real jid. so jid is not fakejid
def _on_ban_participant(self, _widget, jid):
self._ban_jid = jid
nick = app.get_nick_from_jid(jid)
# ask for reason
InputDialog(_('Banning %s') % nick,
_('You may specify a reason below:'), ok_handler=on_ok,
transient_for=self.parent_win.window)
self.xml.ban_label.set_text(_('Ban %s' % nick))
self.xml.ban_reason_entry.grab_focus()
self.xml.ban_participant_button.grab_default()
self._show_page('ban')
def _on_ban_participant_clicked(self, _button):
reason = self.xml.ban_reason_entry.get_text()
con = app.connections[self.account]
con.get_module('MUC').set_affiliation(
self.room_jid,
{self._ban_jid: {'affiliation': 'outcast', 'reason': reason}})
self._show_page('groupchat')
def grant_membership(self, widget, jid):
"""
......
......@@ -547,50 +547,6 @@ def get_text(self):
return self.input_buffer.get_text(start_iter, end_iter, True)
class DestroyMucDialog:
"""
Class for Destroy MUC Dialog
"""
def __init__(self, room_jid, destroy_handler=None):
self._ui = get_builder('destroy_muc_dialog.ui')
self._ui.destroy_muc_dialog.set_transient_for(
app.app.get_active_window())
self.destroy_handler = destroy_handler
title = _('Destroy %s') % room_jid
self._ui.destroy_muc_dialog.set_title(title)
label_header = _('Destroy this group chat permanently?')
self._ui.label_header.set_markup(label_header)
label_alt_venue = _('Where participants should go (optional)')
self._ui.alt_venue_label.set_markup(label_alt_venue)
self._ui.reason_entry.connect('activate', self._on_entry_activate)
self._ui.alt_venue_entry.connect('activate', self._on_entry_activate)
self._ui.destroy_button.connect(
'clicked', self._on_destroy_button_clicked)
self._ui.cancel_button.connect(
'clicked', self._on_cancel_button_clicked)
self._ui.connect_signals(self)
self._ui.destroy_muc_dialog.show_all()
def _on_entry_activate(self, widget, *args):
self._ui.destroy_button.set_active(True)
def _on_reason_mnemonic_activate(self, widget, group_cycling=False):
self._ui.reason_expander.set_expanded(True)
def _on_destroy_button_clicked(self, widget):
user_input_reason = self._ui.reason_entry.get_text()
user_input_alt_venue = self._ui.alt_venue_entry.get_text()
self._ui.destroy_muc_dialog.destroy()
self.destroy_handler(user_input_reason, user_input_alt_venue)
def _on_cancel_button_clicked(self, widget):
self._ui.destroy_muc_dialog.destroy()
class CertificateDialog(Gtk.ApplicationWindow):
def __init__(self, transient_for, account, cert):
Gtk.ApplicationWindow.__init__(self)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment