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
Pipeline #4150 passed with stages
in 2 minutes and 41 seconds
<?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.common.connection_handlers_events import GcMessageOutgoingEvent
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 @@ class GroupchatControl(ChatControlBase):
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 @@ class GroupchatControl(ChatControlBase):
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 @@ class GroupchatControl(ChatControlBase):
(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 @@ class GroupchatControl(ChatControlBase):
(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 @@ class GroupchatControl(ChatControlBase):
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 @@ class InputTextDialog(CommonInputDialog):
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