diff --git a/gajim/config.py b/gajim/config.py index 82b46fe3f..ff03264b3 100644 --- a/gajim/config.py +++ b/gajim/config.py @@ -33,7 +33,6 @@ from gi.repository import GObject from gajim.common import app from gajim.common.i18n import _ -from gajim import gtkgui_helpers from gajim import dialogs from gajim import gui_menu_builder @@ -41,6 +40,7 @@ from gajim import gui_menu_builder from gajim.gtk.dialogs import ConfirmationDialog from gajim.gtk.dialogs import ConfirmationDialogDoubleRadio from gajim.gtk.dialogs import ErrorDialog +from gajim.gtk.util import get_builder class FakeDataForm(Gtk.Table): @@ -110,7 +110,7 @@ class RemoveAccountWindow: def __init__(self, account): self.account = account - xml = gtkgui_helpers.get_gtk_builder('remove_account_window.ui') + xml = get_builder('remove_account_window.ui') self.window = xml.get_object('remove_account_window') active_window = app.app.get_active_window() self.window.set_transient_for(active_window) diff --git a/gajim/dataforms_widget.py b/gajim/dataforms_widget.py index f19d35668..8e8515a40 100644 --- a/gajim/dataforms_widget.py +++ b/gajim/dataforms_widget.py @@ -36,6 +36,8 @@ from gajim.common import helpers from gajim.common import app from gajim.common.i18n import _ +from gajim.gtk.util import get_builder + class DataFormWidget(Gtk.Alignment): # "public" interface @@ -54,8 +56,7 @@ class DataFormWidget(Gtk.Alignment): self.selectable = False self.clean_cb = None - self.xml = gtkgui_helpers.get_gtk_builder('data_form_window.ui', - 'data_form_vbox') + self.xml = get_builder('data_form_window.ui', ['data_form_vbox']) self.xml.connect_signals(self) for name in ('instructions_label', 'instructions_hseparator', 'single_form_viewport', 'data_form_types_notebook', @@ -453,8 +454,7 @@ class SingleForm(Gtk.Table): elif field.type_ == 'jid-multi': commonwidget = False - xml = gtkgui_helpers.get_gtk_builder('data_form_window.ui', - 'multiple_form_hbox') + xml = get_builder('data_form_window.ui', ['multiple_form_hbox']) widget = xml.get_object('multiple_form_hbox') treeview = xml.get_object('records_treeview') diff --git a/gajim/dialogs.py b/gajim/dialogs.py index e2cde1d06..f0fe8bdb5 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -57,6 +57,7 @@ from gajim.gtk.dialogs import * from gajim.gtk.add_contact import AddNewContactWindow from gajim.gtk.util import get_icon_name from gajim.gtk.util import resize_window +from gajim.gtk.util import get_builder log = logging.getLogger('gajim.dialogs') @@ -71,7 +72,7 @@ class EditGroupsDialog: """ list_ is a list of (contact, account) tuples """ - self.xml = gtkgui_helpers.get_gtk_builder('edit_groups_dialog.ui') + self.xml = get_builder('edit_groups_dialog.ui') self.dialog = self.xml.get_object('edit_groups_dialog') self.dialog.set_transient_for(app.interface.roster.window) self.list_ = list_ @@ -221,7 +222,7 @@ class PassphraseDialog: """ def __init__(self, titletext, labeltext, checkbuttontext=None, ok_handler=None, cancel_handler=None, transient_for=None): - self.xml = gtkgui_helpers.get_gtk_builder('passphrase_dialog.ui') + self.xml = get_builder('passphrase_dialog.ui') self.window = self.xml.get_object('passphrase_dialog') self.passphrase_entry = self.xml.get_object('passphrase_entry') self.passphrase = -1 @@ -287,7 +288,7 @@ class ChooseGPGKeyDialog: selected=None, transient_for=None): '''secret_keys : {keyID: userName, ...}''' self.on_response = on_response - xml = gtkgui_helpers.get_gtk_builder('choose_gpg_key_dialog.ui') + xml = get_builder('choose_gpg_key_dialog.ui') self.window = xml.get_object('choose_gpg_key_dialog') self.window.set_title(title_text) self.window.set_transient_for(transient_for) @@ -356,7 +357,7 @@ class ChangeActivityDialog: self.activity = activity_ self.subactivity = subactivity_ self.text = text - self.xml = gtkgui_helpers.get_gtk_builder('change_activity_dialog.ui') + self.xml = get_builder('change_activity_dialog.ui') self.window = self.xml.get_object('change_activity_dialog') self.window.set_transient_for(app.interface.roster.window) @@ -477,7 +478,7 @@ class ChangeMoodDialog: self.on_response = on_response self.mood = mood_ self.text = text - self.xml = gtkgui_helpers.get_gtk_builder('change_mood_dialog.ui') + self.xml = get_builder('change_mood_dialog.ui') self.window = self.xml.get_object('change_mood_dialog') self.window.set_transient_for(app.interface.roster.window) @@ -595,7 +596,7 @@ class ChangeStatusMessageDialog(TimeoutDialog): self.pep_dict = {} self.show_pep = show_pep self.on_response = on_response - self.xml = gtkgui_helpers.get_gtk_builder('change_status_message_dialog.ui') + self.xml = get_builder('change_status_message_dialog.ui') self.dialog = self.xml.get_object('change_status_message_dialog') self.dialog.set_transient_for(app.interface.roster.window) msg = None @@ -848,7 +849,7 @@ class SubscriptionRequestWindow(Gtk.ApplicationWindow): self.set_position(Gtk.WindowPosition.CENTER) self.set_title(_('Subscription Request')) - xml = gtkgui_helpers.get_gtk_builder('subscription_request_window.ui') + xml = get_builder('subscription_request_window.ui') self.add(xml.get_object('subscription_box')) self.jid = jid self.account = account @@ -929,7 +930,7 @@ class SynchroniseSelectAccountDialog: _('Without a connection, you can not synchronise your contacts.')) raise GajimGeneralException('You are not connected to the server') self.account = account - self.xml = gtkgui_helpers.get_gtk_builder('synchronise_select_account_dialog.ui') + self.xml = get_builder('synchronise_select_account_dialog.ui') self.dialog = self.xml.get_object('synchronise_select_account_dialog') self.dialog.set_transient_for(app.get_app_window('AccountsWindow')) self.accounts_treeview = self.xml.get_object('accounts_treeview') @@ -995,8 +996,7 @@ class SynchroniseSelectContactsDialog: def __init__(self, account, remote_account): self.local_account = account self.remote_account = remote_account - self.xml = gtkgui_helpers.get_gtk_builder( - 'synchronise_select_contacts_dialog.ui') + self.xml = get_builder('synchronise_select_contacts_dialog.ui') self.dialog = self.xml.get_object('synchronise_select_contacts_dialog') self.contacts_treeview = self.xml.get_object('contacts_treeview') model = Gtk.ListStore(bool, str) @@ -1081,8 +1081,7 @@ class RosterItemExchangeWindow: show_dialog = False # Connect to gtk builder - self.xml = gtkgui_helpers.get_gtk_builder( - 'roster_item_exchange_window.ui') + self.xml = get_builder('roster_item_exchange_window.ui') self.window = self.xml.get_object('roster_item_exchange_window') # Add Widgets. @@ -1345,7 +1344,7 @@ class ProgressDialog: During text is what to show during the procedure, messages_queue has the message to show in the textview """ - self.xml = gtkgui_helpers.get_gtk_builder('progress_dialog.ui') + self.xml = get_builder('progress_dialog.ui') self.dialog = self.xml.get_object('progress_dialog') self.label = self.xml.get_object('label') self.label.set_markup('' + during_text + '') @@ -1382,7 +1381,7 @@ class TransformChatToMUC: self.auto_jids = jids self.preselected_jids = preselected - self.xml = gtkgui_helpers.get_gtk_builder('chat_to_muc_window.ui') + self.xml = get_builder('chat_to_muc_window.ui') self.window = self.xml.get_object('chat_to_muc_window') for widget_to_add in ('invite_button', 'cancel_button', @@ -1600,7 +1599,7 @@ class VoIPCallReceivedDialog: self.sid = sid self.content_types = content_types - xml = gtkgui_helpers.get_gtk_builder('voip_call_received_dialog.ui') + xml = get_builder('voip_call_received_dialog.ui') xml.connect_signals(self) jid = app.get_jid_without_resource(self.fjid) @@ -1740,8 +1739,7 @@ class ProgressWindow(Gtk.ApplicationWindow): self.event = file.event self.file = file - self.xml = gtkgui_helpers.get_gtk_builder( - 'httpupload_progress_dialog.ui') + self.xml = get_builder('httpupload_progress_dialog.ui') self.label = self.xml.get_object('label') self.progressbar = self.xml.get_object('progressbar') diff --git a/gajim/groupchat_control.py b/gajim/groupchat_control.py index b3481b8e0..aefb33764 100644 --- a/gajim/groupchat_control.py +++ b/gajim/groupchat_control.py @@ -77,6 +77,7 @@ 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_affiliation_surface +from gajim.gtk.util import get_builder log = logging.getLogger('gajim.groupchat_control') @@ -2635,7 +2636,7 @@ class GroupchatControl(ChatControlBase): user_role = self.get_role(user_nick) # making menu from gtk builder - xml = gtkgui_helpers.get_gtk_builder('gc_occupants_menu.ui') + xml = get_builder('gc_occupants_menu.ui') # these conditions were taken from JEP 0045 item = xml.get_object('kick_menuitem') diff --git a/gajim/gtk/accounts.py b/gajim/gtk/accounts.py index d48a33fbb..b39f7804b 100644 --- a/gajim/gtk/accounts.py +++ b/gajim/gtk/accounts.py @@ -29,7 +29,6 @@ from gajim.common.const import Option from gajim.common.const import OptionKind from gajim.common.const import OptionType -from gajim import gtkgui_helpers from gajim import gui_menu_builder from gajim import config @@ -39,6 +38,7 @@ from gajim.options_dialog import OptionsBox from gajim.gtk.dialogs import ConfirmationDialog from gajim.gtk.dialogs import YesNoDialog from gajim.gtk.util import get_icon_name +from gajim.gtk.util import get_builder class AccountsWindow(Gtk.ApplicationWindow): @@ -53,14 +53,11 @@ class AccountsWindow(Gtk.ApplicationWindow): self.set_title(_('Accounts')) self.need_relogin = {} - glade_objects = ['stack', 'box', 'account_list'] - self.builder = gtkgui_helpers.get_gtk_builder('accounts_window.ui') - for obj in glade_objects: - setattr(self, obj, self.builder.get_object(obj)) + self._ui = get_builder('accounts_window.ui') - self.account_list.add(Preferences(self)) + self._ui.account_list.add(Preferences(self)) account_item = AddAccount() - self.account_list.add(account_item) + self._ui.account_list.add(account_item) account_item.set_activatable() accounts = app.config.get_per('accounts') @@ -68,11 +65,11 @@ class AccountsWindow(Gtk.ApplicationWindow): for account in accounts: self.need_relogin[account] = self.get_relogin_options(account) account_item = Account(account, self) - self.account_list.add(account_item) + self._ui.account_list.add(account_item) account_item.set_activatable() - self.add(self.box) - self.builder.connect_signals(self) + self.add(self._ui.box) + self._ui.connect_signals(self) self.connect('destroy', self.on_destroy) self.connect('key-press-event', self.on_key_press) @@ -87,9 +84,9 @@ class AccountsWindow(Gtk.ApplicationWindow): self.update_accounts() def _activate_preferences_page(self): - row = self.account_list.get_row_at_index(0) - self.account_list.select_row(row) - self.account_list.emit('row-activated', row) + row = self._ui.account_list.get_row_at_index(0) + self._ui.account_list.select_row(row) + self._ui.account_list.emit('row-activated', row) def on_key_press(self, widget, event): if event.keyval == Gdk.KEY_Escape: @@ -108,7 +105,7 @@ class AccountsWindow(Gtk.ApplicationWindow): self.check_relogin() def update_accounts(self): - for row in self.account_list.get_children(): + for row in self._ui.account_list.get_children(): row.get_child().update() @staticmethod @@ -116,18 +113,18 @@ class AccountsWindow(Gtk.ApplicationWindow): row.get_child().on_row_activated() def remove_all_pages(self): - for page in self.stack.get_children(): - self.stack.remove(page) + for page in self._ui.stack.get_children(): + self._ui.stack.remove(page) def set_page(self, page, name): self.remove_all_pages() - self.stack.add_named(page, name) + self._ui.stack.add_named(page, name) page.update() page.show_all() - self.stack.set_visible_child(page) + self._ui.stack.set_visible_child(page) def update_proxy_list(self): - page = self.stack.get_child_by_name('connection') + page = self._ui.stack.get_child_by_name('connection') if page is None: return page.listbox.get_option('proxy').update_values() @@ -231,26 +228,26 @@ class AccountsWindow(Gtk.ApplicationWindow): remove(account) def remove_account(self, account): - for row in self.account_list.get_children(): + for row in self._ui.account_list.get_children(): if row.get_child().account == account: - self.account_list.remove(row) + self._ui.account_list.remove(row) del self.need_relogin[account] break self._activate_preferences_page() def add_account(self, account): account_item = Account(account, self) - self.account_list.add(account_item) + self._ui.account_list.add(account_item) account_item.set_activatable() - self.account_list.show_all() - self.stack.show_all() + self._ui.account_list.show_all() + self._ui.stack.show_all() self.need_relogin[account] = self.get_relogin_options(account) def select_account(self, account): - for row in self.account_list.get_children(): + for row in self._ui.account_list.get_children(): if row.get_child().account == account: - self.account_list.select_row(row) - self.account_list.emit('row-activated', row) + self._ui.account_list.select_row(row) + self._ui.account_list.emit('row-activated', row) break @staticmethod diff --git a/gajim/gtk/filetransfer.py b/gajim/gtk/filetransfer.py index 4789de7b2..a05e97e9d 100644 --- a/gajim/gtk/filetransfer.py +++ b/gajim/gtk/filetransfer.py @@ -1015,20 +1015,16 @@ class SendFileDialog(Gtk.ApplicationWindow): self._send_callback = send_callback - xml = gtkgui_helpers.get_gtk_builder('send_file_dialog.ui') - grid = xml.get_object('send_file_grid') + self._ui = get_builder('send_file_dialog.ui') - self._filebox = xml.get_object('listbox') - self._description = xml.get_object('description') - - self.add(grid) + self.add(self._ui.send_file_grid) self.connect('key-press-event', self._key_press_event) - xml.connect_signals(self) + self._ui.connect_signals(self) self.show_all() def _send(self, button): - for file in self._filebox.get_children(): + for file in self._ui.listbox.get_children(): self._send_callback(str(file.path), self._get_description()) self.destroy() @@ -1040,22 +1036,22 @@ class SendFileDialog(Gtk.ApplicationWindow): def _set_files(self, filenames): # Clear the ListBox - self._filebox.foreach(self._remove_widget, None) + self._ui.listbox.foreach(self._remove_widget, None) for file in filenames: row = FileRow(file) if row.path.is_dir(): continue last_dir = row.path.parent - self._filebox.add(row) - self._filebox.show_all() + self._ui.listbox.add(row) + self._ui.listbox.show_all() app.config.set('last_send_dir', str(last_dir)) def _remove_widget(self, widget, data): - self._filebox.remove(widget) + self._ui.listbox.remove(widget) def _get_description(self): - buffer_ = self._description.get_buffer() + buffer_ = self._ui.description.get_buffer() start, end = buffer_.get_bounds() return buffer_.get_text(start, end, False) diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py index 69e0dc7fd..1cbf994bc 100644 --- a/gajim/gtkgui_helpers.py +++ b/gajim/gtkgui_helpers.py @@ -24,11 +24,9 @@ # along with Gajim. If not, see . import os -import sys import math import logging from io import BytesIO -import xml.etree.ElementTree as ET from gi.repository import Gtk from gi.repository import Gdk @@ -41,11 +39,21 @@ try: except Exception: pass -from gajim.common import i18n from gajim.common.i18n import _ from gajim.common import app -from gajim.common import configpaths -from gajim.common.const import PEPEventType, ACTIVITIES, MOODS +from gajim.common import helpers +from gajim.common.const import PEPEventType +from gajim.common.const import ACTIVITIES +from gajim.common.const import MOODS + +HAS_PYWIN32 = True +if os.name == 'nt': + try: + import win32file + import win32con + import pywintypes + except ImportError: + HAS_PYWIN32 = False log = logging.getLogger('gajim.gtkgui_helpers') @@ -58,48 +66,6 @@ class Color: ORANGE = Gdk.RGBA(red=245/255, green=121/255, blue=0/255, alpha=1) -HAS_PYWIN32 = True -if os.name == 'nt': - try: - import win32file - import win32con - import pywintypes - except ImportError: - HAS_PYWIN32 = False - -from gajim.common import helpers - - -def get_gtk_builder(file_name, widget=None): - file_path = os.path.join(configpaths.get('GUI'), file_name) - - builder = Gtk.Builder() - builder.set_translation_domain(i18n.DOMAIN) - - if sys.platform == "win32": - # This is a workaround for non working translation on Windows - tree = ET.parse(file_path) - for node in tree.iter(): - if 'translatable' in node.attrib and node.text is not None: - node.text = _(node.text) - xml_text = ET.tostring(tree.getroot(), - encoding='unicode', - method='xml') - - if widget is not None: - builder.add_objects_from_string(xml_text, [widget]) - else: - # Workaround - # https://gitlab.gnome.org/GNOME/pygobject/issues/255 - Gtk.Builder.__mro__[1].add_from_string( - builder, xml_text, len(xml_text.encode("utf-8"))) - else: - if widget is not None: - builder.add_objects_from_file(file_path, [widget]) - else: - builder.add_from_file(file_path) - return builder - def set_unset_urgency_hint(window, unread_messages_no): """ Sets/unset urgency hint in window argument depending if we have unread diff --git a/gajim/gui_menu_builder.py b/gajim/gui_menu_builder.py index f84d6c804..27e9c5f66 100644 --- a/gajim/gui_menu_builder.py +++ b/gajim/gui_menu_builder.py @@ -26,6 +26,8 @@ from gajim.common import helpers from gajim.common.i18n import ngettext from gajim.common.i18n import _ +from gajim.gtk.util import get_builder + def build_resources_submenu(contacts, account, action, room_jid=None, room_account=None, cap=None): @@ -208,7 +210,7 @@ control=None, gc_contact=None, is_anonymous=True): our_jid = jid == app.get_jid_from_account(account) roster = app.interface.roster - xml = gtkgui_helpers.get_gtk_builder('contact_context_menu.ui') + xml = get_builder('contact_context_menu.ui') contact_context_menu = xml.get_object('contact_context_menu') start_chat_menuitem = xml.get_object('start_chat_menuitem') diff --git a/gajim/message_control.py b/gajim/message_control.py index 0b5c673ca..d84d96317 100644 --- a/gajim/message_control.py +++ b/gajim/message_control.py @@ -22,13 +22,14 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . -from gajim import gtkgui_helpers import uuid from gajim.common import app from gajim.common import helpers from gajim.common import ged +from gajim.gtk.util import get_builder + # Derived types MUST register their type IDs here if custom behavor is required TYPE_CHAT = 'chat' TYPE_GC = 'gc' @@ -60,7 +61,7 @@ class MessageControl: app.last_message_time[self.account][self.get_full_jid()] = 0 - self.xml = gtkgui_helpers.get_gtk_builder('%s.ui' % widget_name) + self.xml = get_builder('%s.ui' % widget_name) self.xml.connect_signals(self) self.widget = self.xml.get_object('%s_hbox' % widget_name) diff --git a/gajim/message_window.py b/gajim/message_window.py index 1132548f7..cb23c2c53 100644 --- a/gajim/message_window.py +++ b/gajim/message_window.py @@ -45,6 +45,7 @@ from gajim.gtk.util import get_icon_name from gajim.gtk.util import resize_window from gajim.gtk.util import move_window from gajim.gtk.util import get_app_icon_list +from gajim.gtk.util import get_builder #################### @@ -80,7 +81,7 @@ class MessageWindow: self.dont_warn_on_delete = False self.widget_name = 'message_window' - self.xml = gtkgui_helpers.get_gtk_builder('%s.ui' % self.widget_name) + self.xml = get_builder('%s.ui' % self.widget_name) self.window = self.xml.get_object(self.widget_name) self.window.set_application(app.app) self.notebook = self.xml.get_object('notebook') @@ -300,7 +301,7 @@ class MessageWindow: ctrl.scroll_to_end() # Add notebook page and connect up to the tab's close button - xml = gtkgui_helpers.get_gtk_builder('message_window.ui', 'chat_tab_ebox') + xml = get_builder('message_window.ui', ['chat_tab_ebox']) tab_label_box = xml.get_object('chat_tab_ebox') widget = xml.get_object('tab_close_button') # this reduces the size of the button diff --git a/gajim/roster_window.py b/gajim/roster_window.py index 5145b14fb..a04f6afb2 100644 --- a/gajim/roster_window.py +++ b/gajim/roster_window.py @@ -84,6 +84,7 @@ from gajim.gtk.util import get_icon_name from gajim.gtk.util import resize_window from gajim.gtk.util import move_window from gajim.gtk.util import get_metacontact_surface +from gajim.gtk.util import get_builder log = logging.getLogger('gajim.roster') @@ -4873,7 +4874,7 @@ class RosterWindow: # we have to create our own set of icons for the menu # using self.jabber_status_images is poopoo if not app.config.get_per('accounts', account, 'is_zeroconf'): - xml = gtkgui_helpers.get_gtk_builder('account_context_menu.ui') + xml = get_builder('account_context_menu.ui') account_context_menu = xml.get_object('account_context_menu') status_menuitem = xml.get_object('status_menuitem') @@ -4982,7 +4983,7 @@ class RosterWindow: pep_menuitem): widget.set_sensitive(False) else: - xml = gtkgui_helpers.get_gtk_builder('zeroconf_context_menu.ui') + xml = get_builder('zeroconf_context_menu.ui') account_context_menu = xml.get_object('zeroconf_context_menu') status_menuitem = xml.get_object('status_menuitem') @@ -5368,7 +5369,7 @@ class RosterWindow: """ Add FOR ACCOUNT options """ - xml = gtkgui_helpers.get_gtk_builder('advanced_menuitem_menu.ui') + xml = get_builder('advanced_menuitem_menu.ui') advanced_menuitem_menu = xml.get_object('advanced_menuitem_menu') xml_console_menuitem = xml.get_object('xml_console_menuitem') @@ -5618,7 +5619,7 @@ class RosterWindow: GdkPixbuf.Pixbuf, GdkPixbuf.Pixbuf, str, str, Gtk.Image, str, bool] - self.xml = gtkgui_helpers.get_gtk_builder('roster_window.ui') + self.xml = get_builder('roster_window.ui') self.window = self.xml.get_object('roster_window') application.add_window(self.window) self.add_actions() diff --git a/gajim/vcard.py b/gajim/vcard.py index 08de87f76..cbed78e4a 100644 --- a/gajim/vcard.py +++ b/gajim/vcard.py @@ -43,6 +43,8 @@ from gajim.common.i18n import Q_ from gajim.common.i18n import _ from gajim.common.const import AvatarSize +from gajim.gtk.util import get_builder + # log = logging.getLogger('gajim.vcard') @@ -53,7 +55,7 @@ class VcardWindow: def __init__(self, contact, account, gc_contact=None): # the contact variable is the jid if vcard is true - self.xml = gtkgui_helpers.get_gtk_builder('vcard_information_window.ui') + self.xml = get_builder('vcard_information_window.ui') self.window = self.xml.get_object('vcard_information_window') self.progressbar = self.xml.get_object('progressbar') @@ -479,7 +481,7 @@ class VcardWindow: class ZeroconfVcardWindow: def __init__(self, contact, account, is_fake=False): # the contact variable is the jid if vcard is true - self.xml = gtkgui_helpers.get_gtk_builder('zeroconf_information_window.ui') + self.xml = get_builder('zeroconf_information_window.ui') self.window = self.xml.get_object('zeroconf_information_window') self.contact = contact