...
 
Commits (14)
......@@ -382,6 +382,7 @@
<property name="spacing">5</property>
<child>
<object class="GtkEventBox" id="banner_eventbox">
<property name="name">ChatControl-BannerEventBox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
......@@ -411,6 +412,7 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="banner_name_label">
<property name="name">ChatControl-BannerNameLabel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">&lt;span weight="heavy" size="large"&gt;Contact name&lt;/span&gt;</property>
......@@ -425,6 +427,7 @@
</child>
<child>
<object class="GtkLabel" id="banner_label">
<property name="name">ChatControl-BannerLabel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">label</property>
......@@ -603,6 +606,7 @@
<property name="spacing">3</property>
<child>
<object class="GtkButton" id="authentication_button">
<property name="name">ChatControl-AuthenticationButton</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
......
......@@ -20,6 +20,7 @@
<property name="spacing">5</property>
<child>
<object class="GtkEventBox" id="banner_eventbox">
<property name="name">GroupChatControl-BannerEventBox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
......@@ -48,6 +49,7 @@
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="banner_name_label">
<property name="name">GroupChatControl-BannerNameLabel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">&lt;span weight="heavy" size="large"&gt;room jid&lt;/span&gt;</property>
......@@ -62,6 +64,7 @@
</child>
<child>
<object class="GtkLabel" id="banner_label">
<property name="name">GroupChatControl-BannerLabel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">label</property>
......
......@@ -24,6 +24,7 @@
<property name="spacing">6</property>
<child>
<object class="GtkEventBox" id="banner_agent_eventbox">
<property name="name">Discovery-BannerEventBox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
......@@ -33,6 +34,7 @@
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="banner_agent_label">
<property name="name">Discovery-BannerLabel</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="ypad">6</property>
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="vcard_information_window">
......@@ -914,6 +914,9 @@
<property name="halign">start</property>
<property name="relief">none</property>
<property name="xalign">0</property>
<style>
<class name="VCard-GtkLinkButton"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -929,6 +932,9 @@
<property name="receives_default">True</property>
<property name="relief">none</property>
<property name="xalign">0</property>
<style>
<class name="VCard-GtkLinkButton"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
......@@ -1327,6 +1333,9 @@
<property name="halign">start</property>
<property name="relief">none</property>
<property name="xalign">0</property>
<style>
<class name="VCard-GtkLinkButton"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
......
/* Gajim Application CSS File */
/* ChatControl */
#ChatControl-AuthenticationButton { padding-top: 0px; padding-bottom: 0px}
/* VCardWindow */
.VCard-GtkLinkButton { padding-left: 5px; border-left: none; }
\ No newline at end of file
......@@ -157,15 +157,6 @@ class ChatControl(ChatControlBase):
# Add lock image to show chat encryption
self.lock_image = self.xml.get_object('lock_image')
# Remove padding from authentication button or else it will
# be higher than the message box
style_provider = Gtk.CssProvider()
css = 'GtkButton { padding-top: 0px; padding-bottom: 0px}'
style_provider.load_from_data(css.encode())
context = self.authentication_button.get_style_context()
context.add_provider(style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER)
# Convert to GC icon
img = self.xml.get_object('convert_to_gc_button_image')
img.set_from_pixbuf(gtkgui_helpers.load_icon(
......@@ -1024,8 +1015,8 @@ class ChatControl(ChatControlBase):
displaymarking = None
if self.correcting:
self.correcting = False
self.msg_textview.override_background_color(
Gtk.StateType.NORMAL, self.old_message_tv_color)
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.print_conversation(message, self.contact.jid,
encrypted=encrypted, xep0184_id=xep0184_id, xhtml=xhtml,
......@@ -1226,7 +1217,7 @@ class ChatControl(ChatControlBase):
else:
self.old_msg_kind = kind
def get_tab_label(self, chatstate):
def get_tab_label(self):
unread = ''
if self.resource:
jid = self.contact.get_full_jid()
......@@ -1239,48 +1230,13 @@ class ChatControl(ChatControlBase):
elif num_unread > 1:
unread = '[' + str(num_unread) + ']'
# Draw tab label using chatstate
theme = gajim.config.get('roster_theme')
color_s = None
if not chatstate:
chatstate = self.contact.chatstate
if chatstate is not None:
if chatstate == 'composing':
color_s = gajim.config.get_per('themes', theme,
'state_composing_color')
elif chatstate == 'inactive':
color_s = gajim.config.get_per('themes', theme,
'state_inactive_color')
elif chatstate == 'gone':
color_s = gajim.config.get_per('themes', theme,
'state_gone_color')
elif chatstate == 'paused':
color_s = gajim.config.get_per('themes', theme,
'state_paused_color')
context = self.parent_win.notebook.get_style_context()
if color_s:
# We set the color for when it's the current tab or not
color = Gdk.RGBA()
ok = Gdk.RGBA.parse(color, color_s)
if not ok:
del color
color = context.get_color(Gtk.StateFlags.ACTIVE)
# In inactive tab color to be lighter against the darker inactive
# background
if chatstate in ('inactive', 'gone') and\
self.parent_win.get_active_control() != self:
color = self.lighten_color(color)
else: # active or not chatstate, get color from gtk
color = context.get_color(Gtk.StateFlags.ACTIVE)
name = self.contact.get_shown_name()
if self.resource:
name += '/' + self.resource
label_str = GLib.markup_escape_text(name)
if num_unread: # if unread, text in the label becomes bold
label_str = '<b>' + unread + label_str + '</b>'
return (label_str, color)
return label_str
def get_tab_image(self, count_unread=True):
if self.resource:
......
......@@ -54,6 +54,13 @@ from common.connection_handlers_events import MessageOutgoingEvent
from command_system.implementation.middleware import ChatCommandProcessor
from command_system.implementation.middleware import CommandTools
# The members of these modules are not referenced directly anywhere in this
# module, but still they need to be kept around. Importing them automatically
# registers the contained CommandContainers with the command system, thereby
# populating the list of available commands.
import command_system.implementation.standard
import command_system.implementation.execute
try:
import gtkspell
HAS_GTK_SPELL = True
......@@ -158,7 +165,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
"""
Derived types MAY implement this
"""
self._paint_banner()
self.draw_banner()
def _update_banner_state_image(self):
......@@ -344,8 +350,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self.msg_textview.drag_dest_set(Gtk.DestDefaults.MOTION |
Gtk.DestDefaults.HIGHLIGHT, self.dnd_list, Gdk.DragAction.COPY)
self.update_font()
# Hook up send button
widget = self.xml.get_object('send_button')
id_ = widget.connect('clicked', self._on_send_button_clicked)
......@@ -371,7 +375,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
if gajim.config.get('use_speller') and HAS_GTK_SPELL:
self.set_speller()
self.conv_textview.tv.show()
self._paint_banner()
# For XEP-0172
self.user_nick = None
......@@ -503,76 +506,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
# send the message
self.send_message(message, xhtml=xhtml)
def _paint_banner(self):
"""
Repaint banner with theme color
"""
theme = gajim.config.get('roster_theme')
bgcolor = gajim.config.get_per('themes', theme, 'bannerbgcolor')
textcolor = gajim.config.get_per('themes', theme, 'bannertextcolor')
# the backgrounds are colored by using an eventbox by
# setting the bg color of the eventbox and the fg of the name_label
banner_eventbox = self.xml.get_object('banner_eventbox')
banner_name_label = self.xml.get_object('banner_name_label')
self.disconnect_style_event(banner_name_label)
self.disconnect_style_event(self.banner_status_label)
if bgcolor:
color = Gdk.RGBA()
Gdk.RGBA.parse(color, bgcolor)
banner_eventbox.override_background_color(Gtk.StateType.NORMAL,
color)
default_bg = False
else:
default_bg = True
if textcolor:
color = Gdk.RGBA()
Gdk.RGBA.parse(color, textcolor)
banner_name_label.override_color(Gtk.StateType.NORMAL,
color)
self.banner_status_label.override_color(
Gtk.StateType.NORMAL, color)
default_fg = False
else:
default_fg = True
if default_bg or default_fg:
self._on_style_set_event(banner_name_label, None, default_fg,
default_bg)
if self.banner_status_label.get_realized():
# Widget is realized
self._on_style_set_event(self.banner_status_label, None, default_fg,
default_bg)
def disconnect_style_event(self, widget):
# Try to find the event_id
for id_ in self.handlers.keys():
if self.handlers[id_] == widget:
widget.disconnect(id_)
del self.handlers[id_]
break
def connect_style_event(self, widget, set_fg=False, set_bg=False):
self.disconnect_style_event(widget)
id_ = widget.connect('style-set', self._on_style_set_event, set_fg,
set_bg)
self.handlers[id_] = widget
def _on_style_set_event(self, widget, style, *opts):
"""
Set style of widget from style class *.Frame.Eventbox
opts[0] == True -> set fg color
opts[1] == True -> set bg color
"""
banner_eventbox = self.xml.get_object('banner_eventbox')
self.disconnect_style_event(widget)
context = widget.get_style_context()
if opts[1]:
bg_color = context.get_background_color(Gtk.StateFlags.SELECTED)
banner_eventbox.override_background_color(Gtk.StateType.NORMAL, bg_color)
if opts[0]:
fg_color = context.get_color(Gtk.StateFlags.SELECTED)
widget.override_color(Gtk.StateType.NORMAL, fg_color)
self.connect_style_event(widget, opts[0], opts[1])
def _conv_textview_key_press_event(self, widget, event):
# translate any layout to latin_layout
valid, entries = self.keymap.get_entries_for_keyval(event.keyval)
......@@ -968,11 +901,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
gtkgui_helpers.popup_emoticons_under_button(menu, widget,
self.parent_win)
def update_font(self):
font = Pango.FontDescription(gajim.config.get('conversation_font'))
self.conv_textview.tv.override_font(font)
self.msg_textview.override_font(font)
def update_tags(self):
self.conv_textview.update_tags()
......@@ -1226,20 +1154,15 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
msg_type == 'sent' and not self.correcting and (not \
history[pos - 1].startswith('/') or history[pos - 1].startswith('/me')):
self.correcting = True
context = self.msg_textview.get_style_context()
state = Gtk.StateFlags.NORMAL
self.old_message_tv_color = context.get_background_color(state)
color = Gdk.RGBA()
Gdk.RGBA.parse(color, 'PaleGoldenrod')
self.msg_textview.override_background_color(Gtk.StateType.NORMAL,
color)
gtkgui_helpers.add_css_class(
self.msg_textview, 'msgcorrectingcolor')
message = history[pos - 1]
msg_buf.set_text(message)
return
if self.correcting:
# We were previously correcting
self.msg_textview.override_background_color(Gtk.StateType.NORMAL,
self.old_message_tv_color)
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
self.correcting = False
pos += -1 if direction == 'up' else +1
if pos == -1:
......@@ -1258,14 +1181,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
message = '> %s\n' % message.replace('\n', '\n> ')
msg_buf.set_text(message)
def lighten_color(self, color):
p = 0.4
mask = 0
color.red = int((color.red * p) + (mask * (1 - p)))
color.green = int((color.green * p) + (mask * (1 - p)))
color.blue = int((color.blue * p) + (mask * (1 - p)))
return color
def widget_set_visible(self, widget, state):
"""
Show or hide a widget
......
......@@ -15,7 +15,7 @@
"""
Provides a tiny framework with simple, yet powerful and extensible
architecture to implement commands in a streight and flexible,
architecture to implement commands in a straight and flexible,
declarative way.
"""
......@@ -67,7 +67,7 @@ class CommandProcessor(object):
"""
# This defines a command prefix (or an initializer), which should
# preceede a a text in order it to be processed as a command.
# precede a text in order for it to be processed as a command.
COMMAND_PREFIX = '/'
def process_as_command(self, text):
......
......@@ -75,7 +75,7 @@ class ChatCommandProcessor(CommandProcessor):
self.command_succeeded = True
def looks_like_command(self, text, body, name, arguments):
# Command escape stuff ggoes here. If text was prepended by the
# Command escape stuff goes here. If text was prepended by the
# command prefix twice, like //not_a_command (if prefix is set
# to /) then it will be escaped, that is sent just as a regular
# message with one (only one) prefix removed, so message will be
......
......@@ -24,7 +24,7 @@ import dialogs
from common import gajim
from common import helpers
from common.exceptions import GajimGeneralException
from common.logger import Constants
from common.logger import KindConstant
from ..errors import CommandError
from ..framework import CommandContainer, command, doc
......@@ -32,10 +32,6 @@ from ..mapping import generate_usage
from .hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
# This holds constants fron the logger, which we'll be using in some of our
# commands.
lc = Constants()
class StandardCommonCommands(CommandContainer):
"""
This command container contains standard commands which are common
......@@ -104,10 +100,10 @@ class StandardCommonCommands(CommandContainer):
raise CommandError(_("Limit must be an integer"))
for row in results:
contact, time, kind, show, message, subject = row
contact, time, kind, show, message, subject, log_line_id = row
if not contact:
if kind == lc.KIND_CHAT_MSG_SENT:
if kind == KindConstant.CHAT_MSG_SENT:
contact = gajim.nicks[self.account]
else:
contact = self.contact.name
......
......@@ -468,6 +468,7 @@ class Config:
'bannerbgcolor': [ opt_color, '', '', True ],
'bannerfont': [ opt_str, '', '', True ],
'bannerfontattrs': [ opt_str, 'B', '', True ],
'msgcorrectingcolor': [opt_color, '#eee8aa'],
# http://www.pitt.edu/~nisg/cis/web/cgi/rgb.html
'state_inactive_color': [ opt_color, 'grey62' ],
......
......@@ -750,6 +750,7 @@ class PreferencesWindow:
# begin repainting themed widgets throughout
gajim.interface.roster.repaint_themed_widgets()
gajim.interface.roster.change_roster_style(None)
gtkgui_helpers.load_css()
def update_theme_list(self):
theme_combobox = self.xml.get_object('theme_combobox')
......@@ -880,14 +881,7 @@ class PreferencesWindow:
else:
font = ''
gajim.config.set(text, font)
self.update_text_font()
def update_text_font(self):
"""
Update text font in opened chat windows
"""
for ctrl in self._get_all_controls():
ctrl.update_font()
gtkgui_helpers.load_css()
def on_incoming_nick_colorbutton_color_set(self, widget):
self.on_preference_widget_color_set(widget, 'inmsgcolor')
......
......@@ -238,8 +238,8 @@ class ConversationTextview(GObject.GObject):
self.change_cursor = False
self.last_time_printout = 0
font = Pango.FontDescription(gajim.config.get('conversation_font'))
self.tv.override_font(font)
style = self.tv.get_style_context()
style.add_class('font_custom')
buffer_ = self.tv.get_buffer()
end_iter = buffer_.get_end_iter()
buffer_.create_mark('end', end_iter, False)
......
......@@ -1671,7 +1671,7 @@ class YesNoDialog(HigDialog):
on_response_no=self.on_response_no)
if checktext:
self.checkbutton = Gtk.CheckButton(label=checktext)
self.checkbutton = Gtk.CheckButton.new_with_mnemonic(checktext)
self.vbox.pack_start(self.checkbutton, False, True, 0)
else:
self.checkbutton = None
......@@ -1764,7 +1764,7 @@ class ConfirmationDialogCheck(ConfirmationDialog):
ok_button = self.action_area.get_children()[0] # right to left
ok_button.grab_focus()
self.checkbutton = Gtk.CheckButton(label=checktext)
self.checkbutton = Gtk.CheckButton.new_with_mnemonic(checktext)
self.vbox.pack_start(self.checkbutton, False, True, 0)
self.set_modal(is_modal)
self.popup()
......@@ -1820,14 +1820,14 @@ class ConfirmationDialogDoubleCheck(ConfirmationDialog):
ok_button.grab_focus()
if checktext1:
self.checkbutton1 = Gtk.CheckButton(label=checktext1)
self.checkbutton1 = Gtk.CheckButton.new_with_mnemonic(checktext1)
if tooltip1:
self.checkbutton1.set_tooltip_text(tooltip1)
self.vbox.pack_start(self.checkbutton1, False, True, 0)
else:
self.checkbutton1 = None
if checktext2:
self.checkbutton2 = Gtk.CheckButton(label=checktext2)
self.checkbutton2 = Gtk.CheckButton.new_with_mnemonic(checktext2)
if tooltip2:
self.checkbutton2.set_tooltip_text(tooltip2)
self.vbox.pack_start(self.checkbutton2, False, True, 0)
......@@ -2098,7 +2098,7 @@ class InputDialogCheck(InputDialog):
self.input_entry.select_region(0, -1) # select all
if checktext:
self.checkbutton = Gtk.CheckButton(label=checktext)
self.checkbutton = Gtk.CheckButton.new_with_mnemonic(checktext)
self.vbox.pack_start(self.checkbutton, False, True, 0)
self.checkbutton.show()
......@@ -3379,10 +3379,6 @@ class XMLConsoleWindow:
self.enabled = True
self.xml.get_object('enable_checkbutton').set_active(True)
col = Gdk.RGBA()
Gdk.RGBA.parse(col, color)
self.input_textview.override_color(Gtk.StateType.NORMAL, col)
if len(gajim.connections) > 1:
title = _('XML Console for %s') % self.account
else:
......
......@@ -561,7 +561,6 @@ _('Without a connection, you can not browse available services'))
self.banner_eventbox = self.xml.get_object('banner_agent_eventbox')
self.style_event_id = 0
self.banner.realize()
self.paint_banner()
self.action_buttonbox = self.xml.get_object('action_buttonbox')
# Address combobox
......@@ -660,63 +659,6 @@ _('Without a connection, you can not browse available services'))
(markup, font.to_string(), text_after)
self.banner.set_markup(markup)
def paint_banner(self):
"""
Repaint the banner with theme color
"""
theme = gajim.config.get('roster_theme')
bgcolor = gajim.config.get_per('themes', theme, 'bannerbgcolor')
textcolor = gajim.config.get_per('themes', theme, 'bannertextcolor')
self.disconnect_style_event()
if bgcolor:
color = Gdk.RGBA()
Gdk.RGBA.parse(color, bgcolor)
self.banner_eventbox.override_background_color(Gtk.StateType.NORMAL,
color)
default_bg = False
else:
default_bg = True
if textcolor:
color = Gdk.RGBA()
Gdk.RGBA.parse(color, textcolor)
self.banner.override_color(Gtk.StateType.NORMAL, color)
default_fg = False
else:
default_fg = True
if default_fg or default_bg:
self._on_style_set_event(self.banner, None, default_fg, default_bg)
if self.browser:
self.browser.update_theme()
def disconnect_style_event(self):
if self.style_event_id:
self.banner.disconnect(self.style_event_id)
self.style_event_id = 0
def connect_style_event(self, set_fg = False, set_bg = False):
self.disconnect_style_event()
self.style_event_id = self.banner.connect('style-set',
self._on_style_set_event, set_fg, set_bg)
def _on_style_set_event(self, widget, style, *opts):
"""
Set style of widget from style class *.Frame.Eventbox
opts[0] == True -> set fg color
opts[1] == True -> set bg color
"""
self.disconnect_style_event()
context = widget.get_style_context()
if opts[1]:
bg_color = context.get_background_color(Gtk.StateFlags.SELECTED)
self.banner_eventbox.override_background_color(Gtk.StateType.NORMAL,
bg_color)
if opts[0]:
fg_color = context.get_color(Gtk.StateFlags.SELECTED)
self.banner.override_color(Gtk.StateType.NORMAL, fg_color)
self.banner.ensure_style()
self.connect_style_event(opts[0], opts[1])
def destroy(self, chain = False):
"""
Close the browser. This can optionally close its children and propagate
......
......@@ -94,6 +94,9 @@ class GajimApplication(Gtk.Application):
self.add_main_option('loglevel', ord('l'), GLib.OptionFlags.NONE,
GLib.OptionArg.STRING,
_('Configure logging system'), 'LEVEL')
self.add_main_option('warnings', ord('w'), GLib.OptionFlags.NONE,
GLib.OptionArg.NONE,
_('Show all warnings'))
self.profile = ''
self.config_path = None
......@@ -242,7 +245,9 @@ class GajimApplication(Gtk.Application):
def do_activate(self):
Gtk.Application.do_activate(self)
from gui_interface import Interface
import gtkgui_helpers
self.interface = Interface()
gtkgui_helpers.load_css()
self.interface.run(self)
self.add_actions()
import gui_menu_builder
......@@ -286,6 +291,8 @@ class GajimApplication(Gtk.Application):
if options.contains('loglevel'):
loglevel = options.lookup_value('loglevel').get_string()
logging_helpers.set_loglevels(loglevel)
if options.contains('warnings'):
self.show_warnings()
return -1
def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int:
......@@ -294,6 +301,19 @@ class GajimApplication(Gtk.Application):
self.activate()
return 0
def show_warnings(self):
import traceback
import warnings
def warn_with_traceback(message, category, filename, lineno,
file=None, line=None):
traceback.print_stack(file=sys.stderr)
sys.stderr.write(warnings.formatwarning(message, category,
filename, lineno, line))
warnings.showwarning = warn_with_traceback
warnings.filterwarnings(action="always")
def frozen_logging(self, path):
import warnings
if not os.path.exists(path):
......
......@@ -709,29 +709,17 @@ class GroupchatControl(ChatControlBase):
has_focus = self.parent_win.window.get_property('has-toplevel-focus')
current_tab = self.parent_win.get_active_control() == self
color_name = None
color = None
theme = gajim.config.get('roster_theme')
context = self.parent_win.notebook.get_style_context()
if chatstate == 'attention' and (not has_focus or not current_tab):
self.attention_flag = True
color_name = gajim.config.get_per('themes', theme,
'state_muc_directed_msg_color')
elif chatstate:
if chatstate == 'active' or (current_tab and has_focus):
self.attention_flag = False
# get active color from gtk
color = context.get_color(Gtk.StateFlags.ACTIVE)
elif chatstate == 'newmsg' and (not has_focus or not current_tab) \
and not self.attention_flag:
color_name = gajim.config.get_per('themes', theme,
'state_muc_msg_color')
if color_name:
color = Gdk.RGBA()
ok = Gdk.RGBA.parse(color, color_name)
if not ok:
del color
color = context.get_color(Gtk.StateFlags.ACTIVE)
color = 'state_muc_directed_msg_color'
elif chatstate == 'active' or (current_tab and has_focus):
self.attention_flag = False
# get active color from gtk
color = 'active'
elif chatstate == 'newmsg' and (not has_focus or not current_tab) \
and not self.attention_flag:
color = 'state_muc_msg_color'
if self.is_continued:
# if this is a continued conversation
......@@ -1996,8 +1984,8 @@ class GroupchatControl(ChatControlBase):
self.last_sent_msg = msg
if self.correcting:
self.correcting = False
self.msg_textview.override_background_color(
Gtk.StateType.NORMAL, self.old_message_tv_color)
gtkgui_helpers.remove_css_class(
self.msg_textview, 'msgcorrectingcolor')
if self.correcting and self.last_sent_msg:
correction_msg = self.last_sent_msg
......
......@@ -48,6 +48,7 @@ log = logging.getLogger('gajim.gtkgui_helpers')
from common import i18n
from common import gajim
from common import pep
from common import configpaths
gtk_icon_theme = Gtk.IconTheme.get_default()
gtk_icon_theme.append_search_path(gajim.ICONS_DIR)
......@@ -1088,3 +1089,94 @@ def __label_size_allocate(widget, allocation):
def get_action(action):
return gajim.app.lookup_action(action)
def load_css():
path = os.path.join(configpaths.get('DATA'), 'style', 'gajim.css')
try:
with open(path, "r") as f:
css = f.read()
except Exception as exc:
print('Error loading css: %s', exc)
return
provider = Gtk.CssProvider()
css = "\n".join((css, convert_config_to_css()))
provider.load_from_data(bytes(css.encode()))
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
def convert_config_to_css():
css = ''
themed_widgets = {
'ChatControl-BannerEventBox': ('bannerbgcolor', 'background'),
'ChatControl-BannerNameLabel': ('bannertextcolor', 'color'),
'ChatControl-BannerLabel': ('bannertextcolor', 'color'),
'GroupChatControl-BannerEventBox': ('bannerbgcolor', 'background'),
'GroupChatControl-BannerNameLabel': ('bannertextcolor', 'color'),
'GroupChatControl-BannerLabel': ('bannertextcolor', 'color'),
'Discovery-BannerEventBox': ('bannerbgcolor', 'background'),
'Discovery-BannerLabel': ('bannertextcolor', 'color')}
classes = {'state_composing_color': ('', 'color'),
'state_inactive_color': ('', 'color'),
'state_gone_color': ('', 'color'),
'state_paused_color': ('', 'color'),
'msgcorrectingcolor': ('text', 'background'),
'state_muc_directed_msg_color': ('', 'color'),
'state_muc_msg_color': ('', 'color')}
theme = gajim.config.get('roster_theme')
for key, values in themed_widgets.items():
config, attr = values
css += '#{} {{'.format(key)
value = gajim.config.get_per('themes', theme, config)
if value:
css += '{attr}: {color};\n'.format(attr=attr, color=value)
css += '}\n'
for key, values in classes.items():
node, attr = values
value = gajim.config.get_per('themes', theme, key)
if value:
css += '.theme_{cls} {node} {{ {attr}: {color}; }}\n'.format(
cls=key, node=node, attr=attr, color=value)
css += add_css_font()
return css
def add_css_class(widget, class_name):
style = widget.get_style_context()
for css_cls in style.list_classes():
if css_cls.startswith('theme_'):
style.remove_class(css_cls)
if class_name:
style.add_class('theme_' + class_name)
def remove_css_class(widget, class_name):
style = widget.get_style_context()
style.remove_class('theme_' + class_name)
def add_css_font():
conversation_font = gajim.config.get('conversation_font')
if not conversation_font:
return ''
font = Pango.FontDescription(conversation_font)
unit = "pt" if Gtk.check_version(3, 22, 0) is None else "px"
css = """
.font_custom {{
font-family: {family};
font-size: {size}{unit};
font-weight: {weight};
}}""".format(
family=font.get_family(),
size=int(round(font.get_size() / Pango.SCALE)),
unit=unit,
weight=int(font.get_weight()))
css = css.replace("font-size: 0{unit};".format(unit=unit), "")
css = css.replace("font-weight: 0;", "")
css = "\n".join(filter(lambda x: x.strip(), css.splitlines()))
return css
......@@ -39,6 +39,7 @@ import gtkgui_helpers
import message_control
import dialogs
from chat_control_base import ChatControlBase
from chat_control import ChatControl
from common import gajim
from gtkgui_helpers import get_action
......@@ -636,7 +637,7 @@ class MessageWindow(object):
window_mode == MessageWindowMgr.ONE_MSG_WINDOW_ALWAYS_WITH_ROSTER
self.notebook.set_show_tabs(show_tabs_if_one_tab)
def redraw_tab(self, ctrl, chatstate = None):
def redraw_tab(self, ctrl, chatstate=None):
tab = self.notebook.get_tab_label(ctrl.widget)
if not tab:
return
......@@ -653,11 +654,20 @@ class MessageWindow(object):
# Update nick
nick_label.set_max_width_chars(10)
(tab_label_str, tab_label_color) = ctrl.get_tab_label(chatstate)
if isinstance(ctrl, ChatControl):
tab_label_str = ctrl.get_tab_label()
# Set Label Color
class_name = 'state_{}_color'.format(chatstate)
gtkgui_helpers.add_css_class(nick_label, class_name)
else:
tab_label_str, color = ctrl.get_tab_label(chatstate)
# Set Label Color
if color == 'active':
gtkgui_helpers.add_css_class(nick_label, None)
elif color is not None:
gtkgui_helpers.add_css_class(nick_label, color)
nick_label.set_markup(tab_label_str)
if tab_label_color:
nick_label.override_color(Gtk.StateFlags.NORMAL, tab_label_color)
nick_label.override_color(Gtk.StateFlags.ACTIVE, tab_label_color)
tab_img = ctrl.get_tab_image()
if tab_img:
......
......@@ -202,8 +202,8 @@ class GajimPluginConfig():
@log_calls('GajimPluginConfig')
def __init__(self, plugin):
self.plugin = plugin
self.FILE_PATH = os.path.join(gajim.PLUGINS_CONFIG_DIR,
self.plugin.short_name).encode(locale.getpreferredencoding())
self.FILE_PATH = os.path.join(
gajim.PLUGINS_CONFIG_DIR, self.plugin.short_name)
self.data = {}
@log_calls('GajimPluginConfig')
......
......@@ -4800,8 +4800,6 @@ class RosterWindow:
for win in gajim.interface.msg_win_mgr.windows():
win.repaint_themed_widgets()
for account in gajim.connections:
for addr in gajim.interface.instances[account]['disco']:
gajim.interface.instances[account]['disco'][addr].paint_banner()
for ctrl in list(gajim.interface.minimized_controls[account].values()):
ctrl.repaint_themed_widgets()
......
......@@ -147,16 +147,10 @@ class VcardWindow:
buffer_ = self.xml.get_object('textview_annotation').get_buffer()
buffer_.set_text(annotations[self.contact.jid])
style_provider = Gtk.CssProvider()
css = 'GtkButton { padding-left: 5px; border-left: none; }'
style_provider.load_from_data(css.encode())
for widget_name in ('URL_label',
'EMAIL_WORK_USERID_label',
'EMAIL_HOME_USERID_label'):
widget = self.xml.get_object(widget_name)
context = widget.get_style_context()
context.add_provider(style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER)
widget.hide()
self.xml.connect_signals(self)
......