9578053 Jan 22 2022 distfiles.gentoo.org/distfiles/gajim-1.3.3-2.tar.gz
This commit is contained in:
parent
a5b3822651
commit
4c1b226bff
1045 changed files with 753037 additions and 18 deletions
286
gajim/gtk/groupchat_info.py
Normal file
286
gajim/gtk/groupchat_info.py
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
# 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 GLib
|
||||
from gi.repository import Gtk
|
||||
|
||||
from nbxmpp.namespaces import Namespace
|
||||
|
||||
from gajim.common import app
|
||||
from gajim.common.i18n import _
|
||||
from gajim.common.i18n import Q_
|
||||
from gajim.common.helpers import open_uri
|
||||
from gajim.common.helpers import get_groupchat_name
|
||||
from gajim.common.const import RFC5646_LANGUAGE_TAGS
|
||||
from gajim.common.const import AvatarSize
|
||||
|
||||
from .util import get_builder
|
||||
from .util import make_href_markup
|
||||
|
||||
|
||||
MUC_FEATURES = {
|
||||
'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_nonanonymous': (
|
||||
'feather-shield-off-symbolic',
|
||||
Q_('?Group chat feature:Not Anonymous'),
|
||||
_('All other group chat participants '
|
||||
'can see your XMPP address')),
|
||||
'muc_semianonymous': (
|
||||
'feather-shield-symbolic',
|
||||
Q_('?Group chat feature:Semi-Anonymous'),
|
||||
_('Only moderators can see your XMPP address')),
|
||||
'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 are '
|
||||
'allowed to send messages')),
|
||||
'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_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')),
|
||||
'muc_persistent': (
|
||||
'feather-hard-drive-symbolic',
|
||||
Q_('?Group chat feature:Persistent'),
|
||||
_('This group chat persists '
|
||||
'even if there are no participants')),
|
||||
'muc_temporary': (
|
||||
'feather-clock-symbolic',
|
||||
Q_('?Group chat feature:Temporary'),
|
||||
_('This group chat will be destroyed '
|
||||
'once the last participant left')),
|
||||
'mam': (
|
||||
'feather-server-symbolic',
|
||||
Q_('?Group chat feature:Archiving'),
|
||||
_('Messages are archived on the server')),
|
||||
}
|
||||
|
||||
|
||||
class GroupChatInfoScrolled(Gtk.ScrolledWindow):
|
||||
def __init__(self, account=None, options=None):
|
||||
Gtk.ScrolledWindow.__init__(self)
|
||||
if options is None:
|
||||
options = {}
|
||||
|
||||
self._minimal = options.get('minimal', False)
|
||||
|
||||
self.set_size_request(options.get('width', 400), -1)
|
||||
self.set_halign(Gtk.Align.CENTER)
|
||||
|
||||
if self._minimal:
|
||||
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
|
||||
else:
|
||||
self.set_vexpand(True)
|
||||
self.set_min_content_height(400)
|
||||
self.set_policy(Gtk.PolicyType.NEVER,
|
||||
Gtk.PolicyType.AUTOMATIC)
|
||||
|
||||
self._account = account
|
||||
self._info = None
|
||||
|
||||
self._ui = get_builder('groupchat_info_scrolled.ui')
|
||||
self.add(self._ui.info_grid)
|
||||
self._ui.connect_signals(self)
|
||||
self.show_all()
|
||||
|
||||
def get_account(self):
|
||||
return self._account
|
||||
|
||||
def set_account(self, account):
|
||||
self._account = account
|
||||
|
||||
def get_jid(self):
|
||||
return self._info.jid
|
||||
|
||||
def set_author(self, author, epoch_timestamp=None):
|
||||
has_author = bool(author)
|
||||
if has_author and epoch_timestamp is not None:
|
||||
time_ = time.strftime('%c', time.localtime(epoch_timestamp))
|
||||
author = f'{author} - {time_}'
|
||||
|
||||
self._ui.author.set_text(author or '')
|
||||
self._ui.author.set_visible(has_author)
|
||||
self._ui.author_label.set_visible(has_author)
|
||||
|
||||
def set_subject(self, subject):
|
||||
has_subject = bool(subject)
|
||||
subject = GLib.markup_escape_text(subject or '')
|
||||
self._ui.subject.set_markup(make_href_markup(subject))
|
||||
self._ui.subject.set_visible(has_subject)
|
||||
self._ui.subject_label.set_visible(has_subject)
|
||||
|
||||
def set_from_disco_info(self, info):
|
||||
self._info = info
|
||||
# Set name
|
||||
if self._account is None:
|
||||
name = info.muc_name
|
||||
else:
|
||||
con = app.connections[self._account]
|
||||
name = get_groupchat_name(con, info.jid)
|
||||
self._ui.name.set_text(name)
|
||||
self._ui.name.set_visible(True)
|
||||
|
||||
# Set avatar
|
||||
surface = app.interface.avatar_storage.get_muc_surface(
|
||||
self._account,
|
||||
str(info.jid),
|
||||
AvatarSize.GROUP_INFO,
|
||||
self.get_scale_factor())
|
||||
self._ui.avatar_image.set_from_surface(surface)
|
||||
|
||||
# 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 address
|
||||
self._ui.address.set_text(str(info.jid))
|
||||
|
||||
if self._minimal:
|
||||
return
|
||||
|
||||
# Set subject
|
||||
self.set_subject(info.muc_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 contacts
|
||||
self._ui.contact_box.foreach(self._ui.contact_box.remove)
|
||||
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
|
||||
for row in range(30, 9, -1):
|
||||
# Remove everything from row 30 to 10
|
||||
# We probably will never have 30 rows and
|
||||
# there is no method to count grid rows
|
||||
grid.remove_row(row)
|
||||
features = list(features)
|
||||
|
||||
if Namespace.MAM_2 in features:
|
||||
features.append('mam')
|
||||
|
||||
row = 10
|
||||
|
||||
for feature in MUC_FEATURES:
|
||||
if 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()
|
||||
|
||||
def _on_copy_address(self, _button):
|
||||
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
|
||||
clipboard.set_text(f'xmpp:{self._info.jid}?join', -1)
|
||||
|
||||
@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(f'xmpp:{button.get_uri()}?message', account=self._account)
|
||||
return Gdk.EVENT_STOP
|
||||
|
||||
@staticmethod
|
||||
def _on_activate_subject_link(_label, uri):
|
||||
# We have to use this, because the default GTK handler
|
||||
# is not cross-platform compatible
|
||||
open_uri(uri)
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue