Commit 84f3c023 authored by Philipp Hörist's avatar Philipp Hörist

Add new group chat join dialog

parent 776b9b3d
Pipeline #3896 passed with stages
in 2 minutes and 55 seconds
......@@ -46,6 +46,7 @@ from gajim.gtk.proxies import ManageProxies
from gajim.gtk.discovery import ServiceDiscoveryWindow
from gajim.gtk.blocking import BlockingList
from gajim.gtk.xml_console import XMLConsoleWindow
from gajim.gtk.groupchat_join import GroupchatJoin
# General Actions
......@@ -395,3 +396,12 @@ def on_browse_history(_action, param):
window.present()
if jid is not None and account is not None:
window.open_history(jid, account)
def on_groupchat_join(_action, param):
account, jid = param.get_strv()
window = app.get_app_window(GroupchatJoin, account=account, jid=jid)
if window is None:
GroupchatJoin(account, jid)
else:
window.present()
......@@ -437,6 +437,11 @@ class GajimApplication(Gtk.Application):
act.connect("activate", app_actions.on_browse_history)
self.add_action(act)
act = Gio.SimpleAction.new('groupchat-join',
GLib.VariantType.new('as'))
act.connect("activate", app_actions.on_groupchat_join)
self.add_action(act)
for action in general_actions:
action_name, func = action
act = Gio.SimpleAction.new(action_name, None)
......
......@@ -229,6 +229,17 @@ MUC_CREATION_EXAMPLES = [
]
MUC_DISCO_ERRORS = {
'remote-server-not-found': _('Remote server not found'),
'remote-server-timeout': _('Remote server timeout'),
'service-unavailable': _('Address does not belong to a group chat server'),
'subscription-required': _('Address does not belong to a group chat server'),
'not-muc-service': _('Address does not belong to a group chat server'),
'already-exists': _('Group chat already exists'),
'item-not-found': _('Group chat does not exist'),
}
EME_MESSAGES = {
'urn:xmpp:otr:0':
_('This message was encrypted with OTR '
......@@ -563,3 +574,239 @@ Travis Shirk (travis AT pobox.com)
Brendan Taylor (whateley AT gmail.com)
Jean-Marie Traissard (jim AT lapin.org)
""".strip().split("\n")
RFC5646_LANGUAGE_TAGS = {
'af': 'Afrikaans',
'af-ZA': 'Afrikaans (South Africa)',
'ar': 'Arabic',
'ar-AE': 'Arabic (U.A.E.)',
'ar-BH': 'Arabic (Bahrain)',
'ar-DZ': 'Arabic (Algeria)',
'ar-EG': 'Arabic (Egypt)',
'ar-IQ': 'Arabic (Iraq)',
'ar-JO': 'Arabic (Jordan)',
'ar-KW': 'Arabic (Kuwait)',
'ar-LB': 'Arabic (Lebanon)',
'ar-LY': 'Arabic (Libya)',
'ar-MA': 'Arabic (Morocco)',
'ar-OM': 'Arabic (Oman)',
'ar-QA': 'Arabic (Qatar)',
'ar-SA': 'Arabic (Saudi Arabia)',
'ar-SY': 'Arabic (Syria)',
'ar-TN': 'Arabic (Tunisia)',
'ar-YE': 'Arabic (Yemen)',
'az': 'Azeri (Latin)',
'az-AZ': 'Azeri (Latin) (Azerbaijan)',
'az-Cyrl-AZ': 'Azeri (Cyrillic) (Azerbaijan)',
'be': 'Belarusian',
'be-BY': 'Belarusian (Belarus)',
'bg': 'Bulgarian',
'bg-BG': 'Bulgarian (Bulgaria)',
'bs-BA': 'Bosnian (Bosnia and Herzegovina)',
'ca': 'Catalan',
'ca-ES': 'Catalan (Spain)',
'cs': 'Czech',
'cs-CZ': 'Czech (Czech Republic)',
'cy': 'Welsh',
'cy-GB': 'Welsh (United Kingdom)',
'da': 'Danish',
'da-DK': 'Danish (Denmark)',
'de': 'German',
'de-AT': 'German (Austria)',
'de-CH': 'German (Switzerland)',
'de-DE': 'German (Germany)',
'de-LI': 'German (Liechtenstein)',
'de-LU': 'German (Luxembourg)',
'dv': 'Divehi',
'dv-MV': 'Divehi (Maldives)',
'el': 'Greek',
'el-GR': 'Greek (Greece)',
'en': 'English',
'en-AU': 'English (Australia)',
'en-BZ': 'English (Belize)',
'en-CA': 'English (Canada)',
'en-CB': 'English (Caribbean)',
'en-GB': 'English (United Kingdom)',
'en-IE': 'English (Ireland)',
'en-JM': 'English (Jamaica)',
'en-NZ': 'English (New Zealand)',
'en-PH': 'English (Republic of the Philippines)',
'en-TT': 'English (Trinidad and Tobago)',
'en-US': 'English (United States)',
'en-ZA': 'English (South Africa)',
'en-ZW': 'English (Zimbabwe)',
'eo': 'Esperanto',
'es': 'Spanish',
'es-AR': 'Spanish (Argentina)',
'es-BO': 'Spanish (Bolivia)',
'es-CL': 'Spanish (Chile)',
'es-CO': 'Spanish (Colombia)',
'es-CR': 'Spanish (Costa Rica)',
'es-DO': 'Spanish (Dominican Republic)',
'es-EC': 'Spanish (Ecuador)',
'es-ES': 'Spanish (Spain)',
'es-GT': 'Spanish (Guatemala)',
'es-HN': 'Spanish (Honduras)',
'es-MX': 'Spanish (Mexico)',
'es-NI': 'Spanish (Nicaragua)',
'es-PA': 'Spanish (Panama)',
'es-PE': 'Spanish (Peru)',
'es-PR': 'Spanish (Puerto Rico)',
'es-PY': 'Spanish (Paraguay)',
'es-SV': 'Spanish (El Salvador)',
'es-UY': 'Spanish (Uruguay)',
'es-VE': 'Spanish (Venezuela)',
'et': 'Estonian',
'et-EE': 'Estonian (Estonia)',
'eu': 'Basque',
'eu-ES': 'Basque (Spain)',
'fa': 'Farsi',
'fa-IR': 'Farsi (Iran)',
'fi': 'Finnish',
'fi-FI': 'Finnish (Finland)',
'fo': 'Faroese',
'fo-FO': 'Faroese (Faroe Islands)',
'fr': 'French',
'fr-BE': 'French (Belgium)',
'fr-CA': 'French (Canada)',
'fr-CH': 'French (Switzerland)',
'fr-FR': 'French (France)',
'fr-LU': 'French (Luxembourg)',
'fr-MC': 'French (Principality of Monaco)',
'gl': 'Galician',
'gl-ES': 'Galician (Spain)',
'gu': 'Gujarati',
'gu-IN': 'Gujarati (India)',
'he': 'Hebrew',
'he-IL': 'Hebrew (Israel)',
'hi': 'Hindi',
'hi-IN': 'Hindi (India)',
'hr': 'Croatian',
'hr-BA': 'Croatian (Bosnia and Herzegovina)',
'hr-HR': 'Croatian (Croatia)',
'hu': 'Hungarian',
'hu-HU': 'Hungarian (Hungary)',
'hy': 'Armenian',
'hy-AM': 'Armenian (Armenia)',
'id': 'Indonesian',
'id-ID': 'Indonesian (Indonesia)',
'is': 'Icelandic',
'is-IS': 'Icelandic (Iceland)',
'it': 'Italian',
'it-CH': 'Italian (Switzerland)',
'it-IT': 'Italian (Italy)',
'ja': 'Japanese',
'ja-JP': 'Japanese (Japan)',
'ka': 'Georgian',
'ka-GE': 'Georgian (Georgia)',
'kk': 'Kazakh',
'kk-KZ': 'Kazakh (Kazakhstan)',
'kn': 'Kannada',
'kn-IN': 'Kannada (India)',
'ko': 'Korean',
'ko-KR': 'Korean (Korea)',
'kok': 'Konkani',
'kok-IN': 'Konkani (India)',
'ky': 'Kyrgyz',
'ky-KG': 'Kyrgyz (Kyrgyzstan)',
'lt': 'Lithuanian',
'lt-LT': 'Lithuanian (Lithuania)',
'lv': 'Latvian',
'lv-LV': 'Latvian (Latvia)',
'mi': 'Maori',
'mi-NZ': 'Maori (New Zealand)',
'mk': 'FYRO Macedonian',
'mk-MK': 'FYRO Macedonian (Former Yugoslav Republic of Macedonia)',
'mn': 'Mongolian',
'mn-MN': 'Mongolian (Mongolia)',
'mr': 'Marathi',
'mr-IN': 'Marathi (India)',
'ms': 'Malay',
'ms-BN': 'Malay (Brunei Darussalam)',
'ms-MY': 'Malay (Malaysia)',
'mt': 'Maltese',
'mt-MT': 'Maltese (Malta)',
'nb': 'Norwegian (Bokm?l)',
'nb-NO': 'Norwegian (Bokm?l) (Norway)',
'nl': 'Dutch',
'nl-BE': 'Dutch (Belgium)',
'nl-NL': 'Dutch (Netherlands)',
'nn-NO': 'Norwegian (Nynorsk) (Norway)',
'ns': 'Northern Sotho',
'ns-ZA': 'Northern Sotho (South Africa)',
'pa': 'Punjabi',
'pa-IN': 'Punjabi (India)',
'pl': 'Polish',
'pl-PL': 'Polish (Poland)',
'ps': 'Pashto',
'ps-AR': 'Pashto (Afghanistan)',
'pt': 'Portuguese',
'pt-BR': 'Portuguese (Brazil)',
'pt-PT': 'Portuguese (Portugal)',
'qu': 'Quechua',
'qu-BO': 'Quechua (Bolivia)',
'qu-EC': 'Quechua (Ecuador)',
'qu-PE': 'Quechua (Peru)',
'ro': 'Romanian',
'ro-RO': 'Romanian (Romania)',
'ru': 'Russian',
'ru-RU': 'Russian (Russia)',
'sa': 'Sanskrit',
'sa-IN': 'Sanskrit (India)',
'se': 'Sami',
'se-FI': 'Sami (Finland)',
'se-NO': 'Sami (Norway)',
'se-SE': 'Sami (Sweden)',
'sk': 'Slovak',
'sk-SK': 'Slovak (Slovakia)',
'sl': 'Slovenian',
'sl-SI': 'Slovenian (Slovenia)',
'sq': 'Albanian',
'sq-AL': 'Albanian (Albania)',
'sr-BA': 'Serbian (Latin) (Bosnia and Herzegovina)',
'sr-Cyrl-BA': 'Serbian (Cyrillic) (Bosnia and Herzegovina)',
'sr-SP': 'Serbian (Latin) (Serbia and Montenegro)',
'sr-Cyrl-SP': 'Serbian (Cyrillic) (Serbia and Montenegro)',
'sv': 'Swedish',
'sv-FI': 'Swedish (Finland)',
'sv-SE': 'Swedish (Sweden)',
'sw': 'Swahili',
'sw-KE': 'Swahili (Kenya)',
'syr': 'Syriac',
'syr-SY': 'Syriac (Syria)',
'ta': 'Tamil',
'ta-IN': 'Tamil (India)',
'te': 'Telugu',
'te-IN': 'Telugu (India)',
'th': 'Thai',
'th-TH': 'Thai (Thailand)',
'tl': 'Tagalog',
'tl-PH': 'Tagalog (Philippines)',
'tn': 'Tswana',
'tn-ZA': 'Tswana (South Africa)',
'tr': 'Turkish',
'tr-TR': 'Turkish (Turkey)',
'tt': 'Tatar',
'tt-RU': 'Tatar (Russia)',
'ts': 'Tsonga',
'uk': 'Ukrainian',
'uk-UA': 'Ukrainian (Ukraine)',
'ur': 'Urdu',
'ur-PK': 'Urdu (Islamic Republic of Pakistan)',
'uz': 'Uzbek (Latin)',
'uz-UZ': 'Uzbek (Latin) (Uzbekistan)',
'uz-Cyrl-UZ': 'Uzbek (Cyrillic) (Uzbekistan)',
'vi': 'Vietnamese',
'vi-VN': 'Vietnamese (Viet Nam)',
'xh': 'Xhosa',
'xh-ZA': 'Xhosa (South Africa)',
'zh': 'Chinese',
'zh-CN': 'Chinese (S)',
'zh-HK': 'Chinese (Hong Kong)',
'zh-MO': 'Chinese (Macau)',
'zh-SG': 'Chinese (Singapore)',
'zh-TW': 'Chinese (T)',
'zu': 'Zulu',
'zu-ZA': 'Zulu (South Africa)'
}
......@@ -1542,7 +1542,9 @@ def open_uri(uri, account=None):
return
if uri.action == URIAction.JOIN:
app.interface.join_gc_minimal(account, uri.data)
app.app.activate_action(
'groupchat-join',
GLib.Variant('as', [account, uri.data['jid']]))
elif uri.action == URIAction.MESSAGE:
app.interface.new_chat_from_jid(account, uri.data['jid'],
message=uri.data.get('body'))
......
This diff is collapsed.
The MIT License (MIT)
Copyright (c) 2013-2017 Cole Bemis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
The MIT License (MIT)
Copyright (c) 2013-2017 Cole Bemis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye-off"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-globe"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-hard-drive"><line x1="22" y1="12" x2="2" y2="12"></line><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><line x1="6" y1="16" x2="6" y2="16"></line><line x1="10" y1="16" x2="10" y2="16"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="square" stroke-linejoin="arcs"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-mic-off"><line x1="1" y1="1" x2="23" y2="23"></line><path d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"></path><path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-mic"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-server"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6" y2="6"></line><line x1="6" y1="18" x2="6" y2="18"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield-off"><path d="M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18"></path><path d="M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38"></path><line x1="1" y1="1" x2="23" y2="23"></line></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shield"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2.5" stroke-linecap="square" stroke-linejoin="arcs"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user-check"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><polyline points="17 11 19 13 23 9"></polyline></svg>
\ No newline at end of file
......@@ -45,6 +45,8 @@
#SubjectPopover box { padding: 10px; }
.link-button { min-height: 0px }
/* VCardWindow */
.VCard-GtkLinkButton { padding-left: 5px; border-left: none; }
......@@ -263,3 +265,6 @@ button.flat.link { padding: 0; border: 0; }
/* Search Dialog */
.search-treeview { padding: 5px; }
.search-scrolled { border: 1px solid; border-color:@unfocused_borders; }
#GroupchatJoin > box {padding: 18px; }
\ No newline at end of file
# 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 time
from gi.repository import Gdk
from gi.repository import Gtk
from nbxmpp.protocol import NS_MAM_1
from nbxmpp.protocol import NS_MAM_2
from gajim.common.i18n import _
from gajim.common.i18n import Q_
from gajim.common.helpers import open_uri
from gajim.common.const import RFC5646_LANGUAGE_TAGS
from gajim.gtk.util import get_builder
MUC_FEATURES = {
'mam': (
'feather-server-symbolic',
Q_('?Group chat feature:Archiving'),
_('Messages are archived on the server')),
'muc_persistent': (
'feather-hard-drive-symbolic',
Q_('?Group chat feature:Persistent'),
_('This group chat persists '
'even if it\'s unoccupied')),
'muc_temporary': (
'feather-clock-symbolic',
Q_('?Group chat feature:Temporary'),
_('This group chat will be destroyed '
'once the last occupant left')),
'muc_moderated': (
'feather-mic-off-symbolic',
Q_('?Group chat feature:Moderated'),
_('Participants entering this group chat need '
'to request permission to send messages')),
'muc_unmoderated': (
'feather-mic-symbolic',
Q_('?Group chat feature:Not Moderated'),
_('Participants entering this group chat can '
'write messages to all participants')),
'muc_open': (
'feather-globe-symbolic',
Q_('?Group chat feature:Open'),
_('Anyone can join this group chat')),
'muc_membersonly': (
'feather-user-check-symbolic',
Q_('?Group chat feature:Members Only'),
_('This group chat is restricted '
'to members only')),
'muc_public': (
'feather-eye-symbolic',
Q_('?Group chat feature:Public'),
_('Group chat can be found via search')),
'muc_hidden': (
'feather-eye-off-symbolic',
Q_('?Group chat feature:Hidden'),
_('This group chat can not be found via search')),
'muc_nonanonymous': (
'feather-shield-off-symbolic',
Q_('?Group chat feature:Not Anonymous'),
_('All other group chat occupants '
'can see your XMPP address')),
'muc_semianonymous': (
'feather-shield-symbolic',
Q_('?Group chat feature:Semi-Anonymous'),
_('Only moderators can see your XMPP address')),
'muc_passwordprotected': (
'feather-lock-symbolic',
Q_('?Group chat feature:Password Required'),
_('This group chat '
'does require a password upon entry')),
'muc_unsecured': (
'feather-unlock-symbolic',
Q_('?Group chat feature:No Password Required'),
_('This group chat does not require '
'a password upon entry')),
}
class GroupChatInfoScrolled(Gtk.ScrolledWindow):
def __init__(self, account):
Gtk.ScrolledWindow.__init__(self)
self.set_size_request(400, -1)
self.set_min_content_height(400)
self.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC)
self._account = account
self._ui = get_builder('groupchat_info_scrolled.ui')
self.add(self._ui.info_grid)
self._ui.connect_signals(self)
self.show_all()
def set_author(self, author, epoch_timestamp=None):
if not author:
return
if epoch_timestamp is not None:
time_ = time.strftime('%c', time.localtime(epoch_timestamp))
author = '{} - {}'.format(author, time_)
self._ui.author.set_text(author)
self._ui.author.set_visible(True)
self._ui.author_label.set_visible(True)
def set_subject(self, subject):
if not subject:
return
self._ui.subject.set_text(subject)
self._ui.subject.set_visible(True)
self._ui.subject_label.set_visible(True)
def set_from_disco_info(self, info):
# Set name
has_name = bool(info.muc_name)
self._ui.name.set_text(info.muc_name or '')
self._ui.name.set_visible(has_name)
self._ui.name_label.set_visible(has_name)
# Set description
has_desc = bool(info.muc_description)
self._ui.description.set_text(info.muc_description or '')
self._ui.description.set_visible(has_desc)
self._ui.description_label.set_visible(has_desc)
# Set subject
has_subject = bool(info.muc_subject)
self._ui.subject.set_text(info.muc_subject or '')
self._ui.subject.set_visible(has_subject)
self._ui.subject_label.set_visible(has_subject)
# Set user
has_users = info.muc_users is not None
self._ui.users.set_text(info.muc_users or '')
self._ui.users.set_visible(has_users)
self._ui.users_image.set_visible(has_users)
# Set address
self._ui.address.set_text(str(info.jid))
# Set contacts
has_contacts = bool(info.muc_contacts)
if has_contacts:
for contact in info.muc_contacts:
self._ui.contact_box.add(self._get_contact_button(contact))
self._ui.contact_box.set_visible(has_contacts)
self._ui.contact_label.set_visible(has_contacts)
# Set discussion logs
has_log_uri = bool(info.muc_log_uri)
self._ui.logs.set_uri(info.muc_log_uri or '')
self._ui.logs.set_label('Website')
self._ui.logs.set_visible(has_log_uri)
self._ui.logs_label.set_visible(has_log_uri)
# Set room language
has_lang = bool(info.muc_lang)
lang = ''
if has_lang:
lang = RFC5646_LANGUAGE_TAGS.get(info.muc_lang, info.muc_lang)
self._ui.lang.set_text(lang)
self._ui.lang.set_visible(has_lang)
self._ui.lang_image.set_visible(has_lang)
self._add_features(info.features)
def _add_features(self, features):
grid = self._ui.info_grid
features = list(features)
has_mam = NS_MAM_2 in features or NS_MAM_1 in features
if has_mam:
features.append('mam')
row = 10
for feature in features:
icon, name, tooltip = MUC_FEATURES.get(feature, (None, None, None))
if icon is None:
continue
grid.attach(self._get_feature_icon(icon, tooltip), 0, row, 1, 1)
grid.attach(self._get_feature_label(name), 1, row, 1, 1)
row += 1
grid.show_all()
@staticmethod
def _on_activate_log_link(button):
open_uri(button.get_uri())
return Gdk.EVENT_STOP
def _on_activate_contact_link(self, button):
open_uri('xmpp:%s?message' % button.get_uri(), account=self._account)
return Gdk.EVENT_STOP
@staticmethod
def _get_feature_icon(icon, tooltip):
image = Gtk.Image.new_from_icon_name(icon, Gtk.IconSize.MENU)
image.set_valign(Gtk.Align.CENTER)
image.set_halign(Gtk.Align.END)
image.set_tooltip_text(tooltip)
return image
@staticmethod
def _get_feature_label(text):
label = Gtk.Label(label=text, use_markup=True)
label.set_halign(Gtk.Align.START)
label.set_valign(Gtk.Align.START)
return label
def _get_contact_button(self, contact):
button = Gtk.LinkButton.new(contact)
button.set_halign(Gtk.Align.START)
button.get_style_context().add_class('link-button')
button.connect('activate-link', self._on_activate_contact_link)
button.show()
return button
# 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/>.
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Pango
from nbxmpp.util import is_error_result
from gajim.common import app
from gajim.common.i18n import _
from gajim.common.const import MUC_DISCO_ERRORS
from gajim.gtk.groupchat_info import GroupChatInfoScrolled
from gajim.gtk.util import ensure_not_destroyed
class GroupchatJoin(Gtk.ApplicationWindow):
def __init__(self, account, jid):
Gtk.ApplicationWindow.__init__(self)
self.set_name('GroupchatJoin')
self.set_application(app.app)
self.set_position(Gtk.WindowPosition.CENTER)
self.set_show_menubar(False)
self.set_title(_('Join Group Chat'))