Commit 1b975172 authored by Philipp Hörist's avatar Philipp Hörist

Merge branch 'history-highlighting' into 'master'

Highlight all paragraphs of a message in the history window

See merge request !46
parents 8157cb38 deebe384
......@@ -628,7 +628,7 @@ class Logger:
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
found nothing to meet our demands
......@@ -645,7 +645,9 @@ class Logger:
last_second_of_day = start_of_day + seconds_in_a_day - 1
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)
AND time BETWEEN %d AND %d
ORDER BY time
......@@ -660,7 +662,7 @@ class Logger:
def get_search_results_for_query(self, jid, query, account, year=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
found nothing to meet our demands
......@@ -671,33 +673,25 @@ class Logger:
# Error trying to create a new jid_id. This means there is no log
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)
like_sql = '%' + query.replace("'", "''") + '%'
if year:
start_of_day = self.get_unix_time_from_date(year, month, day)
seconds_in_a_day = 86400 # 60 * 60 * 24
last_second_of_day = start_of_day + seconds_in_a_day - 1
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject FROM logs
WHERE (%s) AND message LIKE '%s'
AND time BETWEEN %d AND %d
ORDER BY time
''' % (where_sql, like_sql, start_of_day, last_second_of_day),
jid_tuple)
else:
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject FROM logs
WHERE (%s) AND message LIKE '%s'
ORDER BY time
''' % (where_sql, like_sql), jid_tuple)
where_sql, jid_tuple = self._build_contact_where(account, jid)
like_sql = '%' + query.replace("'", "''") + '%'
if year:
start_of_day = self.get_unix_time_from_date(year, month, day)
seconds_in_a_day = 86400 # 60 * 60 * 24
last_second_of_day = start_of_day + seconds_in_a_day - 1
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
WHERE (%s) AND message LIKE '%s'
AND time BETWEEN %d AND %d
ORDER BY time
''' % (where_sql, like_sql, start_of_day, last_second_of_day),
jid_tuple)
else:
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
WHERE (%s) AND message LIKE '%s'
ORDER BY time
''' % (where_sql, like_sql), jid_tuple)
results = self.cur.fetchall()
return results
......
......@@ -56,6 +56,7 @@ class Column(IntEnum):
UNIXTIME = 2
MESSAGE = 3
TIME = 4
LOG_LINE_ID = 5
class HistoryWindow:
"""
......@@ -85,8 +86,8 @@ class HistoryWindow:
self.results_window = xml.get_object('results_scrolledwindow')
self.search_in_date = xml.get_object('search_in_date')
# contact_name, date, message, time
model = Gtk.ListStore(str, str, str, str, str)
# jid, contact_name, date, message, time, log_line_id
model = Gtk.ListStore(str, str, str, str, str, int)
self.results_treeview.set_model(model)
col = Gtk.TreeViewColumn(_('Name'))
self.results_treeview.append_column(col)
......@@ -393,28 +394,31 @@ class HistoryWindow:
show_status = self.show_status_checkbutton.get_active()
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:
# 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[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,
KindConstant.STATUS):
continue
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
"""
if not message and kind not in (KindConstant.STATUS,
KindConstant.GCSTATUS):
return
buf = self.history_buffer
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':
timestamp_str = gajim.config.get('time_stamp')
timestamp_str = helpers.from_one_line(timestamp_str)
......@@ -429,12 +433,6 @@ class HistoryWindow:
tim = time.strftime('%X ', time.localtime(float(tim)))
buf.insert_with_tags_by_name(end_iter, tim + '\n',
'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_msg = ''
......@@ -512,9 +510,7 @@ class HistoryWindow:
else:
self.history_textview.print_real_text(message, name=contact_name,
xhtml=xhtml, additional_data=additional_data)
buffer_ = self.history_textview.tv.get_buffer()
eob = buffer_.get_end_iter()
buffer_.insert_with_tags_by_name(eob, '\n', 'eol')
self.history_textview.print_real_text('\n', text_tags=['eol'])
def on_search_entry_activate(self, widget):
text = self.search_entry.get_text()
......@@ -563,12 +559,13 @@ class HistoryWindow:
contact_name = self.completion_dict[jid][InfoColumn.NAME]
tim = row[1]
message = row[4]
log_line_id = row[6]
local_time = time.localtime(tim)
date = time.strftime('%Y-%m-%d', local_time)
# jid (to which log is assigned to), name, date, message,
# 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):
"""
......@@ -576,7 +573,7 @@ class HistoryWindow:
which results to showing conversation logs for that 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)
model = widget.get_model()
# 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:
self.calendar.select_month(month, year)
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
if year != cur_year or gtk_month != cur_month or day != cur_day:
self.calendar.select_day(day)
self._scroll_to_message_and_highlight(model[path][Column.LOG_LINE_ID])
def _scroll_to_result(self, unix_time):
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))
timestamp_str = gajim.config.get('time_stamp')
timestamp_str = helpers.from_one_line(timestamp_str)
tim = time.strftime(timestamp_str, local_time)
result = start_iter.forward_search(tim, Gtk.TextSearchFlags.TEXT_ONLY,
None)
if result is not None:
match_start_iter, match_end_iter = result
match_start_iter.backward_char() # include '[' or other character before time
match_end_iter.forward_line() # highlight all message not just time
self.history_buffer.apply_tag_by_name('highlight', match_start_iter,
match_end_iter)
mark = self.history_buffer.create_mark('match', match_start_iter, True)
GLib.idle_add(self.history_textview.tv.scroll_to_mark, mark,
0, True, 0.0, 0.5)
def iterator_has_mark(iterator, mark_name):
for mark in iterator.get_marks():
if mark.get_name() == mark_name:
return True
return False
# Clear previous search result by removing the highlighting. The scroll
# mark is automatically removed when the new one is set.
start = self.history_buffer.get_start_iter()
end = self.history_buffer.get_end_iter()
self.history_buffer.remove_tag_by_name('highlight', start, end)
log_line_id = str(log_line_id)
line = start
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):
# log conversation history?
......
......@@ -850,7 +850,7 @@ class HtmlTextView(Gtk.TextView):
self.connect('copy-clipboard', self.on_html_text_view_copy_clipboard)
self.id_ = self.connect('button-release-event',
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.config = gajim.config
self.interface = gajim.interface
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment