summaryrefslogtreecommitdiff
path: root/poezio/theming.py
diff options
context:
space:
mode:
Diffstat (limited to 'poezio/theming.py')
-rwxr-xr-xpoezio/theming.py63
1 files changed, 43 insertions, 20 deletions
diff --git a/poezio/theming.py b/poezio/theming.py
index bbf2fb64..187d07c5 100755
--- a/poezio/theming.py
+++ b/poezio/theming.py
@@ -1,9 +1,10 @@
+#!/usr/bin/env python3
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
-# it under the terms of the zlib license. See the COPYING file.
+# it under the terms of the GPL-3.0+ license. See the COPYING file.
"""
Define the variables (colors and some other stuff) that are
used when drawing the interface.
@@ -73,11 +74,11 @@ except ImportError:
import curses
import functools
-import os
-from typing import Dict, List, Union, Tuple, Optional
+from typing import Dict, List, Union, Tuple, Optional, cast
from pathlib import Path
from os import path
from poezio import colors, xdg
+from datetime import datetime
from importlib import machinery
finder = machinery.PathFinder()
@@ -143,6 +144,14 @@ class Theme:
return sub_mapping[sub] if sub == keep else ''
return sub_mapping.get(sub, '')
+ # Short date format (only show time)
+ SHORT_TIME_FORMAT = '%H:%M:%S'
+ SHORT_TIME_FORMAT_LENGTH = len(datetime.now().strftime(SHORT_TIME_FORMAT))
+
+ # Long date format (show date and time)
+ LONG_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
+ LONG_TIME_FORMAT_LENGTH = len(datetime.now().strftime(LONG_TIME_FORMAT))
+
# Message text color
COLOR_NORMAL_TEXT = (-1, -1)
COLOR_INFORMATION_TEXT = (5, -1) # TODO
@@ -178,12 +187,13 @@ class Theme:
CHAR_CHATSTATE_COMPOSING = 'X'
CHAR_CHATSTATE_PAUSED = 'p'
- # These characters are used for the affiliation in the user list
- # in a MUC
+ # These characters are used for the affiliation wherever needed, e.g., in
+ # the user list in a MUC, or when displaying affiliation lists.
CHAR_AFFILIATION_OWNER = '~'
CHAR_AFFILIATION_ADMIN = '&'
CHAR_AFFILIATION_MEMBER = '+'
CHAR_AFFILIATION_NONE = '-'
+ CHAR_AFFILIATION_OUTCAST = '!'
# XML Tab
CHAR_XML_IN = 'IN '
@@ -224,6 +234,15 @@ class Theme:
COLOR_TAB_ATTENTION = (7, 1)
COLOR_TAB_DISCONNECTED = (7, 8)
+ # If autocolor_tab_names is set to true, the following modes are used to
+ # distinguish tabs with normal and important messages.
+ MODE_TAB_NORMAL = ''
+ MODE_TAB_IMPORTANT = 'r' # reverse video mode
+
+ # This is the mode used for the tab name in the info bar of MUC and 1:1
+ # chat tabs.
+ MODE_TAB_NAME = 'r'
+
COLOR_VERTICAL_TAB_NORMAL = (4, -1)
COLOR_VERTICAL_TAB_NONEMPTY = (4, -1)
COLOR_VERTICAL_TAB_JOINED = (82, -1)
@@ -281,7 +300,7 @@ class Theme:
(224, -1), (225, -1), (226, -1), (227, -1)]
# XEP-0392 consistent color generation palette placeholder
# it’s generated on first use when accessing the ccg_palette property
- CCG_PALETTE = None # type: Optional[Dict[float, int]]
+ CCG_PALETTE: Optional[Dict[float, int]] = None
CCG_Y = 0.5**0.45
# yapf: enable
@@ -315,7 +334,9 @@ class Theme:
COLOR_COLUMN_HEADER_SEL = (4, 36)
# Strings for special messages (like join, quit, nick change, etc)
- # Special messages
+ CHAR_BEFORE_NICK_ME = '* '
+ CHAR_AFTER_NICK_ME = ' '
+ CHAR_AFTER_NICK = '> '
CHAR_JOIN = '--->'
CHAR_QUIT = '<---'
CHAR_KICK = '-!-'
@@ -358,7 +379,7 @@ class Theme:
# Info messages color (the part before the ">")
INFO_COLORS = {
'info': (5, -1),
- 'error': (16, 1),
+ 'error': (9, 7, 'b'),
'warning': (1, -1),
'roster': (2, -1),
'help': (10, -1),
@@ -371,7 +392,7 @@ class Theme:
}
@property
- def ccg_palette(self):
+ def ccg_palette(self) -> Optional[Dict[float, int]]:
prepare_ccolor_palette(self)
return self.CCG_PALETTE
@@ -383,8 +404,7 @@ theme = Theme()
# Each time we use a color tuple, we check if it has already been used.
# If not we create a new color_pair and keep it in that dict, to use it
# the next time.
-curses_colors_dict = {
-} # type: Dict[Union[Tuple[int, int], Tuple[int, int, str]], int]
+curses_colors_dict: Dict[Union[Tuple[int, int], Tuple[int, int, str]], int] = {}
# yapf: disable
@@ -408,7 +428,7 @@ table_256_to_16 = [
]
# yapf: enable
-load_path = [] # type: List[str]
+load_path: List[str] = []
def color_256_to_16(color):
@@ -441,13 +461,14 @@ def to_curses_attr(
returns a valid curses attr that can be passed directly to attron() or attroff()
"""
# extract the color from that tuple
+ colors: Union[Tuple[int, int], Tuple[int, int, str]]
if len(color_tuple) == 3:
colors = (color_tuple[0], color_tuple[1])
else:
colors = color_tuple
bold = False
- if curses.COLORS != 256:
+ if curses.COLORS < 256:
# We are not in a term supporting 256 colors, so we convert
# colors to numbers between -1 and 8
colors = (color_256_to_16(colors[0]), color_256_to_16(colors[1]))
@@ -466,7 +487,7 @@ def to_curses_attr(
curses_colors_dict[colors] = pair
curses_pair = curses.color_pair(pair)
if len(color_tuple) == 3:
- additional_val = color_tuple[2]
+ _, _, additional_val = cast(Tuple[int, int, str], color_tuple)
if 'b' in additional_val or bold is True:
curses_pair = curses_pair | curses.A_BOLD
if 'u' in additional_val:
@@ -476,6 +497,8 @@ def to_curses_attr(
curses, 'A_ITALIC') else curses.A_REVERSE)
if 'a' in additional_val:
curses_pair = curses_pair | curses.A_BLINK
+ if 'r' in additional_val:
+ curses_pair = curses_pair | curses.A_REVERSE
return curses_pair
@@ -498,7 +521,7 @@ def update_themes_dir(option: Optional[str] = None,
load_path.append(default_dir)
# import from the user-defined prefs
- themes_dir_str = config.get('themes_dir')
+ themes_dir_str = config.getstr('themes_dir')
themes_dir = Path(themes_dir_str).expanduser(
) if themes_dir_str else xdg.DATA_HOME / 'themes'
try:
@@ -544,7 +567,7 @@ def prepare_ccolor_palette(theme: Theme) -> None:
def reload_theme() -> Optional[str]:
- theme_name = config.get('theme')
+ theme_name = config.getstr('theme')
global theme
if theme_name == 'default' or not theme_name.strip():
theme = Theme()
@@ -552,10 +575,10 @@ def reload_theme() -> Optional[str]:
new_theme = None
exc = None
try:
- loader = finder.find_module(theme_name, load_path)
- if not loader:
+ spec = finder.find_spec(theme_name, path=load_path)
+ if not spec or not spec.loader:
return 'Failed to load the theme %s' % theme_name
- new_theme = loader.load_module()
+ new_theme = spec.loader.load_module(theme_name)
except Exception as e:
log.error('Failed to load the theme %s', theme_name, exc_info=True)
exc = e
@@ -564,7 +587,7 @@ def reload_theme() -> Optional[str]:
return 'Failed to load theme: %s' % exc
if hasattr(new_theme, 'theme'):
- theme = new_theme.theme
+ theme = new_theme.theme # type: ignore
prepare_ccolor_palette(theme)
return None
return 'No theme present in the theme file'