Code is cleaner & faster now. Hope I didn't introduce any bugs. Next step: combine *EVERYTHING* not just formatting ;P. I rewrote the algo for that in recursion, and u'll see it in the next commit I hope

This commit is contained in:
Nikos Kouremenos 2005-03-13 17:04:57 +00:00
parent e5f9884867
commit f0d77e7c1a
4 changed files with 117 additions and 104 deletions

View File

@ -37,8 +37,8 @@ gtk.glade.textdomain(APP)
GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade' GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade'
class chat: class Chat:
"""Class for tabbed chat window""" """Class for chat/groupchat windows"""
def __init__(self, plugin, account, widget_name): def __init__(self, plugin, account, widget_name):
self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP) self.xml = gtk.glade.XML(GTKGUI_GLADE, widget_name, APP)
self.notebook = self.xml.get_widget('chat_notebook') self.notebook = self.xml.get_widget('chat_notebook')
@ -427,51 +427,86 @@ class chat:
#we launch the correct application #we launch the correct application
self.plugin.launch_browser_mailer(kind, word) self.plugin.launch_browser_mailer(kind, word)
def print_special_text(self, text, jid, other_tag): def detect_and_print_special_text(self, otext, jid, other_tag, print_all_special):
# nk 2 yann: when doing this in GC you have to pass sth and looks for
# xmls[Other-key-here] I believe :D
conversation_textview = self.xmls[jid].get_widget('conversation_textview') conversation_textview = self.xmls[jid].get_widget('conversation_textview')
conversation_buffer = conversation_textview.get_buffer() conversation_buffer = conversation_textview.get_buffer()
# make it CAPS (emoticons keys are all CAPS) # == DETECT SPECIAL TEXT ==
possible_emot_ascii_caps = text.upper() start = 0
if possible_emot_ascii_caps in self.plugin.emoticons.keys(): end = 0
#it's an emoticon index = 0
emot_ascii = possible_emot_ascii_caps #special_text = ''
print 'emoticon:', emot_ascii
end_iter = conversation_buffer.get_end_iter()
conversation_buffer.insert_pixbuf(end_iter, \
self.plugin.emoticons[emot_ascii])
return
elif text.startswith('mailto:'):
#it's a mail
tag = 'mail'
print tag
elif self.plugin.sth_at_sth_dot_sth_re.match(text): #returns match object
#or None
#it's a mail
tag = 'mail'
print tag
elif text.startswith('*') and text.endswith('*'):
#it's a bold text
tag = 'bold'
text = text[1:-1] # remove * *
elif text.startswith('/') and text.endswith('/'):
#it's an italic text
tag = 'italic'
text = text[1:-1] # remove / /
print tag
elif text.startswith('_') and text.endswith('_'):
#it's an underlined text
tag = 'underline'
text = text[1:-1] # remove _ _
print tag
else:
#it's a url
tag = 'url'
print tag
end_iter = conversation_buffer.get_end_iter() # basic: links + mail + formatting is always checked (we like that)
if tag in ['bold', 'italic', 'underline'] and other_tag: if self.plugin.config['useemoticons']: # search for emoticons & urls
conversation_buffer.insert_with_tags_by_name(end_iter, text,\ iterator = self.plugin.emot_and_basic_re.finditer(otext)
other_tag, tag) else: # search for just urls + mail + formatting
else: iterator = self.plugin.basic_pattern_re.finditer(otext)
conversation_buffer.insert_with_tags_by_name(end_iter, text, tag) for match in iterator:
start, end = match.span()
special_text = otext[start:end]
if start != 0:
text_before_special_text = otext[index:start]
end_iter = conversation_buffer.get_end_iter()
if print_all_special:
conversation_buffer.insert_with_tags_by_name(end_iter, \
text_before_special_text, other_tag)
else:
conversation_buffer.insert(end_iter, text_before_special_text)
if not print_all_special:
other_tag = ''
index = end # update index
# == PRINT SPECIAL TEXT ==
# make it CAPS (emoticons keys are all CAPS)
possible_emot_ascii_caps = special_text.upper()
if possible_emot_ascii_caps in self.plugin.emoticons.keys():
#it's an emoticon
tag = None
emot_ascii = possible_emot_ascii_caps
print 'emoticon:', emot_ascii
end_iter = conversation_buffer.get_end_iter()
conversation_buffer.insert_pixbuf(end_iter, \
self.plugin.emoticons[emot_ascii])
#break # it used to be a return
elif special_text.startswith('mailto:'):
#it's a mail
tag = 'mail'
print tag
elif self.plugin.sth_at_sth_dot_sth_re.match(special_text):
#it's a mail
tag = 'mail'
print tag
elif special_text.startswith('*') and special_text.endswith('*'):
#it's a bold text
tag = 'bold'
special_text = special_text[1:-1] # remove * *
print tag
elif special_text.startswith('/') and special_text.endswith('/'):
#it's an italic text
tag = 'italic'
special_text = special_text[1:-1] # remove / /
print tag
elif special_text.startswith('_') and special_text.endswith('_'):
#it's an underlined text
tag = 'underline'
special_text = special_text[1:-1] # remove _ _
print tag
else:
#it's a url
tag = 'url'
print tag
end_iter = conversation_buffer.get_end_iter()
if tag is not None:
if tag in ['bold', 'italic', 'underline'] and other_tag:
conversation_buffer.insert_with_tags_by_name(end_iter,\
special_text, other_tag, tag)
else:
conversation_buffer.insert_with_tags_by_name(end_iter,\
special_text, tag)
return index, other_tag

View File

@ -38,9 +38,10 @@ gtk.glade.textdomain(APP)
GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade' GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade'
class Groupchat_window(chat): class Groupchat_window(Chat):
"""Class for Groupchat window"""
def __init__(self, room_jid, nick, plugin, account): def __init__(self, room_jid, nick, plugin, account):
chat.__init__(self, plugin, account, 'groupchat_window') Chat.__init__(self, plugin, account, 'groupchat_window')
self.nicks = {} self.nicks = {}
self.list_treeview = {} self.list_treeview = {}
self.subjects = {} self.subjects = {}
@ -72,14 +73,14 @@ class Groupchat_window(chat):
for room_jid in self.xmls: for room_jid in self.xmls:
self.plugin.send('GC_STATUS', self.account, (self.nicks[room_jid], \ self.plugin.send('GC_STATUS', self.account, (self.nicks[room_jid], \
room_jid, 'offline', 'offline')) room_jid, 'offline', 'offline'))
chat.on_window_destroy(self, widget, 'gc') Chat.on_window_destroy(self, widget, 'gc')
def on_groupchat_window_focus_in_event(self, widget, event): def on_groupchat_window_focus_in_event(self, widget, event):
"""When window get focus""" """When window get focus"""
chat.on_chat_window_focus_in_event(self, widget, event) Chat.on_chat_window_focus_in_event(self, widget, event)
def on_chat_notebook_key_press_event(self, widget, event): def on_chat_notebook_key_press_event(self, widget, event):
chat.on_chat_notebook_key_press_event(self, widget, event) Chat.on_chat_notebook_key_press_event(self, widget, event)
def get_role_iter(self, room_jid, role): def get_role_iter(self, room_jid, role):
model = self.list_treeview[room_jid].get_model() model = self.list_treeview[room_jid].get_model()
@ -429,7 +430,7 @@ class Groupchat_window(chat):
if dialog.get_response() != gtk.RESPONSE_YES: if dialog.get_response() != gtk.RESPONSE_YES:
return return
chat.remove_tab(self, jid, 'gc') Chat.remove_tab(self, jid, 'gc')
if len(self.xmls) > 0: if len(self.xmls) > 0:
self.plugin.send('GC_STATUS', self.account, (self.nicks[room_jid], \ self.plugin.send('GC_STATUS', self.account, (self.nicks[room_jid], \
room_jid, 'offline', 'offline')) room_jid, 'offline', 'offline'))
@ -441,7 +442,7 @@ class Groupchat_window(chat):
self.names[room_jid] = room_jid.split('@')[0] self.names[room_jid] = room_jid.split('@')[0]
self.xmls[room_jid] = gtk.glade.XML(GTKGUI_GLADE, 'gc_vbox', APP) self.xmls[room_jid] = gtk.glade.XML(GTKGUI_GLADE, 'gc_vbox', APP)
self.childs[room_jid] = self.xmls[room_jid].get_widget('gc_vbox') self.childs[room_jid] = self.xmls[room_jid].get_widget('gc_vbox')
chat.new_tab(self, room_jid) Chat.new_tab(self, room_jid)
self.nicks[room_jid] = nick self.nicks[room_jid] = nick
self.subjects[room_jid] = '' self.subjects[room_jid] = ''
self.list_treeview[room_jid] = self.xmls[room_jid].\ self.list_treeview[room_jid] = self.xmls[room_jid].\

View File

@ -692,7 +692,7 @@ class plugin:
return False return False
return True return True
def make_pattern(self): def make_regexps(self):
# regexp meta characters are: . ^ $ * + ? { } [ ] \ | ( ) # regexp meta characters are: . ^ $ * + ? { } [ ] \ | ( )
# one escapes the metachars with \ # one escapes the metachars with \
# \S matches anything but ' ' '\t' '\n' '\r' '\f' and '\v' # \S matches anything but ' ' '\t' '\n' '\r' '\f' and '\v'
@ -723,7 +723,20 @@ class plugin:
#doesn't detect (it's a feature :P) * bold* *bold * * bold * test*bold* #doesn't detect (it's a feature :P) * bold* *bold * * bold * test*bold*
formatting = r'(?<!\S)\*[^\s*]([^*]*[^\s*])?\*(?!\S)|' r'(?<!\S)/[^\s/]([^/]*[^\s/])?/(?!\S)|' r'(?<!\S)_[^\s_]([^_]*[^\s_])?_(?!\S)' formatting = r'(?<!\S)\*[^\s*]([^*]*[^\s*])?\*(?!\S)|' r'(?<!\S)/[^\s/]([^/]*[^\s/])?/(?!\S)|' r'(?<!\S)_[^\s_]([^_]*[^\s_])?_(?!\S)'
self.basic_pattern = links + mail + formatting basic_pattern = links + mail + formatting
self.basic_pattern_re = sre.compile(basic_pattern, sre.IGNORECASE)
emoticons_pattern = ''
for emoticon in self.emoticons: # travel tru emoticons list
emoticon_escaped = sre.escape(emoticon) # espace regexp metachars
emoticons_pattern += emoticon_escaped + '|'# | means or in regexp
emot_and_basic_pattern = emoticons_pattern + basic_pattern
self.emot_and_basic_re = sre.compile(emot_and_basic_pattern,\
sre.IGNORECASE)
# at least one character in 3 parts (before @, after @, after .)
self.sth_at_sth_dot_sth_re = sre.compile(r'\S+@\S+\.\S+')
def on_launch_browser_mailer(self, widget, url, kind): def on_launch_browser_mailer(self, widget, url, kind):
self.launch_browser_mailer(kind, url) self.launch_browser_mailer(kind, url)
@ -857,20 +870,7 @@ class plugin:
pix = gtk.gdk.pixbuf_new_from_file(emot_file) pix = gtk.gdk.pixbuf_new_from_file(emot_file)
self.emoticons[split_line[2*i]] = pix self.emoticons[split_line[2*i]] = pix
self.make_pattern() self.make_regexps()
# at least one character in 3 parts (before @, after @, after .)
self.sth_at_sth_dot_sth_re = sre.compile(r'\S+@\S+\.\S+')
emoticons_pattern = ''
for emoticon in self.emoticons: # travel tru emoticons list
emoticon_escaped = sre.escape(emoticon) # espace regexp metachars
emoticons_pattern += emoticon_escaped + '|'# | means or in regexp
self.emot_and_basic_pattern =\
emoticons_pattern + self.basic_pattern
print self.emot_and_basic_pattern
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
self.autoconnect() self.autoconnect()

View File

@ -38,10 +38,10 @@ gtk.glade.textdomain(APP)
GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade' GTKGUI_GLADE='plugins/gtkgui/gtkgui.glade'
class tabbed_chat_window(chat): class tabbed_chat_window(Chat):
"""Class for tabbed chat window""" """Class for tabbed chat window"""
def __init__(self, user, plugin, account): def __init__(self, user, plugin, account):
chat.__init__(self, plugin, account, 'tabbed_chat_window') Chat.__init__(self, plugin, account, 'tabbed_chat_window')
self.users = {} self.users = {}
self.new_user(user) self.new_user(user)
self.show_title() self.show_title()
@ -89,13 +89,13 @@ class tabbed_chat_window(chat):
def on_tabbed_chat_window_destroy(self, widget): def on_tabbed_chat_window_destroy(self, widget):
#clean self.plugin.windows[self.account]['chats'] #clean self.plugin.windows[self.account]['chats']
chat.on_window_destroy(self, widget, 'chats') Chat.on_window_destroy(self, widget, 'chats')
def on_tabbed_chat_window_focus_in_event(self, widget, event): def on_tabbed_chat_window_focus_in_event(self, widget, event):
chat.on_chat_window_focus_in_event(self, widget, event) Chat.on_chat_window_focus_in_event(self, widget, event)
def on_chat_notebook_key_press_event(self, widget, event): def on_chat_notebook_key_press_event(self, widget, event):
chat.on_chat_notebook_key_press_event(self, widget, event) Chat.on_chat_notebook_key_press_event(self, widget, event)
def on_clear_button_clicked(self, widget): def on_clear_button_clicked(self, widget):
"""When clear button is pressed : """When clear button is pressed :
@ -118,7 +118,7 @@ class tabbed_chat_window(chat):
if dialog.get_response() != gtk.RESPONSE_YES: if dialog.get_response() != gtk.RESPONSE_YES:
return return
chat.remove_tab(self, jid, 'chats') Chat.remove_tab(self, jid, 'chats')
if len(self.xmls) > 0: if len(self.xmls) > 0:
del self.users[jid] del self.users[jid]
@ -126,7 +126,7 @@ class tabbed_chat_window(chat):
self.names[user.jid] = user.name self.names[user.jid] = user.name
self.xmls[user.jid] = gtk.glade.XML(GTKGUI_GLADE, 'chats_vbox', APP) self.xmls[user.jid] = gtk.glade.XML(GTKGUI_GLADE, 'chats_vbox', APP)
self.childs[user.jid] = self.xmls[user.jid].get_widget('chats_vbox') self.childs[user.jid] = self.xmls[user.jid].get_widget('chats_vbox')
chat.new_tab(self, user.jid) Chat.new_tab(self, user.jid)
self.users[user.jid] = user self.users[user.jid] = user
self.redraw_tab(user.jid) self.redraw_tab(user.jid)
@ -235,42 +235,19 @@ class tabbed_chat_window(chat):
else: else:
otext = ttext otext = ttext
start = 0 # detect urls formatting and if the user has it on emoticons
end = 0 index, other_tag = self.detect_and_print_special_text(otext, jid, tag, print_all_special)
index = 0
if self.plugin.config['useemoticons']: # search for emoticons & urls # add the rest of text located in the index and after
my_re = sre.compile(self.plugin.emot_and_basic_pattern, sre.IGNORECASE)
iterator = my_re.finditer(otext)
else: # search for just urls
my_re = sre.compile(self.plugin.basic_pattern, sre.IGNORECASE)
iterator = my_re.finditer(otext)
for match in iterator:
start, end = match.span()
special_text = otext[start:end]
if start != 0:
text_before_special_text = otext[index:start]
end_iter = conversation_buffer.get_end_iter()
if print_all_special:
conversation_buffer.insert_with_tags_by_name(end_iter, \
text_before_special_text, tag)
else:
conversation_buffer.insert(end_iter, text_before_special_text)
if print_all_special:
self.print_special_text(special_text, jid, tag)
else:
self.print_special_text(special_text, jid, '')
index = end # update index
#add the rest in the index and after
end_iter = conversation_buffer.get_end_iter() end_iter = conversation_buffer.get_end_iter()
if print_all_special: if print_all_special:
conversation_buffer.insert_with_tags_by_name(end_iter, \ conversation_buffer.insert_with_tags_by_name(end_iter, \
otext[index:], tag) otext[index:], other_tag)
else: else:
conversation_buffer.insert(end_iter, otext[index:]) conversation_buffer.insert(end_iter, otext[index:])
#scroll to the end of the textview #scroll to the end of the textview
end_iter = conversation_buffer.get_end_iter()
end_rect = conversation_textview.get_iter_location(end_iter) end_rect = conversation_textview.get_iter_location(end_iter)
visible_rect = conversation_textview.get_visible_rect() visible_rect = conversation_textview.get_visible_rect()
end = False end = False