Merge branch 'history-highlighting' into 'master'
Highlight all paragraphs of a message in the history window See merge request !46
This commit is contained in:
commit
1b975172d6
|
@ -628,7 +628,7 @@ class Logger:
|
||||||
|
|
||||||
def get_conversation_for_date(self, jid, year, month, day, account):
|
def get_conversation_for_date(self, jid, year, month, day, account):
|
||||||
"""
|
"""
|
||||||
Return contact_name, time, kind, show, message, subject
|
Return contact_name, time, kind, show, message, subject, additional_data, log_line_id
|
||||||
|
|
||||||
For each row in a list of tupples, returns list with empty tupple if we
|
For each row in a list of tupples, returns list with empty tupple if we
|
||||||
found nothing to meet our demands
|
found nothing to meet our demands
|
||||||
|
@ -645,7 +645,9 @@ class Logger:
|
||||||
last_second_of_day = start_of_day + seconds_in_a_day - 1
|
last_second_of_day = start_of_day + seconds_in_a_day - 1
|
||||||
|
|
||||||
self.cur.execute('''
|
self.cur.execute('''
|
||||||
SELECT contact_name, time, kind, show, message, subject, additional_data FROM logs
|
SELECT contact_name, time, kind, show, message, subject,
|
||||||
|
additional_data, log_line_id
|
||||||
|
FROM logs
|
||||||
WHERE (%s)
|
WHERE (%s)
|
||||||
AND time BETWEEN %d AND %d
|
AND time BETWEEN %d AND %d
|
||||||
ORDER BY time
|
ORDER BY time
|
||||||
|
@ -660,7 +662,7 @@ class Logger:
|
||||||
def get_search_results_for_query(self, jid, query, account, year=False,
|
def get_search_results_for_query(self, jid, query, account, year=False,
|
||||||
month=False, day=False):
|
month=False, day=False):
|
||||||
"""
|
"""
|
||||||
Returns contact_name, time, kind, show, message
|
Returns contact_name, time, kind, show, message, subject, log_line_id
|
||||||
|
|
||||||
For each row in a list of tupples, returns list with empty tupple if we
|
For each row in a list of tupples, returns list with empty tupple if we
|
||||||
found nothing to meet our demands
|
found nothing to meet our demands
|
||||||
|
@ -671,14 +673,6 @@ class Logger:
|
||||||
# Error trying to create a new jid_id. This means there is no log
|
# Error trying to create a new jid_id. This means there is no log
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if False: # query.startswith('SELECT '): # it's SQL query (FIXME)
|
|
||||||
try:
|
|
||||||
self.cur.execute(query)
|
|
||||||
except sqlite.OperationalError as e:
|
|
||||||
results = [('', '', '', '', str(e))]
|
|
||||||
return results
|
|
||||||
|
|
||||||
else: # user just typed something, we search in message column
|
|
||||||
where_sql, jid_tuple = self._build_contact_where(account, jid)
|
where_sql, jid_tuple = self._build_contact_where(account, jid)
|
||||||
like_sql = '%' + query.replace("'", "''") + '%'
|
like_sql = '%' + query.replace("'", "''") + '%'
|
||||||
if year:
|
if year:
|
||||||
|
@ -686,7 +680,7 @@ class Logger:
|
||||||
seconds_in_a_day = 86400 # 60 * 60 * 24
|
seconds_in_a_day = 86400 # 60 * 60 * 24
|
||||||
last_second_of_day = start_of_day + seconds_in_a_day - 1
|
last_second_of_day = start_of_day + seconds_in_a_day - 1
|
||||||
self.cur.execute('''
|
self.cur.execute('''
|
||||||
SELECT contact_name, time, kind, show, message, subject FROM logs
|
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
|
||||||
WHERE (%s) AND message LIKE '%s'
|
WHERE (%s) AND message LIKE '%s'
|
||||||
AND time BETWEEN %d AND %d
|
AND time BETWEEN %d AND %d
|
||||||
ORDER BY time
|
ORDER BY time
|
||||||
|
@ -694,7 +688,7 @@ class Logger:
|
||||||
jid_tuple)
|
jid_tuple)
|
||||||
else:
|
else:
|
||||||
self.cur.execute('''
|
self.cur.execute('''
|
||||||
SELECT contact_name, time, kind, show, message, subject FROM logs
|
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
|
||||||
WHERE (%s) AND message LIKE '%s'
|
WHERE (%s) AND message LIKE '%s'
|
||||||
ORDER BY time
|
ORDER BY time
|
||||||
''' % (where_sql, like_sql), jid_tuple)
|
''' % (where_sql, like_sql), jid_tuple)
|
||||||
|
|
|
@ -56,6 +56,7 @@ class Column(IntEnum):
|
||||||
UNIXTIME = 2
|
UNIXTIME = 2
|
||||||
MESSAGE = 3
|
MESSAGE = 3
|
||||||
TIME = 4
|
TIME = 4
|
||||||
|
LOG_LINE_ID = 5
|
||||||
|
|
||||||
class HistoryWindow:
|
class HistoryWindow:
|
||||||
"""
|
"""
|
||||||
|
@ -85,8 +86,8 @@ class HistoryWindow:
|
||||||
self.results_window = xml.get_object('results_scrolledwindow')
|
self.results_window = xml.get_object('results_scrolledwindow')
|
||||||
self.search_in_date = xml.get_object('search_in_date')
|
self.search_in_date = xml.get_object('search_in_date')
|
||||||
|
|
||||||
# contact_name, date, message, time
|
# jid, contact_name, date, message, time, log_line_id
|
||||||
model = Gtk.ListStore(str, str, str, str, str)
|
model = Gtk.ListStore(str, str, str, str, str, int)
|
||||||
self.results_treeview.set_model(model)
|
self.results_treeview.set_model(model)
|
||||||
col = Gtk.TreeViewColumn(_('Name'))
|
col = Gtk.TreeViewColumn(_('Name'))
|
||||||
self.results_treeview.append_column(col)
|
self.results_treeview.append_column(col)
|
||||||
|
@ -393,28 +394,31 @@ class HistoryWindow:
|
||||||
show_status = self.show_status_checkbutton.get_active()
|
show_status = self.show_status_checkbutton.get_active()
|
||||||
|
|
||||||
lines = gajim.logger.get_conversation_for_date(self.jid, year, month, day, self.account)
|
lines = gajim.logger.get_conversation_for_date(self.jid, year, month, day, self.account)
|
||||||
# lines holds list with tupples that have:
|
|
||||||
# contact_name, time, kind, show, message
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
# line[0] is contact_name, line[1] is time of message
|
# line[0] is contact_name, line[1] is time of message
|
||||||
# line[2] is kind, line[3] is show, line[4] is message, line[5] is subject
|
# line[2] is kind, line[3] is show, line[4] is message, line[5] is subject
|
||||||
# line[6] is additional_data
|
# line[6] is additional_data, line[7] is log_line_id
|
||||||
if not show_status and line[2] in (KindConstant.GCSTATUS,
|
if not show_status and line[2] in (KindConstant.GCSTATUS,
|
||||||
KindConstant.STATUS):
|
KindConstant.STATUS):
|
||||||
continue
|
continue
|
||||||
self._add_new_line(line[0], line[1], line[2], line[3], line[4],
|
self._add_new_line(line[0], line[1], line[2], line[3], line[4],
|
||||||
line[5], line[6])
|
line[5], line[6], line[7])
|
||||||
|
|
||||||
def _add_new_line(self, contact_name, tim, kind, show, message, subject, additional_data):
|
def _add_new_line(self, contact_name, tim, kind, show, message, subject,
|
||||||
|
additional_data, log_line_id):
|
||||||
"""
|
"""
|
||||||
Add a new line in textbuffer
|
Add a new line in textbuffer
|
||||||
"""
|
"""
|
||||||
if not message and kind not in (KindConstant.STATUS,
|
if not message and kind not in (KindConstant.STATUS,
|
||||||
KindConstant.GCSTATUS):
|
KindConstant.GCSTATUS):
|
||||||
return
|
return
|
||||||
|
|
||||||
buf = self.history_buffer
|
buf = self.history_buffer
|
||||||
end_iter = buf.get_end_iter()
|
end_iter = buf.get_end_iter()
|
||||||
|
|
||||||
|
# Make the beginning of every message searchable by its log_line_id
|
||||||
|
buf.create_mark(str(log_line_id), end_iter, left_gravity=True)
|
||||||
|
|
||||||
if gajim.config.get('print_time') == 'always':
|
if gajim.config.get('print_time') == 'always':
|
||||||
timestamp_str = gajim.config.get('time_stamp')
|
timestamp_str = gajim.config.get('time_stamp')
|
||||||
timestamp_str = helpers.from_one_line(timestamp_str)
|
timestamp_str = helpers.from_one_line(timestamp_str)
|
||||||
|
@ -429,12 +433,6 @@ class HistoryWindow:
|
||||||
tim = time.strftime('%X ', time.localtime(float(tim)))
|
tim = time.strftime('%X ', time.localtime(float(tim)))
|
||||||
buf.insert_with_tags_by_name(end_iter, tim + '\n',
|
buf.insert_with_tags_by_name(end_iter, tim + '\n',
|
||||||
'time_sometimes')
|
'time_sometimes')
|
||||||
else: # don't print time. So we print it as invisible to be able to
|
|
||||||
# search for it
|
|
||||||
timestamp_str = gajim.config.get('time_stamp')
|
|
||||||
timestamp_str = helpers.from_one_line(timestamp_str)
|
|
||||||
tim = time.strftime(timestamp_str, time.localtime(float(tim)))
|
|
||||||
buf.insert_with_tags_by_name(end_iter, tim, 'invisible')
|
|
||||||
|
|
||||||
tag_name = ''
|
tag_name = ''
|
||||||
tag_msg = ''
|
tag_msg = ''
|
||||||
|
@ -512,9 +510,7 @@ class HistoryWindow:
|
||||||
else:
|
else:
|
||||||
self.history_textview.print_real_text(message, name=contact_name,
|
self.history_textview.print_real_text(message, name=contact_name,
|
||||||
xhtml=xhtml, additional_data=additional_data)
|
xhtml=xhtml, additional_data=additional_data)
|
||||||
buffer_ = self.history_textview.tv.get_buffer()
|
self.history_textview.print_real_text('\n', text_tags=['eol'])
|
||||||
eob = buffer_.get_end_iter()
|
|
||||||
buffer_.insert_with_tags_by_name(eob, '\n', 'eol')
|
|
||||||
|
|
||||||
def on_search_entry_activate(self, widget):
|
def on_search_entry_activate(self, widget):
|
||||||
text = self.search_entry.get_text()
|
text = self.search_entry.get_text()
|
||||||
|
@ -563,12 +559,13 @@ class HistoryWindow:
|
||||||
contact_name = self.completion_dict[jid][InfoColumn.NAME]
|
contact_name = self.completion_dict[jid][InfoColumn.NAME]
|
||||||
tim = row[1]
|
tim = row[1]
|
||||||
message = row[4]
|
message = row[4]
|
||||||
|
log_line_id = row[6]
|
||||||
local_time = time.localtime(tim)
|
local_time = time.localtime(tim)
|
||||||
date = time.strftime('%Y-%m-%d', local_time)
|
date = time.strftime('%Y-%m-%d', local_time)
|
||||||
|
|
||||||
# jid (to which log is assigned to), name, date, message,
|
# jid (to which log is assigned to), name, date, message,
|
||||||
# time (full unix time)
|
# time (full unix time)
|
||||||
model.append((jid, contact_name, date, message, str(tim)))
|
model.append((jid, contact_name, date, message, str(tim), log_line_id))
|
||||||
|
|
||||||
def on_results_treeview_row_activated(self, widget, path, column):
|
def on_results_treeview_row_activated(self, widget, path, column):
|
||||||
"""
|
"""
|
||||||
|
@ -576,7 +573,7 @@ class HistoryWindow:
|
||||||
which results to showing conversation logs for that date
|
which results to showing conversation logs for that date
|
||||||
"""
|
"""
|
||||||
# get currently selected date
|
# get currently selected date
|
||||||
cur_year, cur_month = self.calendar.get_date()[0:2]
|
cur_year, cur_month, cur_day = self.calendar.get_date()
|
||||||
cur_month = gtkgui_helpers.make_gtk_month_python_month(cur_month)
|
cur_month = gtkgui_helpers.make_gtk_month_python_month(cur_month)
|
||||||
model = widget.get_model()
|
model = widget.get_model()
|
||||||
# make it a tupple (Y, M, D, 0, 0, 0...)
|
# make it a tupple (Y, M, D, 0, 0, 0...)
|
||||||
|
@ -595,33 +592,41 @@ class HistoryWindow:
|
||||||
if year != cur_year or gtk_month != cur_month:
|
if year != cur_year or gtk_month != cur_month:
|
||||||
self.calendar.select_month(month, year)
|
self.calendar.select_month(month, year)
|
||||||
|
|
||||||
|
if year != cur_year or gtk_month != cur_month or day != cur_day:
|
||||||
self.calendar.select_day(day)
|
self.calendar.select_day(day)
|
||||||
unix_time = model[path][Column.TIME]
|
|
||||||
self._scroll_to_result(unix_time)
|
|
||||||
#FIXME: one day do not search just for unix_time but the whole and user
|
|
||||||
# specific format of the textbuffer line [time] nick: message
|
|
||||||
# and highlight all that
|
|
||||||
|
|
||||||
def _scroll_to_result(self, unix_time):
|
self._scroll_to_message_and_highlight(model[path][Column.LOG_LINE_ID])
|
||||||
|
|
||||||
|
def _scroll_to_message_and_highlight(self, log_line_id):
|
||||||
"""
|
"""
|
||||||
Scroll to the result using unix_time and highlight line
|
Scroll to a message and highlight it
|
||||||
"""
|
"""
|
||||||
start_iter = self.history_buffer.get_start_iter()
|
|
||||||
local_time = time.localtime(float(unix_time))
|
def iterator_has_mark(iterator, mark_name):
|
||||||
timestamp_str = gajim.config.get('time_stamp')
|
for mark in iterator.get_marks():
|
||||||
timestamp_str = helpers.from_one_line(timestamp_str)
|
if mark.get_name() == mark_name:
|
||||||
tim = time.strftime(timestamp_str, local_time)
|
return True
|
||||||
result = start_iter.forward_search(tim, Gtk.TextSearchFlags.TEXT_ONLY,
|
return False
|
||||||
None)
|
|
||||||
if result is not None:
|
# Clear previous search result by removing the highlighting. The scroll
|
||||||
match_start_iter, match_end_iter = result
|
# mark is automatically removed when the new one is set.
|
||||||
match_start_iter.backward_char() # include '[' or other character before time
|
start = self.history_buffer.get_start_iter()
|
||||||
match_end_iter.forward_line() # highlight all message not just time
|
end = self.history_buffer.get_end_iter()
|
||||||
self.history_buffer.apply_tag_by_name('highlight', match_start_iter,
|
self.history_buffer.remove_tag_by_name('highlight', start, end)
|
||||||
match_end_iter)
|
|
||||||
mark = self.history_buffer.create_mark('match', match_start_iter, True)
|
log_line_id = str(log_line_id)
|
||||||
GLib.idle_add(self.history_textview.tv.scroll_to_mark, mark,
|
line = start
|
||||||
0, True, 0.0, 0.5)
|
while not iterator_has_mark(line, log_line_id):
|
||||||
|
if not line.forward_line():
|
||||||
|
return
|
||||||
|
|
||||||
|
match_start = line
|
||||||
|
match_end = match_start.copy()
|
||||||
|
match_end.forward_to_tag_toggle(self.history_buffer.eol_tag)
|
||||||
|
|
||||||
|
self.history_buffer.apply_tag_by_name('highlight', match_start, match_end)
|
||||||
|
mark = self.history_buffer.create_mark('match', match_start, True)
|
||||||
|
GLib.idle_add(self.history_textview.tv.scroll_to_mark, mark, 0, True, 0.0, 0.5)
|
||||||
|
|
||||||
def on_log_history_checkbutton_toggled(self, widget):
|
def on_log_history_checkbutton_toggled(self, widget):
|
||||||
# log conversation history?
|
# log conversation history?
|
||||||
|
|
|
@ -850,7 +850,7 @@ class HtmlTextView(Gtk.TextView):
|
||||||
self.connect('copy-clipboard', self.on_html_text_view_copy_clipboard)
|
self.connect('copy-clipboard', self.on_html_text_view_copy_clipboard)
|
||||||
self.id_ = self.connect('button-release-event',
|
self.id_ = self.connect('button-release-event',
|
||||||
self.on_left_mouse_button_release)
|
self.on_left_mouse_button_release)
|
||||||
self.get_buffer().create_tag('eol')
|
self.get_buffer().eol_tag = self.get_buffer().create_tag('eol')
|
||||||
self.tooltip = tooltips.BaseTooltip()
|
self.tooltip = tooltips.BaseTooltip()
|
||||||
self.config = gajim.config
|
self.config = gajim.config
|
||||||
self.interface = gajim.interface
|
self.interface = gajim.interface
|
||||||
|
|
Loading…
Reference in New Issue