Commit ace90457 authored by Philipp Hörist's avatar Philipp Hörist

Add new Join Groupchat dialog

- Complete rewrite of the old Groupchat dialog
- Has now a "minimal" mode, which is used if we have all infos for joining except the nickname and if we want to bookmark
- Handle xmpp uris received via command line
parent d814a423
......@@ -18,14 +18,15 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
import sys
import os
from gi.repository import Gtk
from gajim.common import app
from gajim.common import helpers
from gajim.common.app import interface
from gajim.common.exceptions import GajimGeneralException
from gi.repository import Gtk
import sys
import os
from gajim import config
from gajim import dialogs
from gajim import features_window
......@@ -116,13 +117,10 @@ class AppActions():
'You cannot join a group chat while you are invisible'))
return
if 'join_gc' in interface.instances[account]:
interface.instances[account]['join_gc'].window.present()
interface.instances[account]['join_gc'].present()
else:
try:
interface.instances[account]['join_gc'] = \
dialogs.JoinGroupchatWindow(account)
except GajimGeneralException:
pass
interface.instances[account]['join_gc'] = \
dialogs.JoinGroupchatWindow(account, None)
def on_add_contact(self, action, param):
dialogs.AddNewContactWindow(param.get_string())
......
......@@ -1601,15 +1601,13 @@ class ChatControl(ChatControlBase):
self._add_info_bar_message(markup, [b], file_props, Gtk.MessageType.ERROR)
def _on_accept_gc_invitation(self, widget, event):
try:
if event.is_continued:
app.interface.join_gc_room(self.account, event.room_jid,
app.nicks[self.account], event.password,
is_continued=True)
else:
dialogs.JoinGroupchatWindow(self.account, event.room_jid)
except GajimGeneralException:
pass
if event.is_continued:
app.interface.join_gc_room(self.account, event.room_jid,
app.nicks[self.account], event.password,
is_continued=True)
else:
app.interface.join_gc_minimal(self.account, event.room_jid)
app.events.remove_events(self.account, self.contact.jid, event=event)
def _on_cancel_gc_invitation(self, widget, event):
......
......@@ -296,21 +296,12 @@ class StandardGroupChatCommands(CommandContainer):
'room_jid': self.room_jid}
@command(raw=True, empty=True)
@doc(_("Join a group chat given by a jid, optionally using given nickname"))
def join(self, jid, nick):
if not nick:
nick = self.nick
@doc(_("Join a group chat given by a jid"))
def join(self, jid):
if '@' not in jid:
jid = jid + '@' + app.get_server_from_jid(self.room_jid)
try:
app.interface.instances[self.account]['join_gc'].window.present()
except KeyError:
try:
dialogs.JoinGroupchatWindow(account=self.account, room_jid=jid, nick=nick)
except GajimGeneralException:
pass
app.interface.join_gc_minimal(self.account, room_jid=jid)
@command('part', 'close', raw=True, empty=True)
@doc(_("Leave the groupchat, optionally giving a reason, and close tab or window"))
......
......@@ -33,6 +33,7 @@ import logging
import locale
import uuid
from distutils.version import LooseVersion as V
from collections import namedtuple
import gi
import nbxmpp
import hashlib
......@@ -81,6 +82,8 @@ PLUGINS_DIRS = [gajimpaths['PLUGINS_BASE'],
PLUGINS_CONFIG_DIR = gajimpaths['PLUGINS_CONFIG_DIR']
MY_CERT_DIR = gajimpaths['MY_CERT']
RecentGroupchat = namedtuple('RecentGroupchat', ['room', 'server', 'nickname'])
try:
LANG = locale.getdefaultlocale()[0] # en_US, fr_FR, el_GR etc..
except (ValueError, locale.Error):
......@@ -373,6 +376,16 @@ def get_number_of_connected_accounts(accounts_list = None):
connected_accounts = connected_accounts + 1
return connected_accounts
def get_connected_accounts():
"""
Returns a list of CONNECTED accounts
"""
account_list = []
for account in connections:
if account_is_connected(account):
account_list.append(account)
return account_list
def account_is_connected(account):
if account not in connections:
return False
......@@ -388,6 +401,11 @@ def zeroconf_is_connected():
return account_is_connected(ZEROCONF_ACC_NAME) and \
config.get_per('accounts', ZEROCONF_ACC_NAME, 'is_zeroconf')
def in_groupchat(account, room_jid):
if room_jid not in gc_connected[account]:
return False
return gc_connected[account][room_jid]
def get_number_of_securely_connected_accounts():
"""
Return the number of the accounts that are SSL/TLS connected
......@@ -495,6 +513,34 @@ def get_name_from_jid(account, jid):
actor = jid
return actor
def get_muc_domain(account):
return connections[account].muc_jid.get('jabber', None)
def get_recent_groupchats(account):
recent_groupchats = config.get_per(
'accounts', account, 'recent_groupchats').split()
recent_list = []
for groupchat in recent_groupchats:
jid = nbxmpp.JID(groupchat)
recent = RecentGroupchat(
jid.getNode(), jid.getDomain(), jid.getResource())
recent_list.append(recent)
return recent_list
def add_recent_groupchat(account, room_jid, nickname):
recent = config.get_per(
'accounts', account, 'recent_groupchats').split()
full_jid = room_jid + '/' + nickname
if full_jid in recent:
recent.remove(full_jid)
recent.insert(0, full_jid)
if len(recent) > 10:
recent = recent[0:9]
config_value = ' '.join(recent)
config.set_per(
'accounts', account, 'recent_groupchats', config_value)
def get_priority(account, show):
"""
Return the priority an account must have
......
......@@ -472,6 +472,10 @@ class MucCapsCache:
if child.getNamespace() == nbxmpp.NS_DATA:
data.append(nbxmpp.DataForm(node=child))
if nbxmpp.NS_MUC not in features:
# Not a MUC, dont cache info
return
self.cache[jid] = self.DiscoInfo(identities, features, data)
def is_cached(self, jid):
......
......@@ -174,7 +174,6 @@ class Config:
'history_window_x-position': [ opt_int, 0 ],
'history_window_y-position': [ opt_int, 0 ],
'latest_disco_addresses': [ opt_str, '' ],
'recently_groupchat': [ opt_str, '' ],
'time_stamp': [ opt_str, '[%X] ', _('This option let you customize timestamp that is printed in conversation. For exemple "[%H:%M] " will show "[hour:minute] ". See python doc on strftime for full documentation: http://docs.python.org/lib/module-time.html') ],
'before_nickname': [ opt_str, '', _('Characters that are printed before the nickname in conversations') ],
'after_nickname': [ opt_str, ':', _('Characters that are printed after the nickname in conversations') ],
......@@ -409,6 +408,7 @@ class Config:
'oauth2_client_id': [ opt_str, '0000000044077801', _('client_id for OAuth 2.0 authentication.')],
'oauth2_redirect_url': [ opt_str, 'https%3A%2F%2Fgajim.org%2Fmsnauth%2Findex.cgi', _('redirect_url for OAuth 2.0 authentication.')],
'opened_chat_controls': [opt_str, '', _('Space separated list of JIDs for which we want to re-open a chat window on next startup.')],
'recent_groupchats': [ opt_str, '' ],
}, {}),
'statusmsg': ({
'message': [ opt_str, '' ],
......
......@@ -98,6 +98,9 @@ class ConnectionDisco:
self.disco_info_ids.append(id_)
def discoverMUC(self, jid, callback):
if muc_caps_cache.is_cached(jid):
callback()
return
disco_info = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_INFO)
self.connection.SendAndCallForResponse(
disco_info, self.received_muc_info, {'callback': callback})
......
......@@ -689,15 +689,9 @@ class ConversationTextview(GObject.GObject):
app.interface.new_chat_from_jid(self.account, jid)
def on_join_group_chat_menuitem_activate(self, widget, room_jid):
if 'join_gc' in app.interface.instances[self.account]:
instance = app.interface.instances[self.account]['join_gc']
instance.xml.get_object('room_jid_entry').set_text(room_jid)
app.interface.instances[self.account]['join_gc'].window.present()
else:
try:
dialogs.JoinGroupchatWindow(account=self.account, room_jid=room_jid)
except GajimGeneralException:
pass
# Remove ?join
room_jid = room_jid.split('?')[0]
app.interface.join_gc_minimal(self.account, room_jid)
def on_add_to_roster_activate(self, widget, jid):
dialogs.AddNewContactWindow(self.account, jid)
......@@ -805,7 +799,7 @@ class ConversationTextview(GObject.GObject):
if '?' in word:
(jid, action) = word.split('?')
if action == 'join':
self.on_join_group_chat_menuitem_activate(None, jid)
app.interface.join_gc_minimal(None, jid)
else:
self.on_start_chat_activate(None, jid)
else:
......
This diff is collapsed.
......@@ -86,4 +86,6 @@ popover#EmoticonPopover flowboxchild { padding-top: 5px; padding-bottom: 5px; }
background-color: @theme_unfocused_bg_color;
color: @theme_text_color; }
/* Text style */
.bold16 { font-size: 16px; font-weight: bold; }
This diff is collapsed.
......@@ -1400,13 +1400,7 @@ class ToplevelAgentBrowser(AgentBrowser):
if not iter_:
return
service = model[iter_][0]
if 'join_gc' not in app.interface.instances[self.account]:
try:
dialogs.JoinGroupchatWindow(self.account, service)
except GajimGeneralException:
pass
else:
app.interface.instances[self.account]['join_gc'].window.present()
app.interface.join_gc_minimal(self.account, service)
def update_actions(self):
if self.execute_button:
......@@ -1810,14 +1804,11 @@ class MucBrowser(AgentBrowser):
return
service = model[iter_][0]
if 'join_gc' not in app.interface.instances[self.account]:
try:
dialogs.JoinGroupchatWindow(self.account, service)
except GajimGeneralException:
pass
app.interface.join_gc_minimal(self.account, service)
else:
app.interface.instances[self.account]['join_gc']._set_room_jid(
service)
app.interface.instances[self.account]['join_gc'].window.present()
app.interface.instances[self.account]['join_gc'].set_room(service)
app.interface.instances[self.account]['join_gc'].present()
self.window.destroy()
def update_actions(self):
sens = self.window.services_treeview.get_selection().count_selected_rows()
......
......@@ -60,7 +60,8 @@ class GajimApplication(Gtk.Application):
'''Main class handling activation and command line.'''
def __init__(self):
Gtk.Application.__init__(self, application_id='org.gajim.Gajim')
Gtk.Application.__init__(self, application_id='org.gajim.Gajim',
flags=Gio.ApplicationFlags.HANDLES_OPEN)
self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE,
GLib.OptionArg.NONE,
......@@ -89,13 +90,11 @@ class GajimApplication(Gtk.Application):
self.add_main_option('warnings', ord('w'), GLib.OptionFlags.NONE,
GLib.OptionArg.NONE,
_('Show all warnings'))
self.add_main_option(GLib.OPTION_REMAINING, 0, GLib.OptionFlags.HIDDEN,
GLib.OptionArg.STRING_ARRAY,
"")
self.connect('handle-local-options', self._handle_local_options)
self.connect('startup', self._startup)
self.connect('activate', self._activate)
self.connect('open', self._open)
self.profile = ''
self.config_path = None
......@@ -235,6 +234,15 @@ class GajimApplication(Gtk.Application):
from gajim import gui_menu_builder
gui_menu_builder.build_accounts_menu()
def _open(self, application, file, hint, *args):
for arg in file:
uri = arg.get_uri()
# remove xmpp:///
uri = uri[8:]
jid, cmd = uri.split('?')
if cmd == 'join':
self.interface.join_gc_minimal(None, jid)
def do_shutdown(self, *args):
Gtk.Application.do_shutdown(self)
# Shutdown GUI and save config
......@@ -274,10 +282,6 @@ class GajimApplication(Gtk.Application):
logging_helpers.set_loglevels(loglevel)
if options.contains('warnings'):
self.show_warnings()
if options.contains(GLib.OPTION_REMAINING):
unhandled = options.lookup_value(GLib.OPTION_REMAINING).get_strv()
print('Error: Unhandled arguments: %s' % unhandled)
return 0
return -1
def show_warnings(self):
......
......@@ -101,6 +101,7 @@ from gajim import profile_window
from gajim import config
from threading import Thread
from gajim.common import ged
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.configpaths import gajimpaths
config_filename = gajimpaths['CONFIG_FILE']
......@@ -1757,6 +1758,49 @@ class Interface:
tv = ctrl.conv_textview
tv.scroll_to_end_iter()
def join_gc_minimal(self, account, room_jid, password=None):
if account is not None:
if app.in_groupchat(account, room_jid):
# If we already in the groupchat, join_gc_room will bring
# it to front
app.interface.join_gc_room(account, room_jid, '', '')
return
for bookmark in app.connections[account].bookmarks:
if bookmark['jid'] != room_jid:
continue
app.interface.join_gc_room(
account, room_jid, bookmark['nick'], bookmark['password'])
return
try:
room_jid = helpers.parse_jid(room_jid)
except helpers.InvalidFormat:
dialogs.ErrorDialog('Invalid JID',
transient_for=app.app.get_active_window())
return
connected_accounts = app.get_connected_accounts()
if account is not None and account not in connected_accounts:
connected_accounts = None
if not connected_accounts:
dialogs.ErrorDialog(
_('You are not connected to the server'),
_('You can not join a group chat unless you are connected.'),
transient_for=app.app.get_active_window())
return
def _on_discover_result():
if not muc_caps_cache.is_cached(room_jid):
dialogs.ErrorDialog(_('JID is not a Groupchat'),
transient_for=app.app.get_active_window())
return
dialogs.JoinGroupchatWindow(account, room_jid, password=password)
disco_account = connected_accounts[0] if account is None else account
app.connections[disco_account].discoverMUC(
room_jid, _on_discover_result)
################################################################################
### Methods dealing with emoticons
################################################################################
......@@ -1953,8 +1997,6 @@ class Interface:
win.set_active_tab(gc_ctrl)
else:
self.roster.on_groupchat_maximized(None, room_jid, account)
dialogs.ErrorDialog(_('You are already in group chat %s') % \
room_jid)
return
invisible_show = app.SHOW_LIST.index('invisible')
......@@ -2130,6 +2172,7 @@ class Interface:
### Other Methods
################################################################################
@staticmethod
def change_awn_icon_status(status):
if not dbus_support.supported:
......@@ -2454,7 +2497,7 @@ class Interface:
self.roster.add_groupchat(jid, account)
def add_gc_bookmark(self, account, name, jid, autojoin, minimize, password,
nick):
nick):
"""
Add a bookmark for this account, sorted in bookmark list
"""
......@@ -2471,10 +2514,6 @@ class Interface:
# check for duplicate entry and respect alpha order
for bookmark in app.connections[account].bookmarks:
if bookmark['jid'] == bm['jid']:
dialogs.ErrorDialog(
_('Bookmark already set'),
_('Group Chat "%s" is already in your bookmarks.') % \
bm['jid'])
return
if bookmark['name'] > bm['name']:
place_found = True
......@@ -2486,10 +2525,6 @@ class Interface:
app.connections[account].bookmarks.append(bm)
app.connections[account].store_bookmarks()
gui_menu_builder.build_bookmark_menu(account)
dialogs.InformationDialog(
_('Bookmark has been added successfully'),
_('You can manage your bookmarks via Actions menu in your roster.'))
# does JID exist only within a groupchat?
def is_pm_contact(self, fjid, account):
......
......@@ -915,10 +915,7 @@ class HtmlTextView(Gtk.TextView):
# app.interface.new_chat_from_jid(self.account, jid)
def on_join_group_chat_menuitem_activate(self, widget, room_jid):
try:
dialogs.JoinGroupchatWindow(room_jid=room_jid)
except GajimGeneralException:
pass
dialogs.JoinGroupchatWindow(None, room_jid)
def on_add_to_roster_activate(self, widget, jid):
dialogs.AddNewContactWindow(self.account, jid)
......
......@@ -908,8 +908,6 @@ class SignalObject(dbus.service.Object):
return
if not nick:
nick = ''
app.interface.instances[account]['join_gc'] = \
JoinGroupchatWindow(account, room_jid, nick)
app.interface.join_gc_minimal(account, room_jid)
else:
app.interface.join_gc_room(account, room_jid, nick, password)
......@@ -3091,15 +3091,11 @@ class RosterWindow:
if app.connections[account].muc_jid[type_]:
# create the room on this muc server
if 'join_gc' in app.interface.instances[account]:
app.interface.instances[account]['join_gc'].window.\
destroy()
try:
app.interface.instances[account]['join_gc'].destroy()
else:
app.interface.instances[account]['join_gc'] = \
dialogs.JoinGroupchatWindow(account,
app.connections[account].muc_jid[type_],
automatic = {'invities': jid_list})
except GajimGeneralException:
continue
dialogs.JoinGroupchatWindow(
account, None, automatic={'invities': jid_list})
break
def on_invite_to_room(self, widget, list_, room_jid, room_account,
......@@ -3676,13 +3672,10 @@ class RosterWindow:
'invisible'))
return
if 'join_gc' in app.interface.instances[account]:
app.interface.instances[account]['join_gc'].window.present()
app.interface.instances[account]['join_gc'].present()
else:
try:
app.interface.instances[account]['join_gc'] = \
dialogs.JoinGroupchatWindow(account)
except GajimGeneralException:
pass
app.interface.instances[account]['join_gc'] = \
dialogs.JoinGroupchatWindow(account, None)
def on_new_chat_menuitem_activate(self, widget, account):
dialogs.NewChatDialog(account)
......
......@@ -651,9 +651,7 @@ if dbus_support.supported:
if not account:
return
if not nick:
nick = ''
gajim.interface.instances[account]['join_gc'] = \
JoinGroupchatWindow(account, room_jid, nick)
gajim.interface.join_gc_minimal(account, room_jid)
else:
gajim.interface.join_gc_room(account, room_jid, nick, password)
......
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