gajim-plural/gajim/gtk/join_groupchat.py

308 lines
11 KiB
Python

# 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/>.
import nbxmpp
from gi.repository import Gtk
from gi.repository import Gdk
from gajim.common import app
from gajim.common import helpers
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.exceptions import GajimGeneralException
from gajim.gtk.dialogs import ErrorDialog
from gajim.gtk.util import get_builder
class JoinGroupchatWindow(Gtk.ApplicationWindow):
def __init__(self, account, room_jid, password=None, automatic=None,
transient_for=None):
Gtk.ApplicationWindow.__init__(self)
self.set_name('JoinGroupchat')
self.set_application(app.app)
self.set_show_menubar(False)
self.set_resizable(False)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_title(_('Join Group Chat'))
if transient_for:
self.set_transient_for(transient_for)
self.automatic = automatic
self.password = password
self.requested_jid = None
self.room_jid = room_jid
self.account = account
if self.room_jid is None:
self.minimal_mode = False
else:
self.minimal_mode = True
glade_objects = ['main_box', 'account_label', 'account_combo',
'server_label', 'server_combo', 'room_entry',
'recently_button', 'recently_popover',
'recently_treeview', 'search_button', 'password_label',
'password_entry', 'nick_entry', 'bookmark_switch',
'autojoin_switch']
self.builder = get_builder('join_groupchat_window.ui')
for obj in glade_objects:
setattr(self, obj, self.builder.get_object(obj))
self.add(self.main_box)
# Show widgets depending on the mode the window is in
if not self.minimal_mode:
self.recently_button.show()
self.search_button.show()
accounts = app.get_enabled_accounts_with_labels()
account_liststore = self.account_combo.get_model()
for acc in accounts:
account_liststore.append(acc)
if not accounts:
return
if not self.account:
self.account = accounts[0][0]
self.builder.connect_signals(self)
self.connect('key-press-event', self._on_key_press_event)
# Hide account combobox if there is only one account
if len(accounts) == 1:
self.account_combo.hide()
self.account_label.hide()
self.account_combo.set_active_id(self.account)
if self.minimal_mode:
if '@' in self.room_jid:
(room, server) = self.room_jid.split('@')
self.room_entry.set_text(room)
if not muc_caps_cache.supports(
self.room_jid, 'muc_passwordprotected'):
self.password_entry.hide()
self.password_label.hide()
self.nick_entry.grab_focus()
else:
self.password_entry.grab_focus()
else:
server = self.room_jid
self.room_entry.grab_focus()
self.server_combo.insert_text(0, server)
self.server_combo.set_active(0)
if self.password is not None:
self.password_entry.set_text(self.password)
# Set bookmark switch sensitive if server supports bookmarks
acc = self.account_combo.get_active_id()
con = app.connections[acc]
if not con.get_module('Bookmarks').available:
self.bookmark_switch.set_sensitive(False)
self.autojoin_switch.set_sensitive(False)
self.show_all()
def set_room(self, room_jid):
room, server = app.get_name_and_server_from_jid(room_jid)
self.room_entry.set_text(room)
self.server_combo.get_child().set_text(server)
def _fill_recent_and_servers(self, account):
recently_liststore = self.recently_treeview.get_model()
recently_liststore.clear()
self.server_combo.remove_all()
recent = app.get_recent_groupchats(account)
servers = []
for groupchat in recent:
label = '%s@%s' % (groupchat.room, groupchat.server)
recently_liststore.append([groupchat.server,
groupchat.room,
groupchat.nickname,
label])
servers.append(groupchat.server)
self.recently_button.set_sensitive(bool(recent))
for server in set(servers):
self.server_combo.append_text(server)
# Add own Server to ComboBox
muc_domain = app.get_muc_domain(account)
if muc_domain is not None:
self.server_combo.insert_text(0, muc_domain)
def _on_recent_selected(self, treeview, *args):
(model, iter_) = treeview.get_selection().get_selected()
self.server_combo.get_child().set_text(model[iter_][0])
self.room_entry.set_text(model[iter_][1])
self.nick_entry.set_text(model[iter_][2])
self.recently_popover.popdown()
def _on_account_combo_changed(self, combo):
account = combo.get_active_id()
self.account = account
self.nick_entry.set_text(app.nicks[account])
self._fill_recent_and_servers(account)
def _on_jid_detection_changed(self, widget):
text = widget.get_text()
if text.startswith('xmpp:'):
text = text[5:]
if '@' in text:
room, server = text.split('@', 1)
server = server.split('?')[0]
widget.set_text('')
if room:
self.room_entry.set_text(room)
if server:
self.server_combo.get_child().set_text(server)
else:
self.server_combo.grab_focus()
def _on_key_press_event(self, widget, event):
if event.keyval == Gdk.KEY_Escape:
self.destroy()
if event.keyval == Gdk.KEY_Return:
self._on_join_clicked()
return True
def _on_join_clicked(self, *args):
account = self.account_combo.get_active_id()
nickname = self.nick_entry.get_text()
invisible_show = app.SHOW_LIST.index('invisible')
if app.connections[account].connected == invisible_show:
app.interface.raise_dialog('join-while-invisible')
return
server = self.server_combo.get_active_text()
room = self.room_entry.get_text()
if room == '':
ErrorDialog(_('Invalid Room'),
_('Please choose a room'), transient_for=self)
return
self.room_jid = '%s@%s' % (room, server)
try:
self.room_jid = helpers.parse_jid(self.room_jid)
except helpers.InvalidFormat as error:
ErrorDialog(_('Invalid JID'), str(error), transient_for=self)
return
if app.in_groupchat(account, self.room_jid):
# If we already in the groupchat, join_gc_room will bring
# it to front
app.interface.join_gc_room(account, self.room_jid, nickname, '')
self.destroy()
return
if nickname == '':
ErrorDialog(_('Invalid Nickname'),
_('Please choose a nickname'), transient_for=self)
return
try:
helpers.parse_resource(nickname)
except helpers.InvalidFormat as error:
ErrorDialog(_('Invalid Nickname'), str(error), transient_for=self)
return
if not app.account_is_connected(account):
ErrorDialog(
_('You are not connected to the server'),
_('You can not join a group chat unless you are connected.'),
transient_for=self)
return
password = self.password_entry.get_text()
self._add_bookmark(account, nickname, password)
app.add_recent_groupchat(account, self.room_jid, nickname)
if self.automatic:
app.automatic_rooms[self.account][self.room_jid] = self.automatic
app.interface.join_gc_room(account, self.room_jid, nickname, password)
self.destroy()
def _on_cancel_clicked(self, *args):
self.destroy()
def _on_bookmark_activate(self, switch, param):
bookmark_state = switch.get_active()
self.autojoin_switch.set_sensitive(bookmark_state)
if not bookmark_state:
self.autojoin_switch.set_active(False)
def _add_bookmark(self, account, nickname, password):
con = app.connections[account]
add_bookmark = self.bookmark_switch.get_active()
if not add_bookmark:
return
autojoin = self.autojoin_switch.get_active()
# Add as bookmark, with autojoin and not minimized
name = app.get_nick_from_jid(self.room_jid)
con.get_module('Bookmarks').add_bookmark(name,
self.room_jid,
autojoin,
True,
password,
nickname)
def _on_search_clicked(self, widget):
server = self.server_combo.get_active_text().strip()
con = app.connections[self.account]
con.get_module('Discovery').disco_info(
server,
success_cb=self._disco_info_received,
error_cb=self._disco_info_error)
def _disco_info_error(self, from_, error):
ErrorDialog(_('Wrong server'),
_('%s is not a groupchat server') % from_,
transient_for=self)
def _disco_info_received(self, from_, identities, features, data, node):
if nbxmpp.NS_MUC not in features:
ErrorDialog(_('Wrong server'),
_('%s is not a groupchat server') % from_,
transient_for=self)
return
jid = str(from_)
if jid in app.interface.instances[self.account]['disco']:
app.interface.instances[self.account]['disco'][jid].window.\
present()
else:
try:
# Object will add itself to the window dict
from gajim.disco import ServiceDiscoveryWindow
ServiceDiscoveryWindow(
self.account, jid,
initial_identities=[{'category': 'conference',
'type': 'text'}])
except GajimGeneralException:
pass