Philipp Hörist pushed to branch master at gajim / gajim
Commits: 88f30f92 by Philipp Hörist at 2018-10-28T16:29:12Z Move SearchWindow to gtk folder
- - - - - efbd2272 by Philipp Hörist at 2018-10-28T18:34:46Z DiscoveryWindow: Use icon name instead of pixbufs
- - - - - cb58fc86 by Philipp Hörist at 2018-10-28T18:38:35Z Move GroupsPostWindow into disco module
- - - - - 59ccac48 by Philipp Hörist at 2018-10-28T18:41:19Z Move ServiceDiscoveryWindow to gtk folder
- - - - - f4a7e2a3 by Philipp Hörist at 2018-10-28T18:45:10Z Move AtomWindow to gtk folder
- - - - - dcfaba09 by Philipp Hörist at 2018-10-28T19:17:59Z PluginsWindow: Refactor code
- Use get_builder - Sort imports - Use load_icon instead of get_icon_pixmap
- - - - - 9ae63b6f by Philipp Hörist at 2018-10-28T19:18:33Z FiletransferWindow: Use icon name instead of pixbufs
- - - - - cdeb902f by Philipp Hörist at 2018-10-28T19:20:49Z FiletransferWindow: Move to gtk module
- - - - - 95e67ab7 by Philipp Hörist at 2018-10-28T19:43:36Z AdHocCommands: move to gtk module
- - - - - 69309d28 by Philipp Hörist at 2018-10-28T19:58:32Z AccountWizard: Use icon name instead of filename
- - - - - 2a0d6dc1 by Philipp Hörist at 2018-10-28T20:26:25Z Use json format for the servers list
- - - - - 5769ca1e by Philipp Hörist at 2018-10-28T20:45:04Z Remove dead servers from servers list
All removed servers did not answer to a IBR request
- - - - - ac3bc749 by Philipp Hörist at 2018-10-28T20:58:30Z Remove unused methods
- - - - -
19 changed files:
- gajim/app_actions.py - gajim/chat_control_base.py - gajim/common/helpers.py - + gajim/data/other/servers.json - − gajim/data/other/servers.xml - gajim/groupchat_control.py - − gajim/groups.py - gajim/gtk/account_wizard.py - gajim/adhoc_commands.py → gajim/gtk/adhoc_commands.py - gajim/atom_window.py → gajim/gtk/atom.py - gajim/disco.py → gajim/gtk/discovery.py - gajim/search_window.py → gajim/gtk/discovery_search.py - gajim/filetransfers_window.py → gajim/gtk/filetransfer.py - gajim/gtk/util.py - gajim/gtkgui_helpers.py - gajim/gui_interface.py - gajim/message_textview.py - gajim/plugins/gui.py - gajim/roster_window.py
Changes:
===================================== gajim/app_actions.py ===================================== @@ -22,7 +22,6 @@ from gajim.common import helpers from gajim.common.app import interface from gajim.common.exceptions import GajimGeneralException from gajim import dialogs -from gajim import disco
import gajim.plugins.gui
@@ -44,6 +43,7 @@ from gajim.gtk.account_wizard import AccountCreationWizard from gajim.gtk.history import HistoryWindow from gajim.gtk.accounts import AccountsWindow from gajim.gtk.proxies import ManageProxies +from gajim.gtk.discovery import ServiceDiscoveryWindow
# General Actions @@ -130,7 +130,7 @@ def on_service_disco(action, param): else: try: # Object will add itself to the window dict - disco.ServiceDiscoveryWindow(account, address_entry=True) + ServiceDiscoveryWindow(account, address_entry=True) except GajimGeneralException: pass
===================================== gajim/chat_control_base.py ===================================== @@ -52,7 +52,9 @@ from gajim.conversation_textview import ConversationTextview from gajim.message_textview import MessageTextView
from gajim.gtk.dialogs import NonModalConfirmationDialog +from gajim.gtk import util from gajim.gtk.util import convert_rgb_to_hex +from gajim.gtk.util import at_the_end from gajim.gtk.emoji_chooser import emoji_chooser
from gajim.command_system.implementation.middleware import ChatCommandProcessor @@ -708,7 +710,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): mark = message_buffer.get_insert() iter_ = message_buffer.get_iter_at_mark(mark) if message_buffer.get_end_iter().equal(iter_): - GLib.idle_add(gtkgui_helpers.scroll_to_end, self.msg_scrolledwindow) + GLib.idle_add(util.scroll_to_end, self.msg_scrolledwindow)
return True elif event.keyval == Gdk.KEY_z: # CTRL+z @@ -1192,7 +1194,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): if event.get_button()[1] != 1: # We want only to catch the left mouse button return - if not gtkgui_helpers.at_the_end(scrollbar.get_parent()): + if not at_the_end(scrollbar.get_parent()): app.log('autoscroll').info('Autoscroll disabled') self.conv_textview.autoscroll = False
===================================== gajim/common/helpers.py ===================================== @@ -39,6 +39,7 @@ import shlex import socket import time import logging +import json from datetime import datetime, timedelta from distutils.version import LooseVersion as V from encodings.punycode import punycode_encode @@ -1492,3 +1493,15 @@ def get_sync_threshold(jid, archive_info): app.logger.set_archive_infos(jid, sync_threshold=threshold) return threshold return archive_info.sync_threshold + +def load_json(path, key=None, default=None): + try: + with open(path, 'r') as file: + json_dict = json.loads(file.read()) + except Exception: + log.exception('Parsing error') + return default + + if key is None: + return json_dict + return json_dict.get(key, default)
===================================== gajim/data/other/servers.json ===================================== @@ -0,0 +1,42 @@ +{ + "servers":[ + "0nl1ne.at", + "404.city", + "brauchen.info", + "chatme.im", + "comm.unicate.me", + "creep.im", + "deshalbfrei.org", + "draugr.de", + "im.apinc.org", + "jabber-hosting.de", + "jabber.at", + "jabber.ccc.de", + "jabber.cz", + "jabber.hot-chilli.net", + "jabber.meta.net.nz", + "jabber.no", + "jabber.sk", + "jabber.rueckgr.at", + "jabberes.org", + "jabbim.com", + "jabbim.cz", + "jabbim.pl", + "jabbim.sk", + "jabster.pl", + "lightwitch.org", + "linuxlovers.at", + "njs.netlab.cz", + "pandion.im", + "richim.org", + "suchat.org", + "tigase.im", + "ubuntu-jabber.de", + "ubuntu-jabber.net", + "verdammung.org", + "xabber.de", + "xmpp-hosting.de", + "xmpp.jp", + "zsim.de" + ] +}
===================================== gajim/data/other/servers.xml deleted ===================================== @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - This file lists the open XMPP servers registered with the XSF. - The format of this file is defined by the Service Discovery - protocol: http://xmpp.org/extensions/xep-0030.html - To add your server to the list, follow the instructions at - http://xmpp.org/services/register.shtml - --> -<query xmlns:reg="urn:xmpp:vcard:registration:1"> - <item jid="0nl1ne.at" /> - <item jid="404.city" /> - <item jid="brauchen.info" /> - <item jid="chatme.im" /> - <item jid="climm.org" /> - <item jid="comm.unicate.me" /> - <item jid="creep.im" /> - <item jid="deshalbfrei.org" /> - <item jid="draugr.de" /> - <item jid="einfachjabber.de" /> - <item jid="forumanalogue.fr" /> - <item jid="im.apinc.org" /> - <item jid="im.flosoft.biz" /> - <item jid="jabber-hosting.de" /> - <item jid="jabber.at" /> - <item jid="jabber.ccc.de" /> - <item jid="jabber.chaotic.de" /> - <item jid="jabber.co.nz" /> - <item jid="jabber.cz" /> - <item jid="jabber.earth.li" /> - <item jid="jabber.fourecks.de" /> - <item jid="jabber.hot-chilli.net" /> - <item jid="jabber.i-pobox.net" /> - <item jid="jabber.me" /> - <item jid="jabber.meta.net.nz" /> - <item jid="jabber.no" /> - <item jid="jabber.sk" /> - <item jid="jabber.org" /> - <item jid="jabber.rueckgr.at" /> - <item jid="jabber.scha.de" /> - <item jid="jabber.second-home.de" /> - <item jid="jabber.smash-net.org" /> - <item jid="jabber.sow.as" /> - <item jid="jabber.theforest.us" /> - <item jid="jabberafrica.org" /> - <item jid="jabberes.org" /> - <item jid="jabberpl.org" /> - <item jid="jabbim.com" /> - <item jid="jabbim.cz" /> - <item jid="jabbim.hu" /> - <item jid="jabbim.pl" /> - <item jid="jabbim.sk" /> - <item jid="jabster.pl" /> - <item jid="jaim.at" /> - <item jid="lightwitch.org" /> - <item jid="linuxlovers.at" /> - <item jid="lsd-25.ru" /> - <item jid="njs.netlab.cz" /> - <item jid="palita.net" /> - <item jid="pandion.im" /> - <item jid="richim.org" /> - <item jid="sss.chaoslab.ru" /> - <item jid="sternenschweif.de" /> - <item jid="suchat.org" /> - <item jid="swissjabber.ch" /> - <item jid="swissjabber.de" /> - <item jid="swissjabber.eu" /> - <item jid="swissjabber.li" /> - <item jid="swissjabber.org" /> - <item jid="tcweb.org" /> - <item jid="tekst.me" /> - <item jid="tigase.im" /> - <item jid="ubuntu-jabber.de" /> - <item jid="ubuntu-jabber.net" /> - <item jid="univers-libre.net" /> - <item jid="uprod.biz" /> - <item jid="verdammung.org" /> - <item jid="wtfismyip.com" /> - <item jid="xabber.de" /> - <item jid="xmpp-hosting.de" /> - <item jid="xmpp.jp" /> - <item jid="xmppnet.de" /> - <item jid="zsim.de" /> -</query>
===================================== gajim/groupchat_control.py ===================================== @@ -44,7 +44,6 @@ from gajim import gui_menu_builder from gajim import message_control from gajim import vcard from gajim import dataforms_widget -from gajim import adhoc_commands
from gajim.common.const import AvatarSize from gajim.common.caps_cache import muc_caps_cache @@ -76,6 +75,7 @@ from gajim.gtk.filechoosers import AvatarChooserDialog from gajim.gtk.add_contact import AddNewContactWindow from gajim.gtk.tooltips import GCTooltip from gajim.gtk.groupchat_config import GroupchatConfig +from gajim.gtk.adhoc_commands import CommandWindow from gajim.gtk.util import get_icon_name from gajim.gtk.util import get_image_from_icon_name
@@ -797,7 +797,7 @@ class GroupchatControl(ChatControlBase): """ Execute AdHoc commands on the current room """ - adhoc_commands.CommandWindow(self.account, self.room_jid) + CommandWindow(self.account, self.room_jid)
def _on_upload_avatar(self, action, param): def _on_accept(filename): @@ -2783,7 +2783,7 @@ class GroupchatControl(ChatControlBase):
def _on_execute_command_occupant(self, widget, nick): jid = self.room_jid + '/' + nick - adhoc_commands.CommandWindow(self.account, jid) + CommandWindow(self.account, jid)
def on_row_activated(self, widget, path): """
===================================== gajim/groups.py deleted ===================================== @@ -1,71 +0,0 @@ -# Copyright (C) 2006-2014 Yann Leboulanger <asterix AT lagaule.org> -# Copyright (C) 2006 Tomasz Melcer <liori AT exroot.org> -# -# 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/. - -'''Window to create new post for discussion groups service.''' - -from gajim.common import app -from nbxmpp import Node -from gajim import gtkgui_helpers - -class GroupsPostWindow: - def __init__(self, account, servicejid, groupid): - """ - Open new 'create post' window to create message for groupid on servicejid - service - """ - assert isinstance(servicejid, str) - assert isinstance(groupid, str) - - self.account = account - self.servicejid = servicejid - self.groupid = groupid - - self.xml = gtkgui_helpers.get_gtk_builder('groups_post_window.ui') - self.window = self.xml.get_object('groups_post_window') - for name in ('from_entry', 'subject_entry', 'contents_textview'): - self.__dict__[name] = self.xml.get_object(name) - - self.xml.connect_signals(self) - self.window.show_all() - - def on_cancel_button_clicked(self, w): - """ - Close window - """ - self.window.destroy() - - def on_send_button_clicked(self, w): - """ - Gather info from widgets and send it as a message - """ - # constructing item to publish... that's atom:entry element - item = Node('entry', {'xmlns':'http://www.w3.org/2005/Atom%27%7D) - author = item.addChild('author') - author.addChild('name', {}, [self.from_entry.get_text()]) - item.addChild('generator', {}, ['Gajim']) - item.addChild('title', {}, [self.subject_entry.get_text()]) - - buf = self.contents_textview.get_buffer() - item.addChild('content', {}, [buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)]) - - # publish it to node - con = app.connections[self.account] - con.get_module('PubSub').send_pb_publish( - self.servicejid, self.groupid, item, '0') - - # close the window - self.window.destroy()
===================================== gajim/gtk/account_wizard.py ===================================== @@ -54,10 +54,11 @@ class AccountCreationWizard:
self.update_proxy_list()
- # parse servers.xml - servers_xml = os.path.join( - configpaths.get('DATA'), 'other', 'servers.xml') - servers = gtkgui_helpers.parse_server_xml(servers_xml) + # parse servers.json + server_file_path = os.path.join( + configpaths.get('DATA'), 'other', 'servers.json') + servers = helpers.load_json(server_file_path, 'servers', []) + servers_model = self.xml.get_object('server_liststore') for server in servers: servers_model.append((server,)) @@ -179,10 +180,10 @@ class AccountCreationWizard: self.go_online_checkbutton.show() img = self.xml.get_object('finish_image') if self.modify: - img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG) + img.set_from_icon_name('emblem-ok-symbolic', Gtk.IconSize.DIALOG) + img.get_style_context().add_class('success-color') else: - path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48) - img.set_from_file(path_to_file) + img.set_from_icon_name('org.gajim.Gajim', Gtk.IconSize.DIALOG) self.show_vcard_checkbutton.set_active(not self.modify) self.notebook.set_current_page(6) # show finish page
===================================== gajim/adhoc_commands.py → gajim/gtk/adhoc_commands.py ===================================== @@ -29,10 +29,10 @@ from gajim.common.i18n import _ from gajim.common.modules import dataforms from gajim.common import ged
-from gajim import gtkgui_helpers from gajim import dataforms_widget
from gajim.gtk.dialogs import HigDialog +from gajim.gtk.util import get_builder
class CommandWindow: @@ -68,7 +68,7 @@ class CommandWindow: self.stage_window_delete_cb = None
# retrieving widgets from xml - self.xml = gtkgui_helpers.get_gtk_builder('adhoc_commands_window.ui') + self.xml = get_builder('adhoc_commands_window.ui') self.window = self.xml.get_object('adhoc_commands_window') self.window.connect('delete-event', self.on_adhoc_commands_window_delete_event)
===================================== gajim/atom_window.py → gajim/gtk/atom.py ===================================== @@ -27,7 +27,7 @@ from gajim.common import helpers from gajim.common import i18n from gajim.common.i18n import _
-from gajim import gtkgui_helpers +from gajim.gtk.util import get_builder
class AtomWindow: window = None @@ -57,7 +57,7 @@ class AtomWindow:
self.entry = None # the entry actually displayed
- self.xml = gtkgui_helpers.get_gtk_builder('atom_entry_window.ui') + self.xml = get_builder('atom_entry_window.ui') self.window = self.xml.get_object('atom_entry_window') for name in ('new_entry_label', 'feed_title_label', 'feed_title_eventbox', 'feed_tagline_label', 'entry_title_label',
===================================== gajim/disco.py → gajim/gtk/discovery.py ===================================== @@ -3,6 +3,7 @@ # Copyright (C) 2005-2014 Yann Leboulanger <asterix AT lagaule.org> # Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com> # Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org> +# Copyright (C) 2006 Tomasz Melcer <liori AT exroot.org> # Copyright (C) 2007 Stephan Erb <steve-e AT h3c.de> # # This file is part of Gajim. @@ -49,11 +50,6 @@ from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GdkPixbuf
-from gajim import gtkgui_helpers -from gajim import groups -from gajim import adhoc_commands -from gajim import search_window - from gajim.common import app from gajim.common.i18n import _ from gajim.common import helpers @@ -62,6 +58,10 @@ from gajim.common.const import StyleAttr from gajim.gtk.dialogs import ErrorDialog from gajim.gtk.dialogs import InformationDialog from gajim.gtk.service_registration import ServiceRegistration +from gajim.gtk.discovery_search import SearchWindow +from gajim.gtk.adhoc_commands import CommandWindow +from gajim.gtk.util import icon_exists +from gajim.gtk.util import get_builder
LABELS = { 1: _('This service has not yet responded with detailed information'), @@ -287,28 +287,19 @@ class ServicesCache: info = _agent_type_info[(cat, type_)] except KeyError: continue - filename = info[1] - if filename: + service_name = info[1] + if service_name: break else: # Loop fell through, default to unknown - filename = addr.split('.')[0] + service_name = addr.split('.')[0] quiet = True - # Use the cache if possible - if filename in _icon_cache: - return _icon_cache[filename] + # Or load it - pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-' + filename, size=32, - quiet=quiet) - if pix: - # Store in cache - _icon_cache[filename] = pix - return pix - if 'jabber' in _icon_cache: - return _icon_cache['jabber'] - pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-jabber', size=32) - _icon_cache['jabber'] = pix - return pix + icon_name = 'gajim-agent-%s' % service_name + if icon_exists(icon_name): + return icon_name + return 'gajim-agent-jabber'
def get_browser(self, identities=None, features=None): """ @@ -513,7 +504,7 @@ _('Without a connection, you can not browse available services'))
if initial_identities: self.cache._on_agent_info(jid, node, initial_identities, [], None) - self.xml = gtkgui_helpers.get_gtk_builder('service_discovery_window.ui') + self.xml = get_builder('service_discovery_window.ui') self.window = self.xml.get_object('service_discovery_window') self.services_treeview = self.xml.get_object('services_treeview') self.model = None @@ -869,8 +860,9 @@ class AgentBrowser: self.window._set_window_banner_text(self._get_agent_address(), name)
# Add an icon to the banner. - pix = self.cache.get_icon(identities, addr=self._get_agent_address()) - self.window.banner_icon.set_from_pixbuf(pix) + icon_name = self.cache.get_icon(identities, + addr=self._get_agent_address()) + self.window.banner_icon.set_from_icon_name(icon_name, Gtk.IconSize.DND) self.window.banner_icon.show()
def _clean_title(self): @@ -1138,8 +1130,9 @@ class ToplevelAgentBrowser(AgentBrowser): identity = {'category': '_jid', 'type': type_} identities.append(identity) # Set the pixmap for the row - pix = self.cache.get_icon(identities, addr=addr) - self.model.append(None, (self.jid, self.node, pix, descr, LABELS[1])) + icon_name = self.cache.get_icon(identities, addr=addr) + self.model.append(None, + (self.jid, self.node, icon_name, descr, LABELS[1])) # Grab info on the service self.cache.get_info(self.jid, self.node, self._agent_info, force=False)
@@ -1149,9 +1142,9 @@ class ToplevelAgentBrowser(AgentBrowser): """ jid = model.get_value(iter_, 0) if jid: - pix = model.get_value(iter_, 2) + icon_name = model.get_value(iter_, 2) cell.set_property('visible', True) - cell.set_property('pixbuf', pix) + cell.set_property('icon_name', icon_name) else: cell.set_property('visible', False)
@@ -1202,7 +1195,7 @@ class ToplevelAgentBrowser(AgentBrowser): # state is None on success or has a string # from LABELS on error or while fetching view = self.window.services_treeview - self.model = Gtk.TreeStore(str, str, GdkPixbuf.Pixbuf, str, str) + self.model = Gtk.TreeStore(str, str, str, str, str) self.model.set_sort_func(4, self._treemodel_sort_func) self.model.set_sort_column_id(4, Gtk.SortType.ASCENDING) view.set_model(self.model) @@ -1211,6 +1204,7 @@ class ToplevelAgentBrowser(AgentBrowser): # Icon Renderer renderer = Gtk.CellRendererPixbuf() renderer.set_property('xpad', 6) + renderer.set_property('stock-size', Gtk.IconSize.DND) col.pack_start(renderer, False) col.set_cell_data_func(renderer, self._pixbuf_renderer_data_func) # Text Renderer @@ -1299,7 +1293,7 @@ class ToplevelAgentBrowser(AgentBrowser): present() else: app.interface.instances[self.account]['search'][service] = \ - search_window.SearchWindow(self.account, service) + SearchWindow(self.account, service)
def cleanup(self): AgentBrowser.cleanup(self) @@ -1319,7 +1313,7 @@ class ToplevelAgentBrowser(AgentBrowser): return service = model[iter_][0] node = model[iter_][1] - adhoc_commands.CommandWindow(self.account, service, commandnode=node) + CommandWindow(self.account, service, commandnode=node)
def on_register_button_clicked(self, widget=None): """ @@ -1547,13 +1541,13 @@ class ToplevelAgentBrowser(AgentBrowser): else: # Put it in the 'other' category for now cat_args = ('other',) - # Set the pixmap for the row - pix = self.cache.get_icon(identities, addr=addr) + + icon_name = self.cache.get_icon(identities, addr=addr) # Put it in the right category cat = self._find_category(*cat_args) if not cat: cat = self._create_category(*cat_args) - self.model.append(cat, (jid, node, pix, descr, LABELS[1])) + self.model.append(cat, (jid, node, icon_name, descr, LABELS[1])) GLib.idle_add(self._expand_all) # Grab info on the service self.cache.get_info(jid, node, self._agent_info, force=force) @@ -1583,7 +1577,7 @@ class ToplevelAgentBrowser(AgentBrowser): self._update_progressbar()
# Search for an icon and category we can display - pix = self.cache.get_icon(identities, addr=addr) + icon_name = self.cache.get_icon(identities, addr=addr) cat, type_ = None, None for identity in identities: try: @@ -1596,7 +1590,7 @@ class ToplevelAgentBrowser(AgentBrowser): old_cat_iter = self.model.iter_parent(iter_) if not old_cat_iter or self.model.get_value(old_cat_iter, 3) == cat: # Already in the right category, just update - self.model[iter_][2] = pix + self.model[iter_][2] = icon_name self.model[iter_][3] = descr self.model[iter_][4] = None return @@ -1613,7 +1607,7 @@ class ToplevelAgentBrowser(AgentBrowser): cat_iter = self._find_category(cat, type_) if not cat_iter: cat_iter = self._create_category(cat, type_) - self.model.append(cat_iter, (jid, node, pix, descr, None)) + self.model.append(cat_iter, (jid, node, icon_name, descr, None)) self._expand_all()
def _update_error(self, iter_, jid, node): @@ -2064,7 +2058,7 @@ class DiscussionGroupsBrowser(AgentBrowser):
groupnode = model.get_value(iter_, 1) # 1 = groupnode
- groups.GroupsPostWindow(self.account, self.jid, groupnode) + GroupsPostWindow(self.account, self.jid, groupnode)
def on_subscribe_button_clicked(self, widget): """ @@ -2153,3 +2147,53 @@ class DiscussionGroupsBrowser(AgentBrowser):
# Fill the global agent type info dictionary _agent_type_info = _gen_agent_type_info() + + +class GroupsPostWindow: + def __init__(self, account, servicejid, groupid): + """ + Open new 'create post' window to create message for groupid on servicejid + service + """ + assert isinstance(servicejid, str) + assert isinstance(groupid, str) + + self.account = account + self.servicejid = servicejid + self.groupid = groupid + + self.xml = get_builder('groups_post_window.ui') + self.window = self.xml.get_object('groups_post_window') + for name in ('from_entry', 'subject_entry', 'contents_textview'): + self.__dict__[name] = self.xml.get_object(name) + + self.xml.connect_signals(self) + self.window.show_all() + + def on_cancel_button_clicked(self, w): + """ + Close window + """ + self.window.destroy() + + def on_send_button_clicked(self, w): + """ + Gather info from widgets and send it as a message + """ + # constructing item to publish... that's atom:entry element + item = nbxmpp.Node('entry', {'xmlns':'http://www.w3.org/2005/Atom%27%7D) + author = item.addChild('author') + author.addChild('name', {}, [self.from_entry.get_text()]) + item.addChild('generator', {}, ['Gajim']) + item.addChild('title', {}, [self.subject_entry.get_text()]) + + buf = self.contents_textview.get_buffer() + item.addChild('content', {}, [buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)]) + + # publish it to node + con = app.connections[self.account] + con.get_module('PubSub').send_pb_publish( + self.servicejid, self.groupid, item, '0') + + # close the window + self.window.destroy()
===================================== gajim/search_window.py → gajim/gtk/discovery_search.py ===================================== @@ -24,33 +24,25 @@ from gajim.common import ged from gajim.common.modules import dataforms from gajim.common.i18n import _
-from gajim import gtkgui_helpers from gajim import vcard from gajim import config from gajim import dataforms_widget + +from gajim.gtk.util import get_builder from gajim.gtk.add_contact import AddNewContactWindow
class SearchWindow: def __init__(self, account, jid): - """ - Create new window - """ - # an account object self.account = account self.jid = jid
- # retrieving widgets from xml - self.xml = gtkgui_helpers.get_gtk_builder('search_window.ui') - self.window = self.xml.get_object('search_window') - for name in ('label', 'progressbar', 'search_vbox', 'search_button', - 'add_contact_button', 'information_button'): - self.__dict__[name] = self.xml.get_object(name) + self._ui = get_builder('search_window.ui') + self.window = self._ui.search_window
- self.search_button.set_sensitive(False) + self._ui.search_button.set_sensitive(False)
- # displaying the window - self.xml.connect_signals(self) + self._ui.connect_signals(self) self.window.show_all() self.request_form() self.pulse_id = GLib.timeout_add(80, self.pulse_callback) @@ -60,36 +52,40 @@ class SearchWindow: # Is there a jid column in results ? if -1: no, else column number self.jid_column = -1
- app.ged.register_event_handler('search-form-received', ged.GUI1, - self._nec_search_form_received) - app.ged.register_event_handler('search-result-received', ged.GUI1, - self._nec_search_result_received) + app.ged.register_event_handler('search-form-received', + ged.GUI1, + self._nec_search_form_received) + app.ged.register_event_handler('search-result-received', + ged.GUI1, + self._nec_search_result_received)
def request_form(self): con = app.connections[self.account] con.get_module('Search').request_search_fields(self.jid)
def pulse_callback(self): - self.progressbar.pulse() + self._ui.progressbar.pulse() return True
- def on_search_window_key_press_event(self, widget, event): + def on_search_window_key_press_event(self, _widget, event): if event.keyval == Gdk.KEY_Escape: self.window.destroy()
- def on_search_window_destroy(self, widget): + def on_search_window_destroy(self, _widget): if self.pulse_id: GLib.source_remove(self.pulse_id) del app.interface.instances[self.account]['search'][self.jid] - app.ged.remove_event_handler('search-form-received', ged.GUI1, - self._nec_search_form_received) - app.ged.remove_event_handler('search-result-received', ged.GUI1, - self._nec_search_result_received) - - def on_close_button_clicked(self, button): + app.ged.remove_event_handler('search-form-received', + ged.GUI1, + self._nec_search_form_received) + app.ged.remove_event_handler('search-result-received', + ged.GUI1, + self._nec_search_result_received) + + def on_close_button_clicked(self, _button): self.window.destroy()
- def on_search_button_clicked(self, button): + def on_search_button_clicked(self, _button): con = app.connections[self.account] if self.is_form: self.data_form_widget.data_form.type_ = 'submit' @@ -101,22 +97,22 @@ class SearchWindow: del infos['instructions'] con.get_module('Search').send_search_form(self.jid, infos, False)
- self.search_vbox.remove(self.data_form_widget) + self._ui.search_vbox.remove(self.data_form_widget)
- self.progressbar.show() - self.label.set_text(_('Waiting for results')) - self.label.show() + self._ui.progressbar.show() + self._ui.label.set_text(_('Waiting for results')) + self._ui.label.show() self.pulse_id = GLib.timeout_add(80, self.pulse_callback) - self.search_button.hide() + self._ui.search_button.hide()
- def on_add_contact_button_clicked(self, widget): + def on_add_contact_button_clicked(self, _widget): (model, iter_) = self.result_treeview.get_selection().get_selected() if not iter_: return jid = model[iter_][self.jid_column] AddNewContactWindow(self.account, jid)
- def on_information_button_clicked(self, widget): + def on_information_button_clicked(self, _widget): (model, iter_) = self.result_treeview.get_selection().get_selected() if not iter_: return @@ -131,8 +127,8 @@ class SearchWindow: def _nec_search_form_received(self, obj): if self.pulse_id: GLib.source_remove(self.pulse_id) - self.progressbar.hide() - self.label.hide() + self._ui.progressbar.hide() + self._ui.label.hide()
if obj.is_dataform: self.is_form = True @@ -142,19 +138,19 @@ class SearchWindow: try: self.data_form_widget.data_form = self.dataform except dataforms.Error: - self.label.set_text(_('Error in received dataform')) - self.label.show() + self._ui.label.set_text(_('Error in received dataform')) + self._ui.label.show() return if self.data_form_widget.title: - self.window.set_title('%s - Search - Gajim' % \ - self.data_form_widget.title) + self.window.set_title( + '%s - Search - Gajim' % self.data_form_widget.title) else: self.is_form = False self.data_form_widget = config.FakeDataForm(obj.data)
self.data_form_widget.show_all() - self.search_vbox.pack_start(self.data_form_widget, True, True, 0) - self.search_button.set_sensitive(True) + self._ui.search_vbox.pack_start(self.data_form_widget, True, True, 0) + self._ui.search_button.set_sensitive(True)
def on_result_treeview_cursor_changed(self, treeview): if self.jid_column == -1: @@ -163,29 +159,29 @@ class SearchWindow: if not iter_: return if model[iter_][self.jid_column]: - self.add_contact_button.set_sensitive(True) - self.information_button.set_sensitive(True) + self._ui.add_contact_button.set_sensitive(True) + self._ui.information_button.set_sensitive(True) else: - self.add_contact_button.set_sensitive(False) - self.information_button.set_sensitive(False) + self._ui.add_contact_button.set_sensitive(False) + self._ui.information_button.set_sensitive(False)
def _nec_search_result_received(self, obj): if self.pulse_id: GLib.source_remove(self.pulse_id) - self.progressbar.hide() - self.label.hide() + self._ui.progressbar.hide() + self._ui.label.hide()
if not obj.is_dataform: if not obj.data: - self.label.set_text(_('No result')) - self.label.show() + self._ui.label.set_text(_('No result')) + self._ui.label.show() return # We suppose all items have the same fields sw = Gtk.ScrolledWindow() sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.result_treeview = Gtk.TreeView() - self.result_treeview.connect('cursor-changed', - self.on_result_treeview_cursor_changed) + self.result_treeview.connect( + 'cursor-changed', self.on_result_treeview_cursor_changed) sw.add(self.result_treeview) # Create model fieldtypes = [str]*len(obj.data[0]) @@ -196,39 +192,41 @@ class SearchWindow: # Create columns counter = 0 for field in obj.data[0].keys(): - self.result_treeview.append_column(Gtk.TreeViewColumn(field, - Gtk.CellRendererText(), text=counter)) + self.result_treeview.append_column( + Gtk.TreeViewColumn(field, + Gtk.CellRendererText(), + text=counter)) if field == 'jid': self.jid_column = counter counter += 1 self.result_treeview.set_model(model) sw.show_all() - self.search_vbox.pack_start(sw, True, True, 0) + self._ui.search_vbox.pack_start(sw, True, True, 0) if self.jid_column > -1: - self.add_contact_button.show() - self.information_button.show() + self._ui.add_contact_button.show() + self._ui.information_button.show() return
self.dataform = dataforms.extend_form(node=obj.data) if not self.dataform.items: # No result - self.label.set_text(_('No result')) - self.label.show() + self._ui.label.set_text(_('No result')) + self._ui.label.show() return
self.data_form_widget.set_sensitive(True) try: self.data_form_widget.data_form = self.dataform except dataforms.Error: - self.label.set_text(_('Error in received dataform')) - self.label.show() + self._ui.label.set_text(_('Error in received dataform')) + self._ui.label.show() return
self.result_treeview = self.data_form_widget.records_treeview selection = self.result_treeview.get_selection() selection.set_mode(Gtk.SelectionMode.SINGLE) - self.result_treeview.connect('cursor-changed', - self.on_result_treeview_cursor_changed) + self.result_treeview.connect( + 'cursor-changed', self.on_result_treeview_cursor_changed)
counter = 0 for field in self.dataform.reported.iter_fields(): @@ -236,11 +234,11 @@ class SearchWindow: self.jid_column = counter break counter += 1 - self.search_vbox.pack_start(self.data_form_widget, True, True, 0) + self._ui.search_vbox.pack_start(self.data_form_widget, True, True, 0) self.data_form_widget.show() if self.jid_column > -1: - self.add_contact_button.show() - self.information_button.show() + self._ui.add_contact_button.show() + self._ui.information_button.show() if self.data_form_widget.title: - self.window.set_title('%s - Search - Gajim' % \ - self.data_form_widget.title) + self.window.set_title( + '%s - Search - Gajim' % self.data_form_widget.title)
===================================== gajim/filetransfers_window.py → gajim/gtk/filetransfer.py ===================================== @@ -50,6 +50,7 @@ from gajim.gtk.dialogs import NonModalConfirmationDialog from gajim.gtk.filechoosers import FileSaveDialog from gajim.gtk.filechoosers import FileChooserDialog from gajim.gtk.tooltips import FileTransfersTooltip +from gajim.gtk.util import get_builder
log = logging.getLogger('gajim.filetransfer_window')
@@ -69,7 +70,7 @@ class FileTransfersWindow: def __init__(self): self.files_props = {'r' : {}, 's': {}} self.height_diff = 0 - self.xml = gtkgui_helpers.get_gtk_builder('filetransfers.ui') + self.xml = get_builder('filetransfers.ui') self.window = self.xml.get_object('file_transfers_window') self.tree = self.xml.get_object('transfers_list') self.cancel_button = self.xml.get_object('cancel_button') @@ -80,8 +81,7 @@ class FileTransfersWindow:
shall_notify = app.config.get('notify_on_file_complete') self.notify_ft_checkbox.set_active(shall_notify) - self.model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str, int, - int, str) + self.model = Gtk.ListStore(str, str, str, str, str, int, int, str) self.tree.set_model(self.model) col = Gtk.TreeViewColumn()
@@ -91,7 +91,7 @@ class FileTransfersWindow: render_pixbuf.set_property('xpad', 3) render_pixbuf.set_property('ypad', 3) render_pixbuf.set_property('yalign', .0) - col.add_attribute(render_pixbuf, 'pixbuf', 0) + col.add_attribute(render_pixbuf, 'icon_name', 0) self.tree.append_column(col)
col = Gtk.TreeViewColumn(_('File')) @@ -133,7 +133,6 @@ class FileTransfersWindow: col.set_expand(False) self.tree.append_column(col)
- self.images = {} self.icons = { 'upload': 'go-up', 'download': 'go-down', @@ -459,10 +458,6 @@ class FileTransfersWindow: on_response_cancel(account, file_props)) dialog.popup()
- def get_icon(self, ident): - return self.images.setdefault(ident, - gtkgui_helpers.get_icon_pixmap(self.icons[ident], 24)) - def set_status(self, file_props, status): """ Change the status of a transfer to state 'status' @@ -505,7 +500,7 @@ class FileTransfersWindow: helpers.convert_bytes(full_size) self.model.set(iter_, Column.PROGRESS, text) self.model.set(iter_, Column.PULSE, GLib.MAXINT32) - self.model.set(iter_, Column.IMAGE, self.get_icon(status)) + self.model.set(iter_, Column.IMAGE, self.icons[status]) path = self.model.get_path(iter_) self.select_func(path)
@@ -644,7 +639,7 @@ class FileTransfersWindow: status = 'waiting' if file_props.connected is False: status = 'stop' - self.model.set(iter_, 0, self.get_icon(status)) + self.model.set(iter_, 0, self.icons[status]) if transfered_size == full_size: # If we are receiver and this is a jingle session if file_props.type_ == 'r' and \
===================================== gajim/gtk/util.py ===================================== @@ -89,6 +89,10 @@ def get_builder(file_name: str, widgets: List[str] = None) -> Builder: return Builder(file_name, widgets)
+def icon_exists(name: str) -> bool: + return _icon_theme.has_icon(name) + + def load_icon(icon_name, widget, size=16, pixbuf=False, flags=Gtk.IconLookupFlags.FORCE_SIZE):
===================================== gajim/gtkgui_helpers.py ===================================== @@ -75,16 +75,6 @@ def get_icon_pixmap(icon_name, size=16, color=None, quiet=False): if not quiet: log.error('Unable to load icon %s: %s', icon_name, str(error))
-def get_icon_path(icon_name, size=16): - try: - icon_info = gtk_icon_theme.lookup_icon(icon_name, size, 0) - if icon_info is None: - log.error('Icon not found: %s', icon_name) - return '' - return icon_info.get_filename() - except GLib.GError as error: - log.error('Unable to find icon %s: %s', icon_name, str(error)) -
HAS_PYWIN32 = True if os.name == 'nt': @@ -97,11 +87,6 @@ if os.name == 'nt':
from gajim.common import helpers
-def add_image_to_button(button, icon_name): - img = Gtk.Image() - path_img = get_icon_path(icon_name) - img.set_from_file(path_img) - button.set_image(img)
def get_image_button(icon_name, tooltip, toggle=False): if toggle: @@ -146,66 +131,6 @@ def get_gtk_builder(file_name, widget=None): builder.add_from_file(file_path) return builder
-def at_the_end(widget): - """Determines if a Scrollbar in a GtkScrolledWindow is at the end. - - Args: - widget (GtkScrolledWindow) - - Returns: - bool: The return value is True if at the end, False if not. - """ - adj_v = widget.get_vadjustment() - max_scroll_pos = adj_v.get_upper() - adj_v.get_page_size() - return adj_v.get_value() == max_scroll_pos - -def scroll_to_end(widget): - """Scrolls to the end of a GtkScrolledWindow. - - Args: - widget (GtkScrolledWindow) - - Returns: - bool: The return value is False so it can be used with GLib.idle_add. - """ - adj_v = widget.get_vadjustment() - if adj_v is None: - # This can happen when the Widget is already destroyed when called - # from GLib.idle_add - return False - max_scroll_pos = adj_v.get_upper() - adj_v.get_page_size() - adj_v.set_value(max_scroll_pos) - - adj_h = widget.get_hadjustment() - adj_h.set_value(0) - return False - - -class ServersXMLHandler(ContentHandler): - def __init__(self): - ContentHandler.__init__(self) - self.servers = [] - - def startElement(self, name, attributes): - if name == 'item': - if 'jid' in attributes.getNames(): - self.servers.append(attributes.getValue('jid')) - - def endElement(self, name): - pass - -def parse_server_xml(path_to_file): - try: - handler = ServersXMLHandler() - xml.sax.parse(path_to_file, handler) - return handler.servers - # handle exception if unable to open file - except IOError as message: - print(_('Error reading file:') + str(message), file=sys.stderr) - # handle exception parsing file - except xml.sax.SAXParseException as message: - print(_('Error parsing file:') + str(message), file=sys.stderr) - def set_unset_urgency_hint(window, unread_messages_no): """ Sets/unset urgency hint in window argument depending if we have unread @@ -247,22 +172,6 @@ def get_cursor(attr): cursor = getattr(Gdk.CursorType, attr) return Gdk.Cursor.new_for_display(display, cursor)
-def get_current_desktop(window): - """ - Return the current virtual desktop for given window - - NOTE: Window is a GDK window. - """ - prop = window.property_get('_NET_CURRENT_DESKTOP') - if prop is None: # it means it's normal window (not root window) - # so we look for it's current virtual desktop in another property - prop = window.property_get('_NET_WM_DESKTOP') - - if prop is not None: - # f.e. prop is ('CARDINAL', 32, [0]) we want 0 or 1.. from [0] - current_virtual_desktop_no = prop[2][0] - return current_virtual_desktop_no - def file_is_locked(path_to_file): """ Return True if file is locked
===================================== gajim/gui_interface.py ===================================== @@ -74,9 +74,7 @@ from gajim.chat_control import ChatControl from gajim.groupchat_control import GroupchatControl from gajim.groupchat_control import PrivateChatControl from gajim.message_window import MessageWindowMgr -from gajim.filetransfers_window import FileTransfersWindow
-from gajim.atom_window import AtomWindow from gajim.session import ChatControlSession
from gajim.common import idle @@ -121,6 +119,8 @@ from gajim.gtk.filechoosers import FileChooserDialog from gajim.gtk.emoji_data import emoji_data from gajim.gtk.emoji_data import emoji_ascii_data from gajim.gtk.groupchat_config import GroupchatConfig +from gajim.gtk.atom import AtomWindow +from gajim.gtk.filetransfer import FileTransfersWindow
parser = optparser.OptionsParser(configpaths.get('CONFIG_FILE'))
===================================== gajim/message_textview.py ===================================== @@ -24,9 +24,12 @@ from gi.repository import GLib from gi.repository import GObject from gi.repository import Pango
+from gajim import gtkgui_helpers + from gajim.common import app from gajim.common.i18n import _ -from gajim import gtkgui_helpers + +from gajim.gtk.util import scroll_to_end
if app.is_installed('GSPELL'): from gi.repository import Gspell @@ -166,7 +169,7 @@ class MessageTextView(Gtk.TextView): mark = buffer_.get_insert() iter_ = buffer_.get_iter_at_mark(mark) if iter_.get_offset() == buffer_.get_end_iter().get_offset(): - GLib.idle_add(gtkgui_helpers.scroll_to_end, textview.get_parent()) + GLib.idle_add(scroll_to_end, textview.get_parent())
def make_clickable_urls(self, text): _buffer = self.get_buffer()
===================================== gajim/plugins/gui.py ===================================== @@ -21,25 +21,27 @@ GUI classes related to plug-in management. :license: GPL '''
-__all__ = ['PluginsWindow'] +import os +from enum import IntEnum +from enum import unique
from gi.repository import Gtk from gi.repository import GdkPixbuf from gi.repository import Gdk -import os
-from enum import IntEnum, unique - -from gajim import gtkgui_helpers -from gajim.gtk.dialogs import WarningDialog -from gajim.gtk.dialogs import YesNoDialog -from gajim.gtk.filechoosers import ArchiveChooserDialog from gajim.common import app from gajim.common import configpaths +from gajim.common.exceptions import PluginsystemError + from gajim.plugins.helpers import log_calls from gajim.plugins.helpers import GajimPluginActivateException from gajim.plugins.plugins_i18n import _ -from gajim.common.exceptions import PluginsystemError + +from gajim.gtk.dialogs import WarningDialog +from gajim.gtk.dialogs import YesNoDialog +from gajim.gtk.filechoosers import ArchiveChooserDialog +from gajim.gtk.util import get_builder +from gajim.gtk.util import load_icon
@unique @@ -57,7 +59,7 @@ class PluginsWindow: @log_calls('PluginsWindow') def __init__(self): '''Initialize Plugins window''' - builder = gtkgui_helpers.get_gtk_builder('plugins_window.ui') + builder = get_builder('plugins_window.ui') self.window = builder.get_object('plugins_window') self.window.set_transient_for(app.interface.roster.window)
@@ -91,7 +93,9 @@ class PluginsWindow: activatable=Column.ACTIVATABLE) self.installed_plugins_treeview.append_column(col)
- self.def_icon = gtkgui_helpers.get_icon_pixmap('preferences-desktop') + self.def_icon = load_icon('preferences-desktop', + self.window, + pixbuf=True)
# connect signal for selection change selection = self.installed_plugins_treeview.get_selection()
===================================== gajim/roster_window.py ===================================== @@ -46,12 +46,10 @@ from nbxmpp.protocol import NS_FILE, NS_ROSTERX, NS_CONFERENCE
from gajim import dialogs from gajim import vcard -from gajim import disco from gajim import gtkgui_helpers from gajim import gui_menu_builder from gajim import cell_renderer_image from gajim import message_control -from gajim import adhoc_commands
from gajim.common import app from gajim.common import helpers @@ -79,9 +77,11 @@ from gajim.gtk.pep_config import ManagePEPServicesWindow from gajim.gtk.bookmarks import ManageBookmarksWindow from gajim.gtk.account_wizard import AccountCreationWizard from gajim.gtk.service_registration import ServiceRegistration +from gajim.gtk.discovery import ServiceDiscoveryWindow from gajim.gtk.history import HistoryWindow from gajim.gtk.accounts import AccountsWindow from gajim.gtk.tooltips import RosterTooltip +from gajim.gtk.adhoc_commands import CommandWindow from gajim.gtk.util import get_icon_name from gajim.gtk.util import resize_window from gajim.gtk.util import move_window @@ -3702,7 +3702,7 @@ class RosterWindow: jid = contact.jid if resource is not None: jid = jid + '/' + resource - adhoc_commands.CommandWindow(account, jid) + CommandWindow(account, jid)
def on_roster_window_focus_in_event(self, widget, event): # roster received focus, so if we had urgency REMOVE IT @@ -4035,7 +4035,7 @@ class RosterWindow: else: try: # Object will add itself to the window dict - disco.ServiceDiscoveryWindow(account, address_entry=True) + ServiceDiscoveryWindow(account, address_entry=True) except GajimGeneralException: pass
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/39dfe41af56df33f2e7e3d56de152f3bbc...