305 lines
11 KiB
Python
305 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 import ged
|
|
from gajim.common.caps_cache import muc_caps_cache
|
|
from gajim.common.exceptions import GajimGeneralException
|
|
from gajim.gtk 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 = int(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, 1, 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
|