Philipp Hörist pushed to branch master at gajim / gajim

Commits:

19 changed files:

Changes:

  • gajim/app_actions.py
    ... ... @@ -22,7 +22,6 @@ from gajim.common import helpers
    22 22
     from gajim.common.app import interface
    
    23 23
     from gajim.common.exceptions import GajimGeneralException
    
    24 24
     from gajim import dialogs
    
    25
    -from gajim import disco
    
    26 25
     
    
    27 26
     import gajim.plugins.gui
    
    28 27
     
    
    ... ... @@ -44,6 +43,7 @@ from gajim.gtk.account_wizard import AccountCreationWizard
    44 43
     from gajim.gtk.history import HistoryWindow
    
    45 44
     from gajim.gtk.accounts import AccountsWindow
    
    46 45
     from gajim.gtk.proxies import ManageProxies
    
    46
    +from gajim.gtk.discovery import ServiceDiscoveryWindow
    
    47 47
     
    
    48 48
     
    
    49 49
     # General Actions
    
    ... ... @@ -130,7 +130,7 @@ def on_service_disco(action, param):
    130 130
         else:
    
    131 131
             try:
    
    132 132
                 # Object will add itself to the window dict
    
    133
    -            disco.ServiceDiscoveryWindow(account, address_entry=True)
    
    133
    +            ServiceDiscoveryWindow(account, address_entry=True)
    
    134 134
             except GajimGeneralException:
    
    135 135
                 pass
    
    136 136
     
    

  • gajim/chat_control_base.py
    ... ... @@ -52,7 +52,9 @@ from gajim.conversation_textview import ConversationTextview
    52 52
     from gajim.message_textview import MessageTextView
    
    53 53
     
    
    54 54
     from gajim.gtk.dialogs import NonModalConfirmationDialog
    
    55
    +from gajim.gtk import util
    
    55 56
     from gajim.gtk.util import convert_rgb_to_hex
    
    57
    +from gajim.gtk.util import at_the_end
    
    56 58
     from gajim.gtk.emoji_chooser import emoji_chooser
    
    57 59
     
    
    58 60
     from gajim.command_system.implementation.middleware import ChatCommandProcessor
    
    ... ... @@ -708,7 +710,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
    708 710
                     mark = message_buffer.get_insert()
    
    709 711
                     iter_ = message_buffer.get_iter_at_mark(mark)
    
    710 712
                     if message_buffer.get_end_iter().equal(iter_):
    
    711
    -                    GLib.idle_add(gtkgui_helpers.scroll_to_end, self.msg_scrolledwindow)
    
    713
    +                    GLib.idle_add(util.scroll_to_end, self.msg_scrolledwindow)
    
    712 714
     
    
    713 715
                 return True
    
    714 716
             elif event.keyval == Gdk.KEY_z: # CTRL+z
    
    ... ... @@ -1192,7 +1194,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
    1192 1194
             if event.get_button()[1] != 1:
    
    1193 1195
                 # We want only to catch the left mouse button
    
    1194 1196
                 return
    
    1195
    -        if not gtkgui_helpers.at_the_end(scrollbar.get_parent()):
    
    1197
    +        if not at_the_end(scrollbar.get_parent()):
    
    1196 1198
                 app.log('autoscroll').info('Autoscroll disabled')
    
    1197 1199
                 self.conv_textview.autoscroll = False
    
    1198 1200
     
    

  • gajim/common/helpers.py
    ... ... @@ -39,6 +39,7 @@ import shlex
    39 39
     import socket
    
    40 40
     import time
    
    41 41
     import logging
    
    42
    +import json
    
    42 43
     from datetime import datetime, timedelta
    
    43 44
     from distutils.version import LooseVersion as V
    
    44 45
     from encodings.punycode import punycode_encode
    
    ... ... @@ -1492,3 +1493,15 @@ def get_sync_threshold(jid, archive_info):
    1492 1493
             app.logger.set_archive_infos(jid, sync_threshold=threshold)
    
    1493 1494
             return threshold
    
    1494 1495
         return archive_info.sync_threshold
    
    1496
    +
    
    1497
    +def load_json(path, key=None, default=None):
    
    1498
    +    try:
    
    1499
    +        with open(path, 'r') as file:
    
    1500
    +            json_dict = json.loads(file.read())
    
    1501
    +    except Exception:
    
    1502
    +        log.exception('Parsing error')
    
    1503
    +        return default
    
    1504
    +
    
    1505
    +    if key is None:
    
    1506
    +        return json_dict
    
    1507
    +    return json_dict.get(key, default)

  • gajim/data/other/servers.json
    1
    +{
    
    2
    +   "servers":[
    
    3
    +      "0nl1ne.at",
    
    4
    +      "404.city",
    
    5
    +      "brauchen.info",
    
    6
    +      "chatme.im",
    
    7
    +      "comm.unicate.me",
    
    8
    +      "creep.im",
    
    9
    +      "deshalbfrei.org",
    
    10
    +      "draugr.de",
    
    11
    +      "im.apinc.org",
    
    12
    +      "jabber-hosting.de",
    
    13
    +      "jabber.at",
    
    14
    +      "jabber.ccc.de",
    
    15
    +      "jabber.cz",
    
    16
    +      "jabber.hot-chilli.net",
    
    17
    +      "jabber.meta.net.nz",
    
    18
    +      "jabber.no",
    
    19
    +      "jabber.sk",
    
    20
    +      "jabber.rueckgr.at",
    
    21
    +      "jabberes.org",
    
    22
    +      "jabbim.com",
    
    23
    +      "jabbim.cz",
    
    24
    +      "jabbim.pl",
    
    25
    +      "jabbim.sk",
    
    26
    +      "jabster.pl",
    
    27
    +      "lightwitch.org",
    
    28
    +      "linuxlovers.at",
    
    29
    +      "njs.netlab.cz",
    
    30
    +      "pandion.im",
    
    31
    +      "richim.org",
    
    32
    +      "suchat.org",
    
    33
    +      "tigase.im",
    
    34
    +      "ubuntu-jabber.de",
    
    35
    +      "ubuntu-jabber.net",
    
    36
    +      "verdammung.org",
    
    37
    +      "xabber.de",
    
    38
    +      "xmpp-hosting.de",
    
    39
    +      "xmpp.jp",
    
    40
    +      "zsim.de"
    
    41
    +   ]
    
    42
    +}

  • gajim/data/other/servers.xml deleted
    1
    -<?xml version="1.0" encoding="utf-8"?>
    
    2
    -<!--
    
    3
    -  This file lists the open XMPP servers registered with the XSF. 
    
    4
    -  The format of this file is defined by the Service Discovery 
    
    5
    -  protocol: http://xmpp.org/extensions/xep-0030.html 
    
    6
    -  To add your server to the list, follow the instructions at
    
    7
    -  http://xmpp.org/services/register.shtml
    
    8
    -    -->
    
    9
    -<query xmlns:reg="urn:xmpp:vcard:registration:1">
    
    10
    -  <item jid="0nl1ne.at" />
    
    11
    -  <item jid="404.city" />
    
    12
    -  <item jid="brauchen.info" />
    
    13
    -  <item jid="chatme.im" />
    
    14
    -  <item jid="climm.org" />
    
    15
    -  <item jid="comm.unicate.me" />
    
    16
    -  <item jid="creep.im" />
    
    17
    -  <item jid="deshalbfrei.org" />
    
    18
    -  <item jid="draugr.de" />
    
    19
    -  <item jid="einfachjabber.de" />
    
    20
    -  <item jid="forumanalogue.fr" />
    
    21
    -  <item jid="im.apinc.org" />
    
    22
    -  <item jid="im.flosoft.biz" />
    
    23
    -  <item jid="jabber-hosting.de" />
    
    24
    -  <item jid="jabber.at" />
    
    25
    -  <item jid="jabber.ccc.de" />
    
    26
    -  <item jid="jabber.chaotic.de" />
    
    27
    -  <item jid="jabber.co.nz" />
    
    28
    -  <item jid="jabber.cz" />
    
    29
    -  <item jid="jabber.earth.li" />
    
    30
    -  <item jid="jabber.fourecks.de" />
    
    31
    -  <item jid="jabber.hot-chilli.net" />
    
    32
    -  <item jid="jabber.i-pobox.net" />
    
    33
    -  <item jid="jabber.me" />
    
    34
    -  <item jid="jabber.meta.net.nz" />
    
    35
    -  <item jid="jabber.no" />
    
    36
    -  <item jid="jabber.sk" />
    
    37
    -  <item jid="jabber.org" />
    
    38
    -  <item jid="jabber.rueckgr.at" />
    
    39
    -  <item jid="jabber.scha.de" />
    
    40
    -  <item jid="jabber.second-home.de" />
    
    41
    -  <item jid="jabber.smash-net.org" />
    
    42
    -  <item jid="jabber.sow.as" />
    
    43
    -  <item jid="jabber.theforest.us" />
    
    44
    -  <item jid="jabberafrica.org" />
    
    45
    -  <item jid="jabberes.org" />
    
    46
    -  <item jid="jabberpl.org" />
    
    47
    -  <item jid="jabbim.com" />
    
    48
    -  <item jid="jabbim.cz" />
    
    49
    -  <item jid="jabbim.hu" />
    
    50
    -  <item jid="jabbim.pl" />
    
    51
    -  <item jid="jabbim.sk" />
    
    52
    -  <item jid="jabster.pl" />
    
    53
    -  <item jid="jaim.at" />
    
    54
    -  <item jid="lightwitch.org" />
    
    55
    -  <item jid="linuxlovers.at" />
    
    56
    -  <item jid="lsd-25.ru" />
    
    57
    -  <item jid="njs.netlab.cz" />
    
    58
    -  <item jid="palita.net" />
    
    59
    -  <item jid="pandion.im" />
    
    60
    -  <item jid="richim.org" />
    
    61
    -  <item jid="sss.chaoslab.ru" />
    
    62
    -  <item jid="sternenschweif.de" />
    
    63
    -  <item jid="suchat.org" />
    
    64
    -  <item jid="swissjabber.ch" />
    
    65
    -  <item jid="swissjabber.de" />
    
    66
    -  <item jid="swissjabber.eu" />
    
    67
    -  <item jid="swissjabber.li" />
    
    68
    -  <item jid="swissjabber.org" />
    
    69
    -  <item jid="tcweb.org" />
    
    70
    -  <item jid="tekst.me" />
    
    71
    -  <item jid="tigase.im" />
    
    72
    -  <item jid="ubuntu-jabber.de" />
    
    73
    -  <item jid="ubuntu-jabber.net" />
    
    74
    -  <item jid="univers-libre.net" />
    
    75
    -  <item jid="uprod.biz" />
    
    76
    -  <item jid="verdammung.org" />
    
    77
    -  <item jid="wtfismyip.com" />
    
    78
    -  <item jid="xabber.de" />
    
    79
    -  <item jid="xmpp-hosting.de" />
    
    80
    -  <item jid="xmpp.jp" />
    
    81
    -  <item jid="xmppnet.de" />
    
    82
    -  <item jid="zsim.de" />
    
    83
    -</query>

  • gajim/groupchat_control.py
    ... ... @@ -44,7 +44,6 @@ from gajim import gui_menu_builder
    44 44
     from gajim import message_control
    
    45 45
     from gajim import vcard
    
    46 46
     from gajim import dataforms_widget
    
    47
    -from gajim import adhoc_commands
    
    48 47
     
    
    49 48
     from gajim.common.const import AvatarSize
    
    50 49
     from gajim.common.caps_cache import muc_caps_cache
    
    ... ... @@ -76,6 +75,7 @@ from gajim.gtk.filechoosers import AvatarChooserDialog
    76 75
     from gajim.gtk.add_contact import AddNewContactWindow
    
    77 76
     from gajim.gtk.tooltips import GCTooltip
    
    78 77
     from gajim.gtk.groupchat_config import GroupchatConfig
    
    78
    +from gajim.gtk.adhoc_commands import CommandWindow
    
    79 79
     from gajim.gtk.util import get_icon_name
    
    80 80
     from gajim.gtk.util import get_image_from_icon_name
    
    81 81
     
    
    ... ... @@ -797,7 +797,7 @@ class GroupchatControl(ChatControlBase):
    797 797
             """
    
    798 798
             Execute AdHoc commands on the current room
    
    799 799
             """
    
    800
    -        adhoc_commands.CommandWindow(self.account, self.room_jid)
    
    800
    +        CommandWindow(self.account, self.room_jid)
    
    801 801
     
    
    802 802
         def _on_upload_avatar(self, action, param):
    
    803 803
             def _on_accept(filename):
    
    ... ... @@ -2783,7 +2783,7 @@ class GroupchatControl(ChatControlBase):
    2783 2783
     
    
    2784 2784
         def _on_execute_command_occupant(self, widget, nick):
    
    2785 2785
             jid = self.room_jid + '/' + nick
    
    2786
    -        adhoc_commands.CommandWindow(self.account, jid)
    
    2786
    +        CommandWindow(self.account, jid)
    
    2787 2787
     
    
    2788 2788
         def on_row_activated(self, widget, path):
    
    2789 2789
             """
    

  • gajim/groups.py deleted
    1
    -# Copyright (C) 2006-2014 Yann Leboulanger <asterix AT lagaule.org>
    
    2
    -# Copyright (C) 2006 Tomasz Melcer <liori AT exroot.org>
    
    3
    -#
    
    4
    -# This file is part of Gajim.
    
    5
    -#
    
    6
    -# Gajim is free software; you can redistribute it and/or modify
    
    7
    -# it under the terms of the GNU General Public License as published
    
    8
    -# by the Free Software Foundation; version 3 only.
    
    9
    -#
    
    10
    -# Gajim is distributed in the hope that it will be useful,
    
    11
    -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    12
    -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    
    13
    -# GNU General Public License for more details.
    
    14
    -#
    
    15
    -# You should have received a copy of the GNU General Public License
    
    16
    -# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    17
    -
    
    18
    -'''Window to create new post for discussion groups service.'''
    
    19
    -
    
    20
    -from gajim.common import app
    
    21
    -from nbxmpp import Node
    
    22
    -from gajim import gtkgui_helpers
    
    23
    -
    
    24
    -class GroupsPostWindow:
    
    25
    -    def __init__(self, account, servicejid, groupid):
    
    26
    -        """
    
    27
    -        Open new 'create post' window to create message for groupid on servicejid
    
    28
    -        service
    
    29
    -        """
    
    30
    -        assert isinstance(servicejid, str)
    
    31
    -        assert isinstance(groupid, str)
    
    32
    -
    
    33
    -        self.account = account
    
    34
    -        self.servicejid = servicejid
    
    35
    -        self.groupid = groupid
    
    36
    -
    
    37
    -        self.xml = gtkgui_helpers.get_gtk_builder('groups_post_window.ui')
    
    38
    -        self.window = self.xml.get_object('groups_post_window')
    
    39
    -        for name in ('from_entry', 'subject_entry', 'contents_textview'):
    
    40
    -            self.__dict__[name] = self.xml.get_object(name)
    
    41
    -
    
    42
    -        self.xml.connect_signals(self)
    
    43
    -        self.window.show_all()
    
    44
    -
    
    45
    -    def on_cancel_button_clicked(self, w):
    
    46
    -        """
    
    47
    -        Close window
    
    48
    -        """
    
    49
    -        self.window.destroy()
    
    50
    -
    
    51
    -    def on_send_button_clicked(self, w):
    
    52
    -        """
    
    53
    -        Gather info from widgets and send it as a message
    
    54
    -        """
    
    55
    -        # constructing item to publish... that's atom:entry element
    
    56
    -        item = Node('entry', {'xmlns':'http://www.w3.org/2005/Atom'})
    
    57
    -        author = item.addChild('author')
    
    58
    -        author.addChild('name', {}, [self.from_entry.get_text()])
    
    59
    -        item.addChild('generator', {}, ['Gajim'])
    
    60
    -        item.addChild('title', {}, [self.subject_entry.get_text()])
    
    61
    -
    
    62
    -        buf = self.contents_textview.get_buffer()
    
    63
    -        item.addChild('content', {}, [buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)])
    
    64
    -
    
    65
    -        # publish it to node
    
    66
    -        con = app.connections[self.account]
    
    67
    -        con.get_module('PubSub').send_pb_publish(
    
    68
    -            self.servicejid, self.groupid, item, '0')
    
    69
    -
    
    70
    -        # close the window
    
    71
    -        self.window.destroy()

  • gajim/gtk/account_wizard.py
    ... ... @@ -54,10 +54,11 @@ class AccountCreationWizard:
    54 54
     
    
    55 55
             self.update_proxy_list()
    
    56 56
     
    
    57
    -        # parse servers.xml
    
    58
    -        servers_xml = os.path.join(
    
    59
    -            configpaths.get('DATA'), 'other', 'servers.xml')
    
    60
    -        servers = gtkgui_helpers.parse_server_xml(servers_xml)
    
    57
    +        # parse servers.json
    
    58
    +        server_file_path = os.path.join(
    
    59
    +            configpaths.get('DATA'), 'other', 'servers.json')
    
    60
    +        servers = helpers.load_json(server_file_path, 'servers', [])
    
    61
    +
    
    61 62
             servers_model = self.xml.get_object('server_liststore')
    
    62 63
             for server in servers:
    
    63 64
                 servers_model.append((server,))
    
    ... ... @@ -179,10 +180,10 @@ class AccountCreationWizard:
    179 180
             self.go_online_checkbutton.show()
    
    180 181
             img = self.xml.get_object('finish_image')
    
    181 182
             if self.modify:
    
    182
    -            img.set_from_icon_name(Gtk.STOCK_APPLY, Gtk.IconSize.DIALOG)
    
    183
    +            img.set_from_icon_name('emblem-ok-symbolic', Gtk.IconSize.DIALOG)
    
    184
    +            img.get_style_context().add_class('success-color')
    
    183 185
             else:
    
    184
    -            path_to_file = gtkgui_helpers.get_icon_path('org.gajim.Gajim', 48)
    
    185
    -            img.set_from_file(path_to_file)
    
    186
    +            img.set_from_icon_name('org.gajim.Gajim', Gtk.IconSize.DIALOG)
    
    186 187
             self.show_vcard_checkbutton.set_active(not self.modify)
    
    187 188
             self.notebook.set_current_page(6) # show finish page
    
    188 189
     
    

  • gajim/adhoc_commands.py → gajim/gtk/adhoc_commands.py
    ... ... @@ -29,10 +29,10 @@ from gajim.common.i18n import _
    29 29
     from gajim.common.modules import dataforms
    
    30 30
     from gajim.common import ged
    
    31 31
     
    
    32
    -from gajim import gtkgui_helpers
    
    33 32
     from gajim import dataforms_widget
    
    34 33
     
    
    35 34
     from gajim.gtk.dialogs import HigDialog
    
    35
    +from gajim.gtk.util import get_builder
    
    36 36
     
    
    37 37
     
    
    38 38
     class CommandWindow:
    
    ... ... @@ -68,7 +68,7 @@ class CommandWindow:
    68 68
             self.stage_window_delete_cb = None
    
    69 69
     
    
    70 70
             # retrieving widgets from xml
    
    71
    -        self.xml = gtkgui_helpers.get_gtk_builder('adhoc_commands_window.ui')
    
    71
    +        self.xml = get_builder('adhoc_commands_window.ui')
    
    72 72
             self.window = self.xml.get_object('adhoc_commands_window')
    
    73 73
             self.window.connect('delete-event',
    
    74 74
                 self.on_adhoc_commands_window_delete_event)
    

  • gajim/atom_window.py → gajim/gtk/atom.py
    ... ... @@ -27,7 +27,7 @@ from gajim.common import helpers
    27 27
     from gajim.common import i18n
    
    28 28
     from gajim.common.i18n import _
    
    29 29
     
    
    30
    -from gajim import gtkgui_helpers
    
    30
    +from gajim.gtk.util import get_builder
    
    31 31
     
    
    32 32
     class AtomWindow:
    
    33 33
         window = None
    
    ... ... @@ -57,7 +57,7 @@ class AtomWindow:
    57 57
     
    
    58 58
             self.entry = None # the entry actually displayed
    
    59 59
     
    
    60
    -        self.xml = gtkgui_helpers.get_gtk_builder('atom_entry_window.ui')
    
    60
    +        self.xml = get_builder('atom_entry_window.ui')
    
    61 61
             self.window = self.xml.get_object('atom_entry_window')
    
    62 62
             for name in ('new_entry_label', 'feed_title_label',
    
    63 63
             'feed_title_eventbox', 'feed_tagline_label', 'entry_title_label',
    

  • gajim/disco.py → gajim/gtk/discovery.py
    ... ... @@ -3,6 +3,7 @@
    3 3
     # Copyright (C) 2005-2014 Yann Leboulanger <asterix AT lagaule.org>
    
    4 4
     # Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
    
    5 5
     # Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
    
    6
    +# Copyright (C) 2006 Tomasz Melcer <liori AT exroot.org>
    
    6 7
     # Copyright (C) 2007 Stephan Erb <steve-e AT h3c.de>
    
    7 8
     #
    
    8 9
     # This file is part of Gajim.
    
    ... ... @@ -49,11 +50,6 @@ from gi.repository import Gtk
    49 50
     from gi.repository import Gdk
    
    50 51
     from gi.repository import GdkPixbuf
    
    51 52
     
    
    52
    -from gajim import gtkgui_helpers
    
    53
    -from gajim import groups
    
    54
    -from gajim import adhoc_commands
    
    55
    -from gajim import search_window
    
    56
    -
    
    57 53
     from gajim.common import app
    
    58 54
     from gajim.common.i18n import _
    
    59 55
     from gajim.common import helpers
    
    ... ... @@ -62,6 +58,10 @@ from gajim.common.const import StyleAttr
    62 58
     from gajim.gtk.dialogs import ErrorDialog
    
    63 59
     from gajim.gtk.dialogs import InformationDialog
    
    64 60
     from gajim.gtk.service_registration import ServiceRegistration
    
    61
    +from gajim.gtk.discovery_search import SearchWindow
    
    62
    +from gajim.gtk.adhoc_commands import CommandWindow
    
    63
    +from gajim.gtk.util import icon_exists
    
    64
    +from gajim.gtk.util import get_builder
    
    65 65
     
    
    66 66
     LABELS = {
    
    67 67
         1: _('This service has not yet responded with detailed information'),
    
    ... ... @@ -287,28 +287,19 @@ class ServicesCache:
    287 287
                     info = _agent_type_info[(cat, type_)]
    
    288 288
                 except KeyError:
    
    289 289
                     continue
    
    290
    -            filename = info[1]
    
    291
    -            if filename:
    
    290
    +            service_name = info[1]
    
    291
    +            if service_name:
    
    292 292
                     break
    
    293 293
             else:
    
    294 294
                 # Loop fell through, default to unknown
    
    295
    -            filename = addr.split('.')[0]
    
    295
    +            service_name = addr.split('.')[0]
    
    296 296
                 quiet = True
    
    297
    -        # Use the cache if possible
    
    298
    -        if filename in _icon_cache:
    
    299
    -            return _icon_cache[filename]
    
    297
    +
    
    300 298
             # Or load it
    
    301
    -        pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-' + filename, size=32,
    
    302
    -            quiet=quiet)
    
    303
    -        if pix:
    
    304
    -            # Store in cache
    
    305
    -            _icon_cache[filename] = pix
    
    306
    -            return pix
    
    307
    -        if 'jabber' in _icon_cache:
    
    308
    -            return _icon_cache['jabber']
    
    309
    -        pix = gtkgui_helpers.get_icon_pixmap('gajim-agent-jabber', size=32)
    
    310
    -        _icon_cache['jabber'] = pix
    
    311
    -        return pix
    
    299
    +        icon_name = 'gajim-agent-%s' % service_name
    
    300
    +        if icon_exists(icon_name):
    
    301
    +            return icon_name
    
    302
    +        return 'gajim-agent-jabber'
    
    312 303
     
    
    313 304
         def get_browser(self, identities=None, features=None):
    
    314 305
             """
    
    ... ... @@ -513,7 +504,7 @@ _('Without a connection, you can not browse available services'))
    513 504
     
    
    514 505
             if initial_identities:
    
    515 506
                 self.cache._on_agent_info(jid, node, initial_identities, [], None)
    
    516
    -        self.xml = gtkgui_helpers.get_gtk_builder('service_discovery_window.ui')
    
    507
    +        self.xml = get_builder('service_discovery_window.ui')
    
    517 508
             self.window = self.xml.get_object('service_discovery_window')
    
    518 509
             self.services_treeview = self.xml.get_object('services_treeview')
    
    519 510
             self.model = None
    
    ... ... @@ -869,8 +860,9 @@ class AgentBrowser:
    869 860
                 self.window._set_window_banner_text(self._get_agent_address(), name)
    
    870 861
     
    
    871 862
             # Add an icon to the banner.
    
    872
    -        pix = self.cache.get_icon(identities, addr=self._get_agent_address())
    
    873
    -        self.window.banner_icon.set_from_pixbuf(pix)
    
    863
    +        icon_name = self.cache.get_icon(identities,
    
    864
    +                                        addr=self._get_agent_address())
    
    865
    +        self.window.banner_icon.set_from_icon_name(icon_name, Gtk.IconSize.DND)
    
    874 866
             self.window.banner_icon.show()
    
    875 867
     
    
    876 868
         def _clean_title(self):
    
    ... ... @@ -1138,8 +1130,9 @@ class ToplevelAgentBrowser(AgentBrowser):
    1138 1130
                 identity = {'category': '_jid', 'type': type_}
    
    1139 1131
                 identities.append(identity)
    
    1140 1132
             # Set the pixmap for the row
    
    1141
    -        pix = self.cache.get_icon(identities, addr=addr)
    
    1142
    -        self.model.append(None, (self.jid, self.node, pix, descr, LABELS[1]))
    
    1133
    +        icon_name = self.cache.get_icon(identities, addr=addr)
    
    1134
    +        self.model.append(None,
    
    1135
    +                          (self.jid, self.node, icon_name, descr, LABELS[1]))
    
    1143 1136
             # Grab info on the service
    
    1144 1137
             self.cache.get_info(self.jid, self.node, self._agent_info, force=False)
    
    1145 1138
     
    
    ... ... @@ -1149,9 +1142,9 @@ class ToplevelAgentBrowser(AgentBrowser):
    1149 1142
             """
    
    1150 1143
             jid = model.get_value(iter_, 0)
    
    1151 1144
             if jid:
    
    1152
    -            pix = model.get_value(iter_, 2)
    
    1145
    +            icon_name = model.get_value(iter_, 2)
    
    1153 1146
                 cell.set_property('visible', True)
    
    1154
    -            cell.set_property('pixbuf', pix)
    
    1147
    +            cell.set_property('icon_name', icon_name)
    
    1155 1148
             else:
    
    1156 1149
                 cell.set_property('visible', False)
    
    1157 1150
     
    
    ... ... @@ -1202,7 +1195,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1202 1195
             # state is None on success or has a string
    
    1203 1196
             # from LABELS on error or while fetching
    
    1204 1197
             view = self.window.services_treeview
    
    1205
    -        self.model = Gtk.TreeStore(str, str, GdkPixbuf.Pixbuf, str, str)
    
    1198
    +        self.model = Gtk.TreeStore(str, str, str, str, str)
    
    1206 1199
             self.model.set_sort_func(4, self._treemodel_sort_func)
    
    1207 1200
             self.model.set_sort_column_id(4, Gtk.SortType.ASCENDING)
    
    1208 1201
             view.set_model(self.model)
    
    ... ... @@ -1211,6 +1204,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1211 1204
             # Icon Renderer
    
    1212 1205
             renderer = Gtk.CellRendererPixbuf()
    
    1213 1206
             renderer.set_property('xpad', 6)
    
    1207
    +        renderer.set_property('stock-size', Gtk.IconSize.DND)
    
    1214 1208
             col.pack_start(renderer, False)
    
    1215 1209
             col.set_cell_data_func(renderer, self._pixbuf_renderer_data_func)
    
    1216 1210
             # Text Renderer
    
    ... ... @@ -1299,7 +1293,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1299 1293
                         present()
    
    1300 1294
             else:
    
    1301 1295
                 app.interface.instances[self.account]['search'][service] = \
    
    1302
    -                    search_window.SearchWindow(self.account, service)
    
    1296
    +                    SearchWindow(self.account, service)
    
    1303 1297
     
    
    1304 1298
         def cleanup(self):
    
    1305 1299
             AgentBrowser.cleanup(self)
    
    ... ... @@ -1319,7 +1313,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1319 1313
                 return
    
    1320 1314
             service = model[iter_][0]
    
    1321 1315
             node = model[iter_][1]
    
    1322
    -        adhoc_commands.CommandWindow(self.account, service, commandnode=node)
    
    1316
    +        CommandWindow(self.account, service, commandnode=node)
    
    1323 1317
     
    
    1324 1318
         def on_register_button_clicked(self, widget=None):
    
    1325 1319
             """
    
    ... ... @@ -1547,13 +1541,13 @@ class ToplevelAgentBrowser(AgentBrowser):
    1547 1541
             else:
    
    1548 1542
                 # Put it in the 'other' category for now
    
    1549 1543
                 cat_args = ('other',)
    
    1550
    -        # Set the pixmap for the row
    
    1551
    -        pix = self.cache.get_icon(identities, addr=addr)
    
    1544
    +
    
    1545
    +        icon_name = self.cache.get_icon(identities, addr=addr)
    
    1552 1546
             # Put it in the right category
    
    1553 1547
             cat = self._find_category(*cat_args)
    
    1554 1548
             if not cat:
    
    1555 1549
                 cat = self._create_category(*cat_args)
    
    1556
    -        self.model.append(cat, (jid, node, pix, descr, LABELS[1]))
    
    1550
    +        self.model.append(cat, (jid, node, icon_name, descr, LABELS[1]))
    
    1557 1551
             GLib.idle_add(self._expand_all)
    
    1558 1552
             # Grab info on the service
    
    1559 1553
             self.cache.get_info(jid, node, self._agent_info, force=force)
    
    ... ... @@ -1583,7 +1577,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1583 1577
             self._update_progressbar()
    
    1584 1578
     
    
    1585 1579
             # Search for an icon and category we can display
    
    1586
    -        pix = self.cache.get_icon(identities, addr=addr)
    
    1580
    +        icon_name = self.cache.get_icon(identities, addr=addr)
    
    1587 1581
             cat, type_ = None, None
    
    1588 1582
             for identity in identities:
    
    1589 1583
                 try:
    
    ... ... @@ -1596,7 +1590,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1596 1590
             old_cat_iter = self.model.iter_parent(iter_)
    
    1597 1591
             if not old_cat_iter or self.model.get_value(old_cat_iter, 3) == cat:
    
    1598 1592
                 # Already in the right category, just update
    
    1599
    -            self.model[iter_][2] = pix
    
    1593
    +            self.model[iter_][2] = icon_name
    
    1600 1594
                 self.model[iter_][3] = descr
    
    1601 1595
                 self.model[iter_][4] = None
    
    1602 1596
                 return
    
    ... ... @@ -1613,7 +1607,7 @@ class ToplevelAgentBrowser(AgentBrowser):
    1613 1607
             cat_iter = self._find_category(cat, type_)
    
    1614 1608
             if not cat_iter:
    
    1615 1609
                 cat_iter = self._create_category(cat, type_)
    
    1616
    -        self.model.append(cat_iter, (jid, node, pix, descr, None))
    
    1610
    +        self.model.append(cat_iter, (jid, node, icon_name, descr, None))
    
    1617 1611
             self._expand_all()
    
    1618 1612
     
    
    1619 1613
         def _update_error(self, iter_, jid, node):
    
    ... ... @@ -2064,7 +2058,7 @@ class DiscussionGroupsBrowser(AgentBrowser):
    2064 2058
     
    
    2065 2059
             groupnode = model.get_value(iter_, 1)   # 1 = groupnode
    
    2066 2060
     
    
    2067
    -        groups.GroupsPostWindow(self.account, self.jid, groupnode)
    
    2061
    +        GroupsPostWindow(self.account, self.jid, groupnode)
    
    2068 2062
     
    
    2069 2063
         def on_subscribe_button_clicked(self, widget):
    
    2070 2064
             """
    
    ... ... @@ -2153,3 +2147,53 @@ class DiscussionGroupsBrowser(AgentBrowser):
    2153 2147
     
    
    2154 2148
     # Fill the global agent type info dictionary
    
    2155 2149
     _agent_type_info = _gen_agent_type_info()
    
    2150
    +
    
    2151
    +
    
    2152
    +class GroupsPostWindow:
    
    2153
    +    def __init__(self, account, servicejid, groupid):
    
    2154
    +        """
    
    2155
    +        Open new 'create post' window to create message for groupid on servicejid
    
    2156
    +        service
    
    2157
    +        """
    
    2158
    +        assert isinstance(servicejid, str)
    
    2159
    +        assert isinstance(groupid, str)
    
    2160
    +
    
    2161
    +        self.account = account
    
    2162
    +        self.servicejid = servicejid
    
    2163
    +        self.groupid = groupid
    
    2164
    +
    
    2165
    +        self.xml = get_builder('groups_post_window.ui')
    
    2166
    +        self.window = self.xml.get_object('groups_post_window')
    
    2167
    +        for name in ('from_entry', 'subject_entry', 'contents_textview'):
    
    2168
    +            self.__dict__[name] = self.xml.get_object(name)
    
    2169
    +
    
    2170
    +        self.xml.connect_signals(self)
    
    2171
    +        self.window.show_all()
    
    2172
    +
    
    2173
    +    def on_cancel_button_clicked(self, w):
    
    2174
    +        """
    
    2175
    +        Close window
    
    2176
    +        """
    
    2177
    +        self.window.destroy()
    
    2178
    +
    
    2179
    +    def on_send_button_clicked(self, w):
    
    2180
    +        """
    
    2181
    +        Gather info from widgets and send it as a message
    
    2182
    +        """
    
    2183
    +        # constructing item to publish... that's atom:entry element
    
    2184
    +        item = nbxmpp.Node('entry', {'xmlns':'http://www.w3.org/2005/Atom'})
    
    2185
    +        author = item.addChild('author')
    
    2186
    +        author.addChild('name', {}, [self.from_entry.get_text()])
    
    2187
    +        item.addChild('generator', {}, ['Gajim'])
    
    2188
    +        item.addChild('title', {}, [self.subject_entry.get_text()])
    
    2189
    +
    
    2190
    +        buf = self.contents_textview.get_buffer()
    
    2191
    +        item.addChild('content', {}, [buf.get_text(buf.get_start_iter(), buf.get_end_iter(), True)])
    
    2192
    +
    
    2193
    +        # publish it to node
    
    2194
    +        con = app.connections[self.account]
    
    2195
    +        con.get_module('PubSub').send_pb_publish(
    
    2196
    +            self.servicejid, self.groupid, item, '0')
    
    2197
    +
    
    2198
    +        # close the window
    
    2199
    +        self.window.destroy()

  • gajim/search_window.py → gajim/gtk/discovery_search.py
    ... ... @@ -24,33 +24,25 @@ from gajim.common import ged
    24 24
     from gajim.common.modules import dataforms
    
    25 25
     from gajim.common.i18n import _
    
    26 26
     
    
    27
    -from gajim import gtkgui_helpers
    
    28 27
     from gajim import vcard
    
    29 28
     from gajim import config
    
    30 29
     from gajim import dataforms_widget
    
    30
    +
    
    31
    +from gajim.gtk.util import get_builder
    
    31 32
     from gajim.gtk.add_contact import AddNewContactWindow
    
    32 33
     
    
    33 34
     
    
    34 35
     class SearchWindow:
    
    35 36
         def __init__(self, account, jid):
    
    36
    -        """
    
    37
    -        Create new window
    
    38
    -        """
    
    39
    -        # an account object
    
    40 37
             self.account = account
    
    41 38
             self.jid = jid
    
    42 39
     
    
    43
    -        # retrieving widgets from xml
    
    44
    -        self.xml = gtkgui_helpers.get_gtk_builder('search_window.ui')
    
    45
    -        self.window = self.xml.get_object('search_window')
    
    46
    -        for name in ('label', 'progressbar', 'search_vbox', 'search_button',
    
    47
    -        'add_contact_button', 'information_button'):
    
    48
    -            self.__dict__[name] = self.xml.get_object(name)
    
    40
    +        self._ui = get_builder('search_window.ui')
    
    41
    +        self.window = self._ui.search_window
    
    49 42
     
    
    50
    -        self.search_button.set_sensitive(False)
    
    43
    +        self._ui.search_button.set_sensitive(False)
    
    51 44
     
    
    52
    -        # displaying the window
    
    53
    -        self.xml.connect_signals(self)
    
    45
    +        self._ui.connect_signals(self)
    
    54 46
             self.window.show_all()
    
    55 47
             self.request_form()
    
    56 48
             self.pulse_id = GLib.timeout_add(80, self.pulse_callback)
    
    ... ... @@ -60,36 +52,40 @@ class SearchWindow:
    60 52
             # Is there a jid column in results ? if -1: no, else column number
    
    61 53
             self.jid_column = -1
    
    62 54
     
    
    63
    -        app.ged.register_event_handler('search-form-received', ged.GUI1,
    
    64
    -            self._nec_search_form_received)
    
    65
    -        app.ged.register_event_handler('search-result-received', ged.GUI1,
    
    66
    -            self._nec_search_result_received)
    
    55
    +        app.ged.register_event_handler('search-form-received',
    
    56
    +                                       ged.GUI1,
    
    57
    +                                       self._nec_search_form_received)
    
    58
    +        app.ged.register_event_handler('search-result-received',
    
    59
    +                                       ged.GUI1,
    
    60
    +                                       self._nec_search_result_received)
    
    67 61
     
    
    68 62
         def request_form(self):
    
    69 63
             con = app.connections[self.account]
    
    70 64
             con.get_module('Search').request_search_fields(self.jid)
    
    71 65
     
    
    72 66
         def pulse_callback(self):
    
    73
    -        self.progressbar.pulse()
    
    67
    +        self._ui.progressbar.pulse()
    
    74 68
             return True
    
    75 69
     
    
    76
    -    def on_search_window_key_press_event(self, widget, event):
    
    70
    +    def on_search_window_key_press_event(self, _widget, event):
    
    77 71
             if event.keyval == Gdk.KEY_Escape:
    
    78 72
                 self.window.destroy()
    
    79 73
     
    
    80
    -    def on_search_window_destroy(self, widget):
    
    74
    +    def on_search_window_destroy(self, _widget):
    
    81 75
             if self.pulse_id:
    
    82 76
                 GLib.source_remove(self.pulse_id)
    
    83 77
             del app.interface.instances[self.account]['search'][self.jid]
    
    84
    -        app.ged.remove_event_handler('search-form-received', ged.GUI1,
    
    85
    -            self._nec_search_form_received)
    
    86
    -        app.ged.remove_event_handler('search-result-received', ged.GUI1,
    
    87
    -            self._nec_search_result_received)
    
    88
    -
    
    89
    -    def on_close_button_clicked(self, button):
    
    78
    +        app.ged.remove_event_handler('search-form-received',
    
    79
    +                                     ged.GUI1,
    
    80
    +                                     self._nec_search_form_received)
    
    81
    +        app.ged.remove_event_handler('search-result-received',
    
    82
    +                                     ged.GUI1,
    
    83
    +                                     self._nec_search_result_received)
    
    84
    +
    
    85
    +    def on_close_button_clicked(self, _button):
    
    90 86
             self.window.destroy()
    
    91 87
     
    
    92
    -    def on_search_button_clicked(self, button):
    
    88
    +    def on_search_button_clicked(self, _button):
    
    93 89
             con = app.connections[self.account]
    
    94 90
             if self.is_form:
    
    95 91
                 self.data_form_widget.data_form.type_ = 'submit'
    
    ... ... @@ -101,22 +97,22 @@ class SearchWindow:
    101 97
                     del infos['instructions']
    
    102 98
                 con.get_module('Search').send_search_form(self.jid, infos, False)
    
    103 99
     
    
    104
    -        self.search_vbox.remove(self.data_form_widget)
    
    100
    +        self._ui.search_vbox.remove(self.data_form_widget)
    
    105 101
     
    
    106
    -        self.progressbar.show()
    
    107
    -        self.label.set_text(_('Waiting for results'))
    
    108
    -        self.label.show()
    
    102
    +        self._ui.progressbar.show()
    
    103
    +        self._ui.label.set_text(_('Waiting for results'))
    
    104
    +        self._ui.label.show()
    
    109 105
             self.pulse_id = GLib.timeout_add(80, self.pulse_callback)
    
    110
    -        self.search_button.hide()
    
    106
    +        self._ui.search_button.hide()
    
    111 107
     
    
    112
    -    def on_add_contact_button_clicked(self, widget):
    
    108
    +    def on_add_contact_button_clicked(self, _widget):
    
    113 109
             (model, iter_) = self.result_treeview.get_selection().get_selected()
    
    114 110
             if not iter_:
    
    115 111
                 return
    
    116 112
             jid = model[iter_][self.jid_column]
    
    117 113
             AddNewContactWindow(self.account, jid)
    
    118 114
     
    
    119
    -    def on_information_button_clicked(self, widget):
    
    115
    +    def on_information_button_clicked(self, _widget):
    
    120 116
             (model, iter_) = self.result_treeview.get_selection().get_selected()
    
    121 117
             if not iter_:
    
    122 118
                 return
    
    ... ... @@ -131,8 +127,8 @@ class SearchWindow:
    131 127
         def _nec_search_form_received(self, obj):
    
    132 128
             if self.pulse_id:
    
    133 129
                 GLib.source_remove(self.pulse_id)
    
    134
    -        self.progressbar.hide()
    
    135
    -        self.label.hide()
    
    130
    +        self._ui.progressbar.hide()
    
    131
    +        self._ui.label.hide()
    
    136 132
     
    
    137 133
             if obj.is_dataform:
    
    138 134
                 self.is_form = True
    
    ... ... @@ -142,19 +138,19 @@ class SearchWindow:
    142 138
                 try:
    
    143 139
                     self.data_form_widget.data_form = self.dataform
    
    144 140
                 except dataforms.Error:
    
    145
    -                self.label.set_text(_('Error in received dataform'))
    
    146
    -                self.label.show()
    
    141
    +                self._ui.label.set_text(_('Error in received dataform'))
    
    142
    +                self._ui.label.show()
    
    147 143
                     return
    
    148 144
                 if self.data_form_widget.title:
    
    149
    -                self.window.set_title('%s - Search - Gajim' % \
    
    150
    -                        self.data_form_widget.title)
    
    145
    +                self.window.set_title(
    
    146
    +                    '%s - Search - Gajim' % self.data_form_widget.title)
    
    151 147
             else:
    
    152 148
                 self.is_form = False
    
    153 149
                 self.data_form_widget = config.FakeDataForm(obj.data)
    
    154 150
     
    
    155 151
             self.data_form_widget.show_all()
    
    156
    -        self.search_vbox.pack_start(self.data_form_widget, True, True, 0)
    
    157
    -        self.search_button.set_sensitive(True)
    
    152
    +        self._ui.search_vbox.pack_start(self.data_form_widget, True, True, 0)
    
    153
    +        self._ui.search_button.set_sensitive(True)
    
    158 154
     
    
    159 155
         def on_result_treeview_cursor_changed(self, treeview):
    
    160 156
             if self.jid_column == -1:
    
    ... ... @@ -163,29 +159,29 @@ class SearchWindow:
    163 159
             if not iter_:
    
    164 160
                 return
    
    165 161
             if model[iter_][self.jid_column]:
    
    166
    -            self.add_contact_button.set_sensitive(True)
    
    167
    -            self.information_button.set_sensitive(True)
    
    162
    +            self._ui.add_contact_button.set_sensitive(True)
    
    163
    +            self._ui.information_button.set_sensitive(True)
    
    168 164
             else:
    
    169
    -            self.add_contact_button.set_sensitive(False)
    
    170
    -            self.information_button.set_sensitive(False)
    
    165
    +            self._ui.add_contact_button.set_sensitive(False)
    
    166
    +            self._ui.information_button.set_sensitive(False)
    
    171 167
     
    
    172 168
         def _nec_search_result_received(self, obj):
    
    173 169
             if self.pulse_id:
    
    174 170
                 GLib.source_remove(self.pulse_id)
    
    175
    -        self.progressbar.hide()
    
    176
    -        self.label.hide()
    
    171
    +        self._ui.progressbar.hide()
    
    172
    +        self._ui.label.hide()
    
    177 173
     
    
    178 174
             if not obj.is_dataform:
    
    179 175
                 if not obj.data:
    
    180
    -                self.label.set_text(_('No result'))
    
    181
    -                self.label.show()
    
    176
    +                self._ui.label.set_text(_('No result'))
    
    177
    +                self._ui.label.show()
    
    182 178
                     return
    
    183 179
                 # We suppose all items have the same fields
    
    184 180
                 sw = Gtk.ScrolledWindow()
    
    185 181
                 sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
    
    186 182
                 self.result_treeview = Gtk.TreeView()
    
    187
    -            self.result_treeview.connect('cursor-changed',
    
    188
    -                self.on_result_treeview_cursor_changed)
    
    183
    +            self.result_treeview.connect(
    
    184
    +                'cursor-changed', self.on_result_treeview_cursor_changed)
    
    189 185
                 sw.add(self.result_treeview)
    
    190 186
                 # Create model
    
    191 187
                 fieldtypes = [str]*len(obj.data[0])
    
    ... ... @@ -196,39 +192,41 @@ class SearchWindow:
    196 192
                 # Create columns
    
    197 193
                 counter = 0
    
    198 194
                 for field in obj.data[0].keys():
    
    199
    -                self.result_treeview.append_column(Gtk.TreeViewColumn(field,
    
    200
    -                    Gtk.CellRendererText(), text=counter))
    
    195
    +                self.result_treeview.append_column(
    
    196
    +                    Gtk.TreeViewColumn(field,
    
    197
    +                                       Gtk.CellRendererText(),
    
    198
    +                                       text=counter))
    
    201 199
                     if field == 'jid':
    
    202 200
                         self.jid_column = counter
    
    203 201
                     counter += 1
    
    204 202
                 self.result_treeview.set_model(model)
    
    205 203
                 sw.show_all()
    
    206
    -            self.search_vbox.pack_start(sw, True, True, 0)
    
    204
    +            self._ui.search_vbox.pack_start(sw, True, True, 0)
    
    207 205
                 if self.jid_column > -1:
    
    208
    -                self.add_contact_button.show()
    
    209
    -                self.information_button.show()
    
    206
    +                self._ui.add_contact_button.show()
    
    207
    +                self._ui.information_button.show()
    
    210 208
                 return
    
    211 209
     
    
    212 210
             self.dataform = dataforms.extend_form(node=obj.data)
    
    213 211
             if not self.dataform.items:
    
    214 212
                 # No result
    
    215
    -            self.label.set_text(_('No result'))
    
    216
    -            self.label.show()
    
    213
    +            self._ui.label.set_text(_('No result'))
    
    214
    +            self._ui.label.show()
    
    217 215
                 return
    
    218 216
     
    
    219 217
             self.data_form_widget.set_sensitive(True)
    
    220 218
             try:
    
    221 219
                 self.data_form_widget.data_form = self.dataform
    
    222 220
             except dataforms.Error:
    
    223
    -            self.label.set_text(_('Error in received dataform'))
    
    224
    -            self.label.show()
    
    221
    +            self._ui.label.set_text(_('Error in received dataform'))
    
    222
    +            self._ui.label.show()
    
    225 223
                 return
    
    226 224
     
    
    227 225
             self.result_treeview = self.data_form_widget.records_treeview
    
    228 226
             selection = self.result_treeview.get_selection()
    
    229 227
             selection.set_mode(Gtk.SelectionMode.SINGLE)
    
    230
    -        self.result_treeview.connect('cursor-changed',
    
    231
    -            self.on_result_treeview_cursor_changed)
    
    228
    +        self.result_treeview.connect(
    
    229
    +            'cursor-changed', self.on_result_treeview_cursor_changed)
    
    232 230
     
    
    233 231
             counter = 0
    
    234 232
             for field in self.dataform.reported.iter_fields():
    
    ... ... @@ -236,11 +234,11 @@ class SearchWindow:
    236 234
                     self.jid_column = counter
    
    237 235
                     break
    
    238 236
                 counter += 1
    
    239
    -        self.search_vbox.pack_start(self.data_form_widget, True, True, 0)
    
    237
    +        self._ui.search_vbox.pack_start(self.data_form_widget, True, True, 0)
    
    240 238
             self.data_form_widget.show()
    
    241 239
             if self.jid_column > -1:
    
    242
    -            self.add_contact_button.show()
    
    243
    -            self.information_button.show()
    
    240
    +            self._ui.add_contact_button.show()
    
    241
    +            self._ui.information_button.show()
    
    244 242
             if self.data_form_widget.title:
    
    245
    -            self.window.set_title('%s - Search - Gajim' % \
    
    246
    -                self.data_form_widget.title)
    243
    +            self.window.set_title(
    
    244
    +                '%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
    50 50
     from gajim.gtk.filechoosers import FileSaveDialog
    
    51 51
     from gajim.gtk.filechoosers import FileChooserDialog
    
    52 52
     from gajim.gtk.tooltips import FileTransfersTooltip
    
    53
    +from gajim.gtk.util import get_builder
    
    53 54
     
    
    54 55
     log = logging.getLogger('gajim.filetransfer_window')
    
    55 56
     
    
    ... ... @@ -69,7 +70,7 @@ class FileTransfersWindow:
    69 70
         def __init__(self):
    
    70 71
             self.files_props = {'r' : {}, 's': {}}
    
    71 72
             self.height_diff = 0
    
    72
    -        self.xml = gtkgui_helpers.get_gtk_builder('filetransfers.ui')
    
    73
    +        self.xml = get_builder('filetransfers.ui')
    
    73 74
             self.window = self.xml.get_object('file_transfers_window')
    
    74 75
             self.tree = self.xml.get_object('transfers_list')
    
    75 76
             self.cancel_button = self.xml.get_object('cancel_button')
    
    ... ... @@ -80,8 +81,7 @@ class FileTransfersWindow:
    80 81
     
    
    81 82
             shall_notify = app.config.get('notify_on_file_complete')
    
    82 83
             self.notify_ft_checkbox.set_active(shall_notify)
    
    83
    -        self.model = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str, int,
    
    84
    -            int, str)
    
    84
    +        self.model = Gtk.ListStore(str, str, str, str, str, int, int, str)
    
    85 85
             self.tree.set_model(self.model)
    
    86 86
             col = Gtk.TreeViewColumn()
    
    87 87
     
    
    ... ... @@ -91,7 +91,7 @@ class FileTransfersWindow:
    91 91
             render_pixbuf.set_property('xpad', 3)
    
    92 92
             render_pixbuf.set_property('ypad', 3)
    
    93 93
             render_pixbuf.set_property('yalign', .0)
    
    94
    -        col.add_attribute(render_pixbuf, 'pixbuf', 0)
    
    94
    +        col.add_attribute(render_pixbuf, 'icon_name', 0)
    
    95 95
             self.tree.append_column(col)
    
    96 96
     
    
    97 97
             col = Gtk.TreeViewColumn(_('File'))
    
    ... ... @@ -133,7 +133,6 @@ class FileTransfersWindow:
    133 133
             col.set_expand(False)
    
    134 134
             self.tree.append_column(col)
    
    135 135
     
    
    136
    -        self.images = {}
    
    137 136
             self.icons = {
    
    138 137
                     'upload': 'go-up',
    
    139 138
                     'download': 'go-down',
    
    ... ... @@ -459,10 +458,6 @@ class FileTransfersWindow:
    459 458
                 on_response_cancel(account, file_props))
    
    460 459
             dialog.popup()
    
    461 460
     
    
    462
    -    def get_icon(self, ident):
    
    463
    -        return self.images.setdefault(ident,
    
    464
    -            gtkgui_helpers.get_icon_pixmap(self.icons[ident], 24))
    
    465
    -
    
    466 461
         def set_status(self, file_props, status):
    
    467 462
             """
    
    468 463
             Change the status of a transfer to state 'status'
    
    ... ... @@ -505,7 +500,7 @@ class FileTransfersWindow:
    505 500
                     helpers.convert_bytes(full_size)
    
    506 501
                 self.model.set(iter_, Column.PROGRESS, text)
    
    507 502
                 self.model.set(iter_, Column.PULSE, GLib.MAXINT32)
    
    508
    -        self.model.set(iter_, Column.IMAGE, self.get_icon(status))
    
    503
    +        self.model.set(iter_, Column.IMAGE, self.icons[status])
    
    509 504
             path = self.model.get_path(iter_)
    
    510 505
             self.select_func(path)
    
    511 506
     
    
    ... ... @@ -644,7 +639,7 @@ class FileTransfersWindow:
    644 639
                     status = 'waiting'
    
    645 640
                 if file_props.connected is False:
    
    646 641
                     status = 'stop'
    
    647
    -            self.model.set(iter_, 0, self.get_icon(status))
    
    642
    +            self.model.set(iter_, 0, self.icons[status])
    
    648 643
                 if transfered_size == full_size:
    
    649 644
                     # If we are receiver and this is a jingle session
    
    650 645
                     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:
    89 89
         return Builder(file_name, widgets)
    
    90 90
     
    
    91 91
     
    
    92
    +def icon_exists(name: str) -> bool:
    
    93
    +    return _icon_theme.has_icon(name)
    
    94
    +
    
    95
    +
    
    92 96
     def load_icon(icon_name, widget, size=16, pixbuf=False,
    
    93 97
                   flags=Gtk.IconLookupFlags.FORCE_SIZE):
    
    94 98
     
    

  • gajim/gtkgui_helpers.py
    ... ... @@ -75,16 +75,6 @@ def get_icon_pixmap(icon_name, size=16, color=None, quiet=False):
    75 75
             if not quiet:
    
    76 76
                 log.error('Unable to load icon %s: %s', icon_name, str(error))
    
    77 77
     
    
    78
    -def get_icon_path(icon_name, size=16):
    
    79
    -    try:
    
    80
    -        icon_info = gtk_icon_theme.lookup_icon(icon_name, size, 0)
    
    81
    -        if icon_info is None:
    
    82
    -            log.error('Icon not found: %s', icon_name)
    
    83
    -            return ''
    
    84
    -        return icon_info.get_filename()
    
    85
    -    except GLib.GError as error:
    
    86
    -        log.error('Unable to find icon %s: %s', icon_name, str(error))
    
    87
    -
    
    88 78
     
    
    89 79
     HAS_PYWIN32 = True
    
    90 80
     if os.name == 'nt':
    
    ... ... @@ -97,11 +87,6 @@ if os.name == 'nt':
    97 87
     
    
    98 88
     from gajim.common import helpers
    
    99 89
     
    
    100
    -def add_image_to_button(button, icon_name):
    
    101
    -    img = Gtk.Image()
    
    102
    -    path_img = get_icon_path(icon_name)
    
    103
    -    img.set_from_file(path_img)
    
    104
    -    button.set_image(img)
    
    105 90
     
    
    106 91
     def get_image_button(icon_name, tooltip, toggle=False):
    
    107 92
         if toggle:
    
    ... ... @@ -146,66 +131,6 @@ def get_gtk_builder(file_name, widget=None):
    146 131
                 builder.add_from_file(file_path)
    
    147 132
         return builder
    
    148 133
     
    
    149
    -def at_the_end(widget):
    
    150
    -    """Determines if a Scrollbar in a GtkScrolledWindow is at the end.
    
    151
    -
    
    152
    -    Args:
    
    153
    -        widget (GtkScrolledWindow)
    
    154
    -
    
    155
    -    Returns:
    
    156
    -        bool: The return value is True if at the end, False if not.
    
    157
    -    """
    
    158
    -    adj_v = widget.get_vadjustment()
    
    159
    -    max_scroll_pos = adj_v.get_upper() - adj_v.get_page_size()
    
    160
    -    return adj_v.get_value() == max_scroll_pos
    
    161
    -
    
    162
    -def scroll_to_end(widget):
    
    163
    -    """Scrolls to the end of a GtkScrolledWindow.
    
    164
    -
    
    165
    -    Args:
    
    166
    -        widget (GtkScrolledWindow)
    
    167
    -
    
    168
    -    Returns:
    
    169
    -        bool: The return value is False so it can be used with GLib.idle_add.
    
    170
    -    """
    
    171
    -    adj_v = widget.get_vadjustment()
    
    172
    -    if adj_v is None:
    
    173
    -        # This can happen when the Widget is already destroyed when called
    
    174
    -        # from GLib.idle_add
    
    175
    -        return False
    
    176
    -    max_scroll_pos = adj_v.get_upper() - adj_v.get_page_size()
    
    177
    -    adj_v.set_value(max_scroll_pos)
    
    178
    -
    
    179
    -    adj_h = widget.get_hadjustment()
    
    180
    -    adj_h.set_value(0)
    
    181
    -    return False
    
    182
    -
    
    183
    -
    
    184
    -class ServersXMLHandler(ContentHandler):
    
    185
    -    def __init__(self):
    
    186
    -        ContentHandler.__init__(self)
    
    187
    -        self.servers = []
    
    188
    -
    
    189
    -    def startElement(self, name, attributes):
    
    190
    -        if name == 'item':
    
    191
    -            if 'jid' in attributes.getNames():
    
    192
    -                self.servers.append(attributes.getValue('jid'))
    
    193
    -
    
    194
    -    def endElement(self, name):
    
    195
    -        pass
    
    196
    -
    
    197
    -def parse_server_xml(path_to_file):
    
    198
    -    try:
    
    199
    -        handler = ServersXMLHandler()
    
    200
    -        xml.sax.parse(path_to_file, handler)
    
    201
    -        return handler.servers
    
    202
    -    # handle exception if unable to open file
    
    203
    -    except IOError as message:
    
    204
    -        print(_('Error reading file:') + str(message), file=sys.stderr)
    
    205
    -    # handle exception parsing file
    
    206
    -    except xml.sax.SAXParseException as message:
    
    207
    -        print(_('Error parsing file:') + str(message), file=sys.stderr)
    
    208
    -
    
    209 134
     def set_unset_urgency_hint(window, unread_messages_no):
    
    210 135
         """
    
    211 136
         Sets/unset urgency hint in window argument depending if we have unread
    
    ... ... @@ -247,22 +172,6 @@ def get_cursor(attr):
    247 172
         cursor = getattr(Gdk.CursorType, attr)
    
    248 173
         return Gdk.Cursor.new_for_display(display, cursor)
    
    249 174
     
    
    250
    -def get_current_desktop(window):
    
    251
    -    """
    
    252
    -    Return the current virtual desktop for given window
    
    253
    -
    
    254
    -    NOTE: Window is a GDK window.
    
    255
    -    """
    
    256
    -    prop = window.property_get('_NET_CURRENT_DESKTOP')
    
    257
    -    if prop is None: # it means it's normal window (not root window)
    
    258
    -        # so we look for it's current virtual desktop in another property
    
    259
    -        prop = window.property_get('_NET_WM_DESKTOP')
    
    260
    -
    
    261
    -    if prop is not None:
    
    262
    -        # f.e. prop is ('CARDINAL', 32, [0]) we want 0 or 1.. from [0]
    
    263
    -        current_virtual_desktop_no = prop[2][0]
    
    264
    -        return current_virtual_desktop_no
    
    265
    -
    
    266 175
     def file_is_locked(path_to_file):
    
    267 176
         """
    
    268 177
         Return True if file is locked
    

  • gajim/gui_interface.py
    ... ... @@ -74,9 +74,7 @@ from gajim.chat_control import ChatControl
    74 74
     from gajim.groupchat_control import GroupchatControl
    
    75 75
     from gajim.groupchat_control import PrivateChatControl
    
    76 76
     from gajim.message_window import MessageWindowMgr
    
    77
    -from gajim.filetransfers_window import FileTransfersWindow
    
    78 77
     
    
    79
    -from gajim.atom_window import AtomWindow
    
    80 78
     from gajim.session import ChatControlSession
    
    81 79
     
    
    82 80
     from gajim.common import idle
    
    ... ... @@ -121,6 +119,8 @@ from gajim.gtk.filechoosers import FileChooserDialog
    121 119
     from gajim.gtk.emoji_data import emoji_data
    
    122 120
     from gajim.gtk.emoji_data import emoji_ascii_data
    
    123 121
     from gajim.gtk.groupchat_config import GroupchatConfig
    
    122
    +from gajim.gtk.atom import AtomWindow
    
    123
    +from gajim.gtk.filetransfer import FileTransfersWindow
    
    124 124
     
    
    125 125
     
    
    126 126
     parser = optparser.OptionsParser(configpaths.get('CONFIG_FILE'))
    

  • gajim/message_textview.py
    ... ... @@ -24,9 +24,12 @@ from gi.repository import GLib
    24 24
     from gi.repository import GObject
    
    25 25
     from gi.repository import Pango
    
    26 26
     
    
    27
    +from gajim import gtkgui_helpers
    
    28
    +
    
    27 29
     from gajim.common import app
    
    28 30
     from gajim.common.i18n import _
    
    29
    -from gajim import gtkgui_helpers
    
    31
    +
    
    32
    +from gajim.gtk.util import scroll_to_end
    
    30 33
     
    
    31 34
     if app.is_installed('GSPELL'):
    
    32 35
         from gi.repository import Gspell
    
    ... ... @@ -166,7 +169,7 @@ class MessageTextView(Gtk.TextView):
    166 169
             mark = buffer_.get_insert()
    
    167 170
             iter_ = buffer_.get_iter_at_mark(mark)
    
    168 171
             if iter_.get_offset() == buffer_.get_end_iter().get_offset():
    
    169
    -            GLib.idle_add(gtkgui_helpers.scroll_to_end, textview.get_parent())
    
    172
    +            GLib.idle_add(scroll_to_end, textview.get_parent())
    
    170 173
     
    
    171 174
         def make_clickable_urls(self, text):
    
    172 175
             _buffer = self.get_buffer()
    

  • gajim/plugins/gui.py
    ... ... @@ -21,25 +21,27 @@ GUI classes related to plug-in management.
    21 21
     :license: GPL
    
    22 22
     '''
    
    23 23
     
    
    24
    -__all__ = ['PluginsWindow']
    
    24
    +import os
    
    25
    +from enum import IntEnum
    
    26
    +from enum import unique
    
    25 27
     
    
    26 28
     from gi.repository import Gtk
    
    27 29
     from gi.repository import GdkPixbuf
    
    28 30
     from gi.repository import Gdk
    
    29
    -import os
    
    30 31
     
    
    31
    -from enum import IntEnum, unique
    
    32
    -
    
    33
    -from gajim import gtkgui_helpers
    
    34
    -from gajim.gtk.dialogs import WarningDialog
    
    35
    -from gajim.gtk.dialogs import YesNoDialog
    
    36
    -from gajim.gtk.filechoosers import ArchiveChooserDialog
    
    37 32
     from gajim.common import app
    
    38 33
     from gajim.common import configpaths
    
    34
    +from gajim.common.exceptions import PluginsystemError
    
    35
    +
    
    39 36
     from gajim.plugins.helpers import log_calls
    
    40 37
     from gajim.plugins.helpers import GajimPluginActivateException
    
    41 38
     from gajim.plugins.plugins_i18n import _
    
    42
    -from gajim.common.exceptions import PluginsystemError
    
    39
    +
    
    40
    +from gajim.gtk.dialogs import WarningDialog
    
    41
    +from gajim.gtk.dialogs import YesNoDialog
    
    42
    +from gajim.gtk.filechoosers import ArchiveChooserDialog
    
    43
    +from gajim.gtk.util import get_builder
    
    44
    +from gajim.gtk.util import load_icon
    
    43 45
     
    
    44 46
     
    
    45 47
     @unique
    
    ... ... @@ -57,7 +59,7 @@ class PluginsWindow:
    57 59
         @log_calls('PluginsWindow')
    
    58 60
         def __init__(self):
    
    59 61
             '''Initialize Plugins window'''
    
    60
    -        builder = gtkgui_helpers.get_gtk_builder('plugins_window.ui')
    
    62
    +        builder = get_builder('plugins_window.ui')
    
    61 63
             self.window = builder.get_object('plugins_window')
    
    62 64
             self.window.set_transient_for(app.interface.roster.window)
    
    63 65
     
    
    ... ... @@ -91,7 +93,9 @@ class PluginsWindow:
    91 93
                 activatable=Column.ACTIVATABLE)
    
    92 94
             self.installed_plugins_treeview.append_column(col)
    
    93 95
     
    
    94
    -        self.def_icon = gtkgui_helpers.get_icon_pixmap('preferences-desktop')
    
    96
    +        self.def_icon = load_icon('preferences-desktop',
    
    97
    +                                  self.window,
    
    98
    +                                  pixbuf=True)
    
    95 99
     
    
    96 100
             # connect signal for selection change
    
    97 101
             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
    46 46
     
    
    47 47
     from gajim import dialogs
    
    48 48
     from gajim import vcard
    
    49
    -from gajim import disco
    
    50 49
     from gajim import gtkgui_helpers
    
    51 50
     from gajim import gui_menu_builder
    
    52 51
     from gajim import cell_renderer_image
    
    53 52
     from gajim import message_control
    
    54
    -from gajim import adhoc_commands
    
    55 53
     
    
    56 54
     from gajim.common import app
    
    57 55
     from gajim.common import helpers
    
    ... ... @@ -79,9 +77,11 @@ from gajim.gtk.pep_config import ManagePEPServicesWindow
    79 77
     from gajim.gtk.bookmarks import ManageBookmarksWindow
    
    80 78
     from gajim.gtk.account_wizard import AccountCreationWizard
    
    81 79
     from gajim.gtk.service_registration import ServiceRegistration
    
    80
    +from gajim.gtk.discovery import ServiceDiscoveryWindow
    
    82 81
     from gajim.gtk.history import HistoryWindow
    
    83 82
     from gajim.gtk.accounts import AccountsWindow
    
    84 83
     from gajim.gtk.tooltips import RosterTooltip
    
    84
    +from gajim.gtk.adhoc_commands import CommandWindow
    
    85 85
     from gajim.gtk.util import get_icon_name
    
    86 86
     from gajim.gtk.util import resize_window
    
    87 87
     from gajim.gtk.util import move_window
    
    ... ... @@ -3702,7 +3702,7 @@ class RosterWindow:
    3702 3702
             jid = contact.jid
    
    3703 3703
             if resource is not None:
    
    3704 3704
                 jid = jid + '/' + resource
    
    3705
    -        adhoc_commands.CommandWindow(account, jid)
    
    3705
    +        CommandWindow(account, jid)
    
    3706 3706
     
    
    3707 3707
         def on_roster_window_focus_in_event(self, widget, event):
    
    3708 3708
             # roster received focus, so if we had urgency REMOVE IT
    
    ... ... @@ -4035,7 +4035,7 @@ class RosterWindow:
    4035 4035
             else:
    
    4036 4036
                 try:
    
    4037 4037
                     # Object will add itself to the window dict
    
    4038
    -                disco.ServiceDiscoveryWindow(account, address_entry=True)
    
    4038
    +                ServiceDiscoveryWindow(account, address_entry=True)
    
    4039 4039
                 except GajimGeneralException:
    
    4040 4040
                     pass
    
    4041 4041