Commit 72207b29 authored by Martin's avatar Martin

Imported upstream master from 2017-12-06

parent 6c4cf4d9
......@@ -14,7 +14,7 @@ run-test:
run-pylint:
stage: test
script:
- pylint3 --additional-builtins=_ --disable=all --enable=E0001,E0011,E0012,E0100,E0101,E0102,E0103,E0104,E0105,E0106,E0107,E0108,E0202,E0221,E0222,E0235,E0501,E0502,E0503,E0602,E0603,E0604,E0701,E0702,E1001,E1002,E1003,E1004,E1111,E1120,E1121,E1122,E1123,E1124,E1125,E1200,E1201,E1205,E1206,E1300,E1301,E1302,E1303,E1304,E1305,E1306,E1310,E1700,E1701 gajim
- pylint3 --additional-builtins=_ --disable=all --enable=E0001,E0011,E0012,E0100,E0101,E0102,E0103,E0104,E0105,E0106,E0107,E0108,E0202,E0221,E0222,E0235,E0501,E0502,E0503,E0602,E0603,E0604,E0701,E0702,E1001,E1002,E1003,E1004,E1111,E1120,E1121,E1122,E1123,E1124,E1125,E1200,E1201,E1205,E1206,E1300,E1301,E1302,E1303,E1304,E1305,E1306,E1310,E1700,E1701,W0102 gajim
run-build:
stage: build
......
......@@ -25,6 +25,7 @@
- gir1.2-farstream-0.2, gir1.2-gstreamer-1.0 and gir1.2-gst-plugins-base-1.0 for audio and video calls
- gir1.2-gupnpigd-1.0 for better NAT traversing
- gir1.2-networkmanager-1.0 for network lose detection
- gir1.2-geoclue-2.0 for sharing your location
- python3-idna and python3-precis-i18n for correctly parsing JIDs
### Compile-time Requirements
......
......@@ -19,8 +19,6 @@ by D-Bus.
.El
.Ss account_info Aq account
Gets detailed info on a account
.Ss add_contact Ao jid Ac Bq account
Adds contact to roster
.Ss change_avatar Ao picture Ac Bq account
Change the avatar
.Ss change_status Bo status Bc Bo message Bc Bq account
......@@ -35,18 +33,12 @@ Returns current status (the global one unless account is specified)
Returns current status message (the global one unless account is specified)
.Ss get_unread_msgs_number
Returns number of unread messages
.Ss handle_uri Ao uri Ac Bo account Bc Bq message
Handle a xmpp:/ uri
.Ss help Bq command
Shows a help on specific command
.Ss join_room Ao room Ac Bo nick Bc Bo password Bc Bq account
Join a MUC room
.Ss list_accounts
Prints a list of registered accounts
.Ss list_contacts Bq account
Prints a list of all contacts in the roster. Each contact appears on a separate line
.Ss open_chat Ao jid Ac Bo account Bc Bq message
Shows the chat dialog so that you can send messages to a contact
.Ss prefs_del Aq key
Deletes a preference item
.Ss prefs_list
......@@ -71,8 +63,6 @@ Sends custom XML
Changes the priority of account or accounts
.Ss show_next_pending_event
Pops up a window with the next pending event
.Ss start_chat Aq account
Opens 'Start Chat' dialog
.Ss toggle_ipython
Shows or hides the ipython window
.Ss toggle_roster_appearance
......
......@@ -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
......@@ -43,6 +44,11 @@ class AppActions():
def __init__(self, application: Gtk.Application):
self.application = application
# General Actions
def on_add_contact_jid(self, action, param):
dialogs.AddNewContactWindow(None, param.get_string())
# Application Menu Actions
def on_preferences(self, action, param):
......@@ -74,6 +80,12 @@ class AppActions():
def on_quit(self, action, param):
interface.roster.on_quit_request()
def on_new_chat(self, action, param):
if 'start_chat' in app.interface.instances:
app.interface.instances['start_chat'].present()
else:
app.interface.instances['start_chat'] = dialogs.StartChatDialog()
# Accounts Actions
def on_profile(self, action, param):
......@@ -116,20 +128,14 @@ 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())
def on_new_chat(self, action, param):
dialogs.NewChatDialog(param.get_string())
def on_single_message(self, action, param):
dialogs.SingleMessageWindow(param.get_string(), action='send')
......
......@@ -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):
......
......@@ -913,7 +913,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self.received_history_pos = pos
def print_conversation_line(self, text, kind, name, tim,
other_tags_for_name=[], other_tags_for_time=[], other_tags_for_text=[],
other_tags_for_name=None, other_tags_for_time=None, other_tags_for_text=None,
count_as_new=True, subject=None, old_kind=None, xhtml=None, simple=False,
xep0184_id=None, graphics=True, displaymarking=None, msg_log_id=None,
msg_stanza_id=None, correct_id=None, additional_data=None,
......
......@@ -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):
......@@ -231,6 +234,13 @@ try:
except (ImportError, ValueError):
HAVE_FARSTREAM = False
HAVE_GEOCLUE = True
try:
gi.require_version('Geoclue', '2.0')
from gi.repository import Geoclue
except (ImportError, ValueError):
HAVE_GEOCLUE = False
HAVE_UPNP_IGD = True
try:
gi.require_version('GUPnPIgd', '1.0')
......@@ -373,6 +383,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 +408,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 +520,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, '' ],
......
......@@ -182,11 +182,6 @@ class CommonConnection:
self.get_config_values_or_default()
h = app.config.get_per('accounts', self.name, 'hostname')
if h:
app.resolver.resolve('_xmppconnect.' + helpers.idn_to_ascii(h),
self._on_resolve_txt, type_='txt')
def _compute_resource(self):
resource = app.config.get_per('accounts', self.name, 'resource')
# All valid resource substitution strings should be added to this hash.
......@@ -709,6 +704,11 @@ class Connection(CommonConnection, ConnectionHandlers):
self._nec_gc_stanza_message_outgoing)
app.ged.register_event_handler('stanza-message-outgoing',
ged.OUT_CORE, self._nec_stanza_message_outgoing)
h = app.config.get_per('accounts', self.name, 'hostname')
if h:
app.resolver.resolve('_xmppconnect.' + helpers.idn_to_ascii(h),
self._on_resolve_txt, type_='txt')
# END __init__
def cleanup(self):
......
......@@ -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})
......
......@@ -411,6 +411,16 @@ def get_uf_show(show, use_mnemonic = False):
uf_show = Q_('?contact has status:Has errors')
return uf_show
def get_css_show_color(show):
if show in ('online', 'chat', 'invisible'):
return 'status-online'
elif show in ('offline', 'not in roster', 'requested'):
return None
elif show in ('xa', 'dnd'):
return 'status-dnd'
elif show in ('away'):
return 'status-away'
def get_uf_sub(sub):
if sub == 'none':
uf_sub = Q_('?Subscription we already have:None')
......
......@@ -19,14 +19,21 @@
##
from datetime import datetime
import logging
from gajim.common import app
from gajim.common import dbus_support
if dbus_support.supported:
import dbus
import gi
gi.require_version('Geoclue', '2.0')
from gi.repository import Geoclue
from gi.repository import GLib
log = logging.getLogger('gajim.c.location_listener')
class LocationListener:
_instance = None
@classmethod
def get(cls):
if cls._instance is None:
......@@ -36,89 +43,41 @@ class LocationListener:
def __init__(self):
self._data = {}
def get_data(self):
bus = dbus.SessionBus()
def _on_location_update(self, simple):
location = simple.get_location()
timestamp = location.get_property("timestamp")[0]
lat = location.get_property("latitude")
lon = location.get_property("longitude")
alt = location.get_property("altitude")
# in XEP-0080 it's horizontal accuracy
acc = location.get_property("accuracy")
# update data with info we just received
self._data = {'lat': lat, 'lon': lon, 'alt': alt, 'accuracy': acc}
self._data['timestamp'] = self._timestamp_to_utc(timestamp)
self._send_location()
def _on_simple_ready(self, obj, result):
try:
# Initializes Geoclue.
obj = bus.get_object('org.freedesktop.Geoclue.Master',
'/org/freedesktop/Geoclue/Master')
# get MasterClient path
path = obj.Create()
# get MasterClient
cli = bus.get_object('org.freedesktop.Geoclue.Master', path)
cli.SetRequirements(1, 0, True, 1023)
self._get_address(cli)
self._get_position(cli)
except:
self._on_geoclue_position_changed()
return
def _get_address(self, cli):
bus = dbus.SessionBus()
cli.AddressStart()
# Check that there is a provider
name, description, service, path = cli.GetAddressProvider()
if path:
provider = bus.get_object(service, path)
timestamp, address, accuracy = provider.GetAddress()
self._on_geoclue_address_changed(timestamp, address, accuracy)
def _get_position(self, cli):
bus = dbus.SessionBus()
cli.PositionStart()
# Check that there is a provider
name, description, service, path = cli.GetPositionProvider()
if path:
provider = bus.get_object(service, path)
fields, timestamp, lat, lon, alt, accuracy = provider.GetPosition()
self._on_geoclue_position_changed(fields, timestamp, lat, lon, alt,
accuracy)
self.simple = Geoclue.Simple.new_finish(result)
except GLib.Error as e:
if e.domain == 'g-dbus-error-quark':
log.warning("Could not enable geolocation: %s", e.message)
else:
raise
else:
self.simple.connect('notify::location', self._on_location_update)
self._on_location_update(self.simple)
def get_data(self):
Geoclue.Simple.new("org.gajim.Gajim",
Geoclue.AccuracyLevel.EXACT,
None,
self._on_simple_ready)
def start(self):
self.location_info = {}
self.get_data()
bus = dbus.SessionBus()
# Geoclue
bus.add_signal_receiver(self._on_geoclue_address_changed,
'AddressChanged', 'org.freedesktop.Geoclue.Address')
bus.add_signal_receiver(self._on_geoclue_position_changed,
'PositionChanged', 'org.freedesktop.Geoclue.Position')
def shut_down(self):
pass
def _on_geoclue_address_changed(self, timestamp=None, address=None,
accuracy=None):
# update data with info we just received
if address is None:
address = {}
for field in ['country', 'countrycode', 'locality', 'postalcode',
'region', 'street']:
self._data[field] = address.get(field, None)
if timestamp:
self._data['timestamp'] = self._timestamp_to_utc(timestamp)
if accuracy:
# in PEP it's horizontal accuracy
self._data['accuracy'] = accuracy[1]
self._send_location()
def _on_geoclue_position_changed(self, fields=None, timestamp=None, lat=None,
lon=None, alt=None, accuracy=None):
if fields is None:
fields = []
# update data with info we just received
_dict = {'lat': lat, 'lon': lon, 'alt': alt}
for field in _dict:
if _dict[field] is not None:
self._data[field] = _dict[field]
if timestamp:
self._data['timestamp'] = self._timestamp_to_utc(timestamp)
if accuracy:
# in PEP it's horizontal accuracy
self._data['accuracy'] = accuracy[1]
self._send_location()
def _send_location(self):
accounts = app.connections.keys()
......@@ -143,10 +102,7 @@ class LocationListener:
time = datetime.utcfromtimestamp(timestamp)
return time.strftime('%Y-%m-%dT%H:%MZ')
def enable():
listener = LocationListener.get()
listener.start()
def disable():
listener = LocationListener.get()
listener.shut_down()
......@@ -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:
......@@ -1300,7 +1294,7 @@ class ConversationTextview(GObject.GObject):
self.last_time_printout = tim
if app.config.get('print_time_fuzzy') > 0:
tim_format = self.fc.fuzzy_time(
app.config.get('print_time_fuzzy'), tim)
app.config.get('print_time_fuzzy'), local_tim)
else:
tim_format = self.get_time_to_show(local_tim, direction_mark)
buffer_.insert_with_tags_by_name(iter_, tim_format + '\n',
......@@ -1353,11 +1347,13 @@ class ConversationTextview(GObject.GObject):
buffer_.insert(end_iter, subject)
self.print_empty_line(end_iter)
def print_real_text(self, text, text_tags=[], name=None, xhtml=None,
def print_real_text(self, text, text_tags=None, name=None, xhtml=None,
graphics=True, mark=None, additional_data=None):
"""
Add normal and special text. call this to add text
"""
if text_tags is None:
text_tags = []
if additional_data is None:
additional_data = {}
buffer_ = self.tv.get_buffer()
......
......@@ -28,15 +28,6 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="start_chat_menuitem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_Start Chat...</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="join_group_chat_menuitem">
<property name="visible">True</property>
......
......@@ -72,6 +72,11 @@
<attribute name="action">app.accounts</attribute>
<attribute name="accel">&lt;Primary&gt;&lt;Shift&gt;A</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Start Chat</attribute>
<attribute name="action">app.start-chat</attribute>
<attribute name="accel">&lt;Primary&gt;N</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Bookmarks</attribute>
<attribute name="action">app.bookmarks</attribute>
......
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">18</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="is_focus">True</property>
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="listbox">
<property name="name">StartChatListBox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">browse</property>
<property name="activate_on_single_click">False</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</interface>
......@@ -86,4 +86,16 @@ popover#EmoticonPopover flowboxchild { padding-top: 5px; padding-bottom: 5px; }
background-color: @theme_unfocused_bg_color;
color: @theme_text_color; }
/* StartChatListBox */
#StartChatListBox > row { border-bottom: 1px solid; border-color: @theme_unfocused_bg_color; }
#StartChatListBox > row:last-child { border-bottom: 0px}
#StartChatListBox > row.activatable:active { box-shadow: none; }
#StartChatListBox > row { padding: 10px 20px 10px 10px; }
#StartChatListBox > row:not(.activatable) label { color: @insensitive_fg_color }
/* Text style */
.bold16 { font-size: 16px; font-weight: bold; }
.status-away { color: #ff8533;}
.status-dnd { color: #e62e00;}
.status-online { color: #66bf10;}
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()
......
......@@ -53,14 +53,15 @@ from gajim.common import i18n
from gajim.common import logging_helpers
from gajim.common import crypto
MIN_NBXMPP_VER = "0.6.0"
MIN_NBXMPP_VER = "0.6.1"