merge
This commit is contained in:
commit
b7b1faebdb
8 changed files with 380 additions and 75 deletions
2
Makefile
2
Makefile
|
@ -6,6 +6,8 @@ LOCALEDIR=$(DATADIR)/locale
|
|||
MANDIR=$(DATADIR)/man
|
||||
|
||||
all: Makefile
|
||||
python3 setup.py build
|
||||
cp build/lib.linux-x86_64-3.2/poopt.cpython-32mu.so src/
|
||||
|
||||
clean:
|
||||
find ./ -name \*.pyc -delete
|
||||
|
|
16
setup.py
Normal file
16
setup.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from distutils.core import setup, Extension
|
||||
|
||||
module_poopt = Extension('poopt',
|
||||
sources = ['src/pooptmodule.c'])
|
||||
|
||||
setup (name = 'BuildLines',
|
||||
version = '0.0.1',
|
||||
description = 'Poezio Optimizations',
|
||||
ext_modules = [module_poopt],
|
||||
author = 'Florent Le Coz',
|
||||
author_email = 'louiz@louiz.org',
|
||||
long_description = """
|
||||
a python3 module for poezio, used to replace some time-critical
|
||||
python functions that are too slow. If compiled, poezio will use this module,
|
||||
otherwise it will just use the equivalent python functions.
|
||||
""")
|
11
src/core.py
11
src/core.py
|
@ -355,7 +355,8 @@ class Core(object):
|
|||
return
|
||||
log.debug('on_got_offline: %s' % presence)
|
||||
resource = contact.get_resource_by_fulljid(jid.full)
|
||||
assert resource
|
||||
if not resource:
|
||||
return
|
||||
# If a resource got offline, display the message in the conversation with this
|
||||
# precise resource.
|
||||
self.add_information_message_to_conversation_tab(jid.full, '\x195%s is \x191offline' % (resource.get_jid().full))
|
||||
|
@ -674,7 +675,7 @@ class Core(object):
|
|||
roster.add_contact(contact, jid)
|
||||
roster.edit_groups_of_contact(contact, [])
|
||||
contact.set_ask('asked')
|
||||
self.tabs[0].set_color_state(theme.COLOR_TAB_HIGHLIGHT)
|
||||
self.get_tab_by_number(0).set_color_state(theme.COLOR_TAB_HIGHLIGHT)
|
||||
self.information('%s wants to subscribe to your presence'%jid, 'Roster')
|
||||
if isinstance(self.current_tab(), tabs.RosterInfoTab):
|
||||
self.refresh_window()
|
||||
|
@ -777,6 +778,12 @@ class Core(object):
|
|||
return tab
|
||||
return None
|
||||
|
||||
def get_tab_by_number(self, number):
|
||||
for tab in self.tabs:
|
||||
if tab.nb == number:
|
||||
return tab
|
||||
return None
|
||||
|
||||
def get_room_by_name(self, name):
|
||||
"""
|
||||
returns the room that has this name
|
||||
|
|
279
src/pooptmodule.c
Normal file
279
src/pooptmodule.c
Normal file
|
@ -0,0 +1,279 @@
|
|||
/* 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 MIT license. See the COPYING file. */
|
||||
|
||||
/** The poopt python3 module
|
||||
**/
|
||||
|
||||
/* This file is a python3 module for poezio, used to replace some time-critical
|
||||
python functions that are too slow. If compiled, poezio will use this module,
|
||||
otherwise it will just use the equivalent python functions. */
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
PyObject *ErrorObject;
|
||||
|
||||
/***
|
||||
The module functions
|
||||
***/
|
||||
|
||||
/* cut_text: takes a string and returns a tuple of int.
|
||||
Each two int tuple is a line, represented by the ending position it (where it should be cut).
|
||||
Not that this position is calculed using the position of the python string characters,
|
||||
not just the individual bytes.
|
||||
For example, poopt_cut_text("vivent les frigidaires", 6);
|
||||
will return [(0, 6), (7, 10), (11, 17), (17, 22)], meaning that the lines are
|
||||
"vivent", "les", "frigid" and "aires"
|
||||
*/
|
||||
PyDoc_STRVAR(poopt_cut_text_doc, "cut_text(width, text)\n\n\nReturn the list of strings, cut according to the given size.");
|
||||
|
||||
static PyObject *poopt_cut_text(PyObject *self, PyObject *args)
|
||||
{
|
||||
/* int length; */
|
||||
unsigned char *buffer;
|
||||
int width;
|
||||
|
||||
if (PyArg_ParseTuple(args, "si", &buffer, &width) == 0)
|
||||
return NULL;
|
||||
|
||||
int bpos = 0; /* the real position in the char* */
|
||||
int spos = 0; /* the position, considering UTF-8 chars */
|
||||
int last_space = -1;
|
||||
int start_pos = 0;
|
||||
|
||||
PyObject* retlist = PyList_New(0);
|
||||
|
||||
while (buffer[bpos])
|
||||
{
|
||||
if (buffer[bpos] == ' ')
|
||||
last_space = spos;
|
||||
else if (buffer[bpos] == '\n')
|
||||
{
|
||||
if (PyList_Append(retlist, Py_BuildValue("ii", start_pos, spos)) == -1)
|
||||
return NULL;
|
||||
start_pos = spos + 1;
|
||||
last_space = -1;
|
||||
}
|
||||
else if ((spos - start_pos) >= width)
|
||||
{
|
||||
if (last_space == -1)
|
||||
{
|
||||
if (PyList_Append(retlist, Py_BuildValue("ii", start_pos, spos)) == -1)
|
||||
return NULL;
|
||||
start_pos = spos;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PyList_Append(retlist, Py_BuildValue("ii", start_pos, last_space)) == -1)
|
||||
return NULL;
|
||||
start_pos = last_space + 1;
|
||||
last_space = -1;
|
||||
}
|
||||
}
|
||||
if (buffer[bpos] == 25) /* \x19 */
|
||||
{
|
||||
spos++;
|
||||
bpos += 2;
|
||||
}
|
||||
else
|
||||
if (buffer[bpos] <= 127) /* ASCII char on one byte */
|
||||
bpos += 1;
|
||||
else if (buffer[bpos] >= 194 && buffer[bpos] <= 223)
|
||||
bpos += 2;
|
||||
else if (buffer[bpos] >= 224 && buffer[bpos] <= 239)
|
||||
bpos += 3;
|
||||
else if (buffer[bpos] >= 240 && buffer[bpos] <= 244)
|
||||
bpos += 4;
|
||||
else
|
||||
return NULL;
|
||||
spos++;
|
||||
}
|
||||
if (PyList_Append(retlist, Py_BuildValue("(i,i)", start_pos, spos)) == -1)
|
||||
return NULL;
|
||||
return retlist;
|
||||
}
|
||||
|
||||
/***
|
||||
Module initialization. Just taken from the xxmodule.c template from the python sources.
|
||||
***/
|
||||
static PyTypeObject Str_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"pooptmodule.Str", /*tp_name*/
|
||||
0, /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
0, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_reserved*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
0, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
0, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
0, /*tp_getset*/
|
||||
0, /* see PyInit_xx */ /*tp_base*/
|
||||
0, /*tp_dict*/
|
||||
0, /*tp_descr_get*/
|
||||
0, /*tp_descr_set*/
|
||||
0, /*tp_dictoffset*/
|
||||
0, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
0, /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
};
|
||||
|
||||
/* ---------- */
|
||||
|
||||
static PyObject *
|
||||
null_richcompare(PyObject *self, PyObject *other, int op)
|
||||
{
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
||||
static PyTypeObject Null_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"pooptmodule.Null", /*tp_name*/
|
||||
0, /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
0, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_reserved*/
|
||||
0, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
0, /*tp_doc*/
|
||||
0, /*tp_traverse*/
|
||||
0, /*tp_clear*/
|
||||
null_richcompare, /*tp_richcompare*/
|
||||
0, /*tp_weaklistoffset*/
|
||||
0, /*tp_iter*/
|
||||
0, /*tp_iternext*/
|
||||
0, /*tp_methods*/
|
||||
0, /*tp_members*/
|
||||
0, /*tp_getset*/
|
||||
0, /* see PyInit_xx */ /*tp_base*/
|
||||
0, /*tp_dict*/
|
||||
0, /*tp_descr_get*/
|
||||
0, /*tp_descr_set*/
|
||||
0, /*tp_dictoffset*/
|
||||
0, /*tp_init*/
|
||||
0, /*tp_alloc*/
|
||||
0, /* see PyInit_xx */ /*tp_new*/
|
||||
0, /*tp_free*/
|
||||
0, /*tp_is_gc*/
|
||||
};
|
||||
|
||||
|
||||
/* List of functions defined in the module */
|
||||
|
||||
static PyMethodDef poopt_methods[] = {
|
||||
{"cut_text", poopt_cut_text, METH_VARARGS,
|
||||
poopt_cut_text_doc},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(module_doc,
|
||||
"This is a template module just for instruction. And poopt.");
|
||||
|
||||
/* Initialization function for the module (*must* be called PyInit_xx) */
|
||||
|
||||
static struct PyModuleDef pooptmodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"poopt",
|
||||
module_doc,
|
||||
-1,
|
||||
poopt_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_poopt(void)
|
||||
{
|
||||
PyObject *m = NULL;
|
||||
|
||||
/* Due to cross platform compiler issues the slots must be filled
|
||||
* here. It's required for portability to Windows without requiring
|
||||
* C++. */
|
||||
Null_Type.tp_base = &PyBaseObject_Type;
|
||||
Null_Type.tp_new = PyType_GenericNew;
|
||||
Str_Type.tp_base = &PyUnicode_Type;
|
||||
|
||||
/* Finalize the type object including setting type of the new type
|
||||
* object; doing it here is required for portability, too. */
|
||||
/* if (PyType_Ready(&Xxo_Type) < 0) */
|
||||
/* goto fail; */
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = PyModule_Create(&pooptmodule);
|
||||
if (m == NULL)
|
||||
goto fail;
|
||||
|
||||
/* Add some symbolic constants to the module */
|
||||
if (ErrorObject == NULL) {
|
||||
ErrorObject = PyErr_NewException("poopt.error", NULL, NULL);
|
||||
if (ErrorObject == NULL)
|
||||
goto fail;
|
||||
}
|
||||
Py_INCREF(ErrorObject);
|
||||
PyModule_AddObject(m, "error", ErrorObject);
|
||||
|
||||
/* Add Str */
|
||||
if (PyType_Ready(&Str_Type) < 0)
|
||||
goto fail;
|
||||
PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
|
||||
|
||||
/* Add Null */
|
||||
if (PyType_Ready(&Null_Type) < 0)
|
||||
goto fail;
|
||||
PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
|
||||
return m;
|
||||
fail:
|
||||
Py_XDECREF(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* /\* test function *\/ */
|
||||
/* int main(void) */
|
||||
/* { */
|
||||
/* char coucou[] = "vive le foutre, le beurre et le caca boudin"; */
|
||||
|
||||
/* cut_text(coucou, 8); */
|
||||
/* } */
|
|
@ -120,7 +120,9 @@ class Room(TextBuffer):
|
|||
nick_color = highlight
|
||||
time = time or datetime.now()
|
||||
message = Message(txt='%s\x19o'%(txt,), nick_color=nick_color,
|
||||
time=time, nickname=nickname, user=user)
|
||||
time=time, str_time=time.strftime("%Y-%m-%d %H:%M:%S")\
|
||||
if history else time.strftime("%H:%M:%S"),\
|
||||
nickname=nickname, user=user)
|
||||
while len(self.messages) > self.messages_nb_limit:
|
||||
self.messages.pop(0)
|
||||
self.messages.append(message)
|
||||
|
|
18
src/tabs.py
18
src/tabs.py
|
@ -14,7 +14,7 @@ Windows are displayed, resized, etc
|
|||
"""
|
||||
|
||||
MIN_WIDTH = 50
|
||||
MIN_HEIGHT = 16
|
||||
MIN_HEIGHT = 22
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -89,6 +89,10 @@ class Tab(object):
|
|||
@staticmethod
|
||||
def resize(scr):
|
||||
Tab.size = (Tab.height, Tab.width) = scr.getmaxyx()
|
||||
if Tab.height < MIN_HEIGHT or Tab.width < MIN_WIDTH:
|
||||
Tab.visible = False
|
||||
else:
|
||||
Tab.visible = True
|
||||
|
||||
def complete_commands(self, the_input):
|
||||
"""
|
||||
|
@ -671,6 +675,8 @@ class MucTab(ChatTab):
|
|||
"""
|
||||
Resize the whole window. i.e. all its sub-windows
|
||||
"""
|
||||
if not self.visible:
|
||||
return
|
||||
text_width = (self.width//10)*9
|
||||
self.topic_win.resize(1, self.width, 0, 0)
|
||||
self.v_separator.resize(self.height-3, 1, 1, 9*(self.width//10))
|
||||
|
@ -1018,7 +1024,7 @@ class PrivateTab(ChatTab):
|
|||
self.core.close_tab()
|
||||
|
||||
def resize(self):
|
||||
if self.core.information_win_size >= self.height-3:
|
||||
if self.core.information_win_size >= self.height-3 or not self.visible:
|
||||
return
|
||||
self.text_win.resize(self.height-3-self.core.information_win_size, self.width, 0, 0)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
|
@ -1165,6 +1171,8 @@ class RosterInfoTab(Tab):
|
|||
self.resize()
|
||||
|
||||
def resize(self):
|
||||
if not self.visible:
|
||||
return
|
||||
roster_width = self.width//2
|
||||
info_width = self.width-roster_width-1
|
||||
self.v_separator.resize(self.height-2, 1, 0, roster_width)
|
||||
|
@ -1518,7 +1526,7 @@ class ConversationTab(ChatTab):
|
|||
self.core.close_tab()
|
||||
|
||||
def resize(self):
|
||||
if self.core.information_win_size >= self.height-3:
|
||||
if self.core.information_win_size >= self.height-3 or not self.visible:
|
||||
return
|
||||
self.text_win.resize(self.height-4-self.core.information_win_size, self.width, 1, 0)
|
||||
self.text_win.rebuild_everything(self._room)
|
||||
|
@ -1635,6 +1643,8 @@ class MucListTab(Tab):
|
|||
self.input.refresh()
|
||||
|
||||
def resize(self):
|
||||
if not self.visible:
|
||||
return
|
||||
self.upper_message.resize(1, self.width, 0, 0)
|
||||
column_size = {'node-part': (self.width-5)//4,
|
||||
'name': (self.width-5)//4*3,
|
||||
|
@ -1761,6 +1771,8 @@ class SimpleTextTab(Tab):
|
|||
self.core.close_tab()
|
||||
|
||||
def resize(self):
|
||||
if not self.visible:
|
||||
return
|
||||
self.text_win.resize(self.height-2, self.width, 0, 0)
|
||||
self.input.resize(1, self.width, self.height-1, 0)
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ from datetime import datetime
|
|||
import theme
|
||||
from config import config
|
||||
|
||||
Message = collections.namedtuple('Message', 'txt nick_color time nickname user')
|
||||
Message = collections.namedtuple('Message', 'txt nick_color time str_time nickname user')
|
||||
|
||||
class TextBuffer(object):
|
||||
"""
|
||||
|
@ -45,8 +45,11 @@ class TextBuffer(object):
|
|||
self.windows.append(win)
|
||||
|
||||
def add_message(self, txt, time=None, nickname=None, nick_color=None, history=None):
|
||||
time = time or datetime.now()
|
||||
msg = Message(txt='%s\x19o'%(txt,), nick_color=nick_color,
|
||||
time=time or datetime.now(), nickname=nickname, user=None)
|
||||
time=time, str_time=time.strftime("%Y-%m-%d %H:%M:%S")\
|
||||
if history else time.strftime("%H:%M:%S"),\
|
||||
nickname=nickname, user=None)
|
||||
self.messages.append(msg)
|
||||
while len(self.messages) > self.messages_nb_limit:
|
||||
self.messages.pop(0)
|
||||
|
|
114
src/windows.py
114
src/windows.py
|
@ -28,6 +28,7 @@ from threading import Lock
|
|||
|
||||
from contact import Contact, Resource
|
||||
from roster import RosterGroup, roster
|
||||
from poopt import cut_text
|
||||
|
||||
# from message import Line
|
||||
from tabs import MIN_WIDTH, MIN_HEIGHT
|
||||
|
@ -41,7 +42,10 @@ import wcwidth
|
|||
import singleton
|
||||
import collections
|
||||
|
||||
Line = collections.namedtuple('Line', 'text text_offset nickname_color time nickname')
|
||||
# msg is a reference to the corresponding Message tuple. text_start and text_end are the position
|
||||
# delimiting the text in this line.
|
||||
# first is a bool telling if this is the first line of the message.
|
||||
Line = collections.namedtuple('Line', 'msg start_pos end_pos first')
|
||||
|
||||
g_lock = Lock()
|
||||
|
||||
|
@ -89,6 +93,12 @@ class Win(object):
|
|||
except:
|
||||
pass
|
||||
|
||||
def move(self, y, x):
|
||||
try:
|
||||
self._win.move(y, x)
|
||||
except:
|
||||
self._win.move(0, 0)
|
||||
|
||||
def addstr_colored(self, text, y=None, x=None):
|
||||
"""
|
||||
Write a string on the window, setting the
|
||||
|
@ -101,7 +111,7 @@ class Win(object):
|
|||
one of 'u', 'b', 'c[0-9]'
|
||||
"""
|
||||
if y is not None and x is not None:
|
||||
self._win.move(y, x)
|
||||
self.move(y, x)
|
||||
next_attr_char = text.find('\x19')
|
||||
while next_attr_char != -1:
|
||||
if next_attr_char + 1 < len(text):
|
||||
|
@ -529,30 +539,14 @@ class TextWin(Win):
|
|||
if None not in self.built_lines:
|
||||
self.built_lines.append(None)
|
||||
|
||||
def build_new_message(self, message, history=None):
|
||||
def build_new_message(self, message, history=None, clean=True):
|
||||
"""
|
||||
Take one message, build it and add it to the list
|
||||
Return the number of lines that are built for the given
|
||||
message.
|
||||
"""
|
||||
def cut_text(text, width):
|
||||
"""
|
||||
returns the text that should be displayed on the line, and the rest
|
||||
of the text, in a tuple
|
||||
"""
|
||||
cutted = wcwidth.widthcut(text, width) or text[:width]
|
||||
limit = cutted.find('\n')
|
||||
if limit >= 0:
|
||||
return (text[limit+1:], text[:limit])
|
||||
if not wcwidth.wcsislonger(text, width):
|
||||
return ('', text)
|
||||
limit = cutted.rfind(' ')
|
||||
if limit <= 0:
|
||||
return (text[len(cutted):], cutted)
|
||||
else:
|
||||
return (text[limit+1:], text[:limit])
|
||||
|
||||
if message is None: # line separator
|
||||
log.debug('je build NON, cool non ? +++++++++++++++++++++++++++')
|
||||
self.built_lines.append(None)
|
||||
return 0
|
||||
txt = message.txt
|
||||
|
@ -560,53 +554,32 @@ class TextWin(Win):
|
|||
return 0
|
||||
else:
|
||||
txt = txt.replace('\t', ' ')
|
||||
# length of the time
|
||||
if history:
|
||||
offset = 20
|
||||
else:
|
||||
offset = 9
|
||||
if theme.CHAR_TIME_RIGHT:
|
||||
offset += 1
|
||||
if theme.CHAR_TIME_RIGHT:
|
||||
offset += 1
|
||||
nickname = message.nickname
|
||||
if nickname and len(nickname) >= 25:
|
||||
nick = nickname[:25]+'…'
|
||||
else:
|
||||
nick = nickname
|
||||
nick = message.nickname
|
||||
if nick and len(nick) >= 25:
|
||||
nick = nick[:25]+'…'
|
||||
offset = 1 + len(message.str_time)
|
||||
if nick:
|
||||
offset += wcwidth.wcswidth(nick) + 2 # + nick + spaces length
|
||||
if nick:
|
||||
offset += wcwidth.wcswidth(nick) + 2 # + nick + spaces length
|
||||
if theme.CHAR_TIME_LEFT:
|
||||
offset += 1
|
||||
if theme.CHAR_TIME_RIGHT:
|
||||
offset += 1
|
||||
|
||||
lines = cut_text(txt, self.width-offset-1)
|
||||
|
||||
first = True
|
||||
nb = 0
|
||||
while txt != '':
|
||||
(txt, cutted_txt) = cut_text(txt, self.width-offset-1)
|
||||
if first:
|
||||
if message.nick_color:
|
||||
color = message.nick_color
|
||||
elif message.user:
|
||||
color = message.user.color
|
||||
else:
|
||||
color = None
|
||||
else:
|
||||
color = None
|
||||
if first:
|
||||
if history:
|
||||
time = message.time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
else:
|
||||
time = message.time.strftime("%H:%M:%S")
|
||||
nickname = nick
|
||||
else:
|
||||
time = None
|
||||
nickname = None
|
||||
self.built_lines.append(Line(text=cutted_txt,
|
||||
text_offset=offset,
|
||||
nickname_color=color, time=time,
|
||||
nickname=nickname))
|
||||
nb += 1
|
||||
for line in lines:
|
||||
self.built_lines.append(Line(msg=message,
|
||||
start_pos=line[0],
|
||||
end_pos=line[1],
|
||||
first=first))
|
||||
first = False
|
||||
if clean:
|
||||
while len(self.built_lines) > self.lines_nb_limit:
|
||||
self.built_lines.pop(0)
|
||||
return nb
|
||||
return len(lines)
|
||||
|
||||
def refresh(self, room):
|
||||
log.debug('Refresh: %s'%self.__class__.__name__)
|
||||
|
@ -621,17 +594,26 @@ class TextWin(Win):
|
|||
self._win.erase()
|
||||
for y, line in enumerate(lines):
|
||||
if line is None:
|
||||
log.debug('COUCOU JE SUIS NONE\n\n-----------------')
|
||||
self.write_line_separator()
|
||||
else:
|
||||
self.write_time(line.time)
|
||||
self.write_nickname(line.nickname, line.nickname_color)
|
||||
msg = line.msg
|
||||
if line.first:
|
||||
if msg.nick_color:
|
||||
color = msg.nick_color
|
||||
elif msg.user:
|
||||
color = msg.user.color
|
||||
else:
|
||||
color = None
|
||||
self.write_time(msg.str_time)
|
||||
self.write_nickname(msg.nickname, color)
|
||||
if y != self.height-1:
|
||||
self.addstr('\n')
|
||||
self._win.attrset(0)
|
||||
for y, line in enumerate(lines):
|
||||
if not line:
|
||||
continue
|
||||
self.write_text(y, line.text_offset, line.text)
|
||||
self.write_text(y, (3 if line.msg.nickname else 1) + len(line.msg.str_time)+len(line.msg.nickname or ''), line.msg.txt[line.start_pos:line.end_pos])
|
||||
if y != self.height-1:
|
||||
self.addstr('\n')
|
||||
self._win.attrset(0)
|
||||
|
@ -676,7 +658,9 @@ class TextWin(Win):
|
|||
def rebuild_everything(self, room):
|
||||
self.built_lines = []
|
||||
for message in room.messages:
|
||||
self.build_new_message(message)
|
||||
self.build_new_message(message, clean=False)
|
||||
while len(self.built_lines) > self.lines_nb_limit:
|
||||
self.built_lines.pop(0)
|
||||
|
||||
def __del__(self):
|
||||
log.debug('** TextWin: deleting %s built lines' % (len(self.built_lines)))
|
||||
|
|
Loading…
Reference in a new issue