Add basic search highlighting

This commit is contained in:
René Stadler 2007-11-27 12:03:32 +02:00 committed by Stefan Sauer
parent 13d22d4254
commit b9156160e3
2 changed files with 83 additions and 1 deletions

View file

@ -447,6 +447,7 @@ class TextColumn (SizedColumn):
if self.get_data_func: if self.get_data_func:
data_func = self.get_data_func () data_func = self.get_data_func ()
assert data_func
id_ = self.id id_ = self.id
if id_ is not None: if id_ is not None:
def cell_data_func (column, cell, model, tree_iter): def cell_data_func (column, cell, model, tree_iter):
@ -663,6 +664,34 @@ class MessageColumn (TextColumn):
label_header = _("Message") label_header = _("Message")
id = LazyLogModel.COL_MESSAGE id = LazyLogModel.COL_MESSAGE
def __init__ (self, *a, **kw):
self.highlight = {}
TextColumn.__init__ (self, *a, **kw)
def get_data_func (self):
highlight = self.highlight
escape = gobject.markup_escape_text
def message_data_func (props, value, path):
line_index = path[0]
if line_index in highlight:
props.text = None
start, end = highlight[line_index]
props.markup = escape (value[:start]) + \
"<span background='blue' foreground='white'>" + \
escape (value[start:end]) + \
"</span>" + \
escape (value[end:])
else:
props.markup = None
props.text = value
return message_data_func
class ColumnManager (Common.GUI.Manager): class ColumnManager (Common.GUI.Manager):
column_classes = () column_classes = ()

View file

@ -146,6 +146,8 @@ class FindBarFeature (FeatureBase):
def handle_attach_window (self, window): def handle_attach_window (self, window):
self.window = window
ui = window.ui_manager ui = window.ui_manager
ui.insert_action_group (self.action_group, 0) ui.insert_action_group (self.action_group, 0)
@ -170,6 +172,8 @@ class FindBarFeature (FeatureBase):
def handle_detach_window (self, window): def handle_detach_window (self, window):
self.window = None
window.ui_manager.remove_ui (self.merge_id) window.ui_manager.remove_ui (self.merge_id)
self.merge_id = None self.merge_id = None
@ -186,13 +190,14 @@ class FindBarFeature (FeatureBase):
# FIXME: If the new search operation is stricter than the previous one # FIXME: If the new search operation is stricter than the previous one
# (find as you type!), re-use the previous results for a nice # (find as you type!), re-use the previous results for a nice
# performance gain (by only searching in previous results again) # performance gain (by only searching in previous results again)
del self.matches[:] self.clear_results ()
model = self.log_view.props.model model = self.log_view.props.model
search_string = entry.props.text search_string = entry.props.text
if search_string == "": if search_string == "":
self.logger.debug ("search string set to '', aborting search") self.logger.debug ("search string set to '', aborting search")
self.sentinel.abort () self.sentinel.abort ()
self.clear_results ()
# FIXME: Set start position # FIXME: Set start position
self.logger.debug ("starting search for %r", search_string) self.logger.debug ("starting search for %r", search_string)
self.operation = SearchOperation (model, search_string) self.operation = SearchOperation (model, search_string)
@ -203,6 +208,8 @@ class FindBarFeature (FeatureBase):
line_index = model.get_path (tree_iter)[0] line_index = model.get_path (tree_iter)[0]
self.matches.append (line_index) self.matches.append (line_index)
self.update_results ()
if len (self.matches) == 1: if len (self.matches) == 1:
self.scroll_view_to_line (line_index) self.scroll_view_to_line (line_index)
elif len (self.matches) > 10000: elif len (self.matches) > 10000:
@ -210,10 +217,56 @@ class FindBarFeature (FeatureBase):
def handle_search_complete (self): def handle_search_complete (self):
self.update_results (finished = True)
self.logger.debug ("search for %r complete, got %i results", self.logger.debug ("search for %r complete, got %i results",
self.operation.search_string, self.operation.search_string,
len (self.matches)) len (self.matches))
def update_results (self, finished = False):
INTERVAL = 100
if len (self.matches) % INTERVAL == 0:
new_matches = self.matches[-INTERVAL:]
elif finished:
new_matches = self.matches[-(len (self.matches) % INTERVAL):]
else:
return
model = self.log_view.props.model
column = self.window.column_manager.find_item (name = "message")
search = self.operation.search_string
start_path, end_path = self.log_view.get_visible_range ()
start_index, end_index = start_path[0], end_path[0]
for line_index in new_matches:
path = (line_index,)
tree_iter = model.get_iter (path)
message = model.get_value (tree_iter, model.COL_MESSAGE)
pos = message.find (search)
column.highlight[line_index] = (pos, pos + len (search),)
if line_index >= start_index and line_index <= end_index:
model.row_changed (path, tree_iter)
def clear_results (self):
column = self.window.column_manager.find_item (name = "message")
column.highlight.clear ()
model = self.log_view.props.model
start_path, end_path = self.log_view.get_visible_range ()
start_index, end_index = start_path[0], end_path[0]
for line_index in range (start_index, end_index + 1):
if line_index in self.matches:
tree_path = (line_index,)
tree_iter = model.get_iter (tree_path)
model.row_changed (tree_path, tree_iter)
del self.matches[:]
class Plugin (PluginBase): class Plugin (PluginBase):
features = [FindBarFeature] features = [FindBarFeature]