Skip to content

Commit 418e508

Browse files
authored
Highlight search string matches in bold (#328)
1 parent 161154a commit 418e508

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

data/settings.appdata.xml.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
</description>
4848
<issues>
4949
<issue url="https://github.com/elementary/switchboard/issues/182">Search returns alphabetically sorted list after clicking on a search result</issue>
50+
<issue url="https://github.com/elementary/switchboard/issues/149">Highlight search string matches in bold</issue>
5051
</issues>
5152
</release>
5253

src/SearchView.vala

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,12 @@ public class Switchboard.SearchView : Gtk.Box {
7676
return true;
7777
}
7878

79-
return search_text.down () in ((SearchRow) listbox_row).last_item.down ();
79+
bool valid = search_text.down () in ((SearchRow) listbox_row).last_item.down ();
80+
if (valid) {
81+
((SearchRow) listbox_row).pattern = search_entry.text;
82+
}
83+
84+
return valid;
8085
}
8186

8287
private int sort_func (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) {
@@ -146,6 +151,16 @@ public class Switchboard.SearchView : Gtk.Box {
146151
public string last_item { get; construct; }
147152
public string uri { get; construct; }
148153

154+
private Gtk.Label title;
155+
private Gtk.Label description_label;
156+
157+
public string pattern {
158+
set {
159+
title.set_markup (highlight_text (last_item, value));
160+
description_label.set_markup (highlight_text (description, value));
161+
}
162+
}
163+
149164
public SearchRow (string icon_name, string description, string uri) {
150165
var path = description.split ("");
151166
var last_item = path[path.length - 1];
@@ -163,14 +178,18 @@ public class Switchboard.SearchView : Gtk.Box {
163178
icon_size = LARGE
164179
};
165180

166-
var title = new Gtk.Label (last_item) {
167-
halign = START
181+
title = new Gtk.Label (null) {
182+
halign = START,
183+
use_markup = true
168184
};
185+
title.set_markup (GLib.Markup.escape_text (last_item, -1));
169186

170-
var description_label = new Gtk.Label (description) {
187+
description_label = new Gtk.Label (null) {
171188
ellipsize = MIDDLE,
172-
halign = START
189+
halign = START,
190+
use_markup = true
173191
};
192+
description_label.set_markup (GLib.Markup.escape_text (description, -1));
174193
description_label.add_css_class (Granite.STYLE_CLASS_DIM_LABEL);
175194
description_label.add_css_class (Granite.STYLE_CLASS_SMALL_LABEL);
176195

@@ -183,5 +202,28 @@ public class Switchboard.SearchView : Gtk.Box {
183202

184203
child = grid;
185204
}
205+
206+
private string highlight_text (string _text, string search_term) {
207+
string text = GLib.Markup.escape_text (_text, -1);
208+
209+
if (search_term.length <= 0) {
210+
return text;
211+
}
212+
213+
try {
214+
Regex regex = new Regex (Regex.escape_string (search_term), RegexCompileFlags.CASELESS);
215+
string highlighted_text = regex.replace (text, text.length, 0, "<b>\\0</b>");
216+
return escape_markup_but_preserve_b_tags (highlighted_text);
217+
} catch (Error e) {
218+
return text;
219+
}
220+
}
221+
222+
private string escape_markup_but_preserve_b_tags (string text) {
223+
string escaped_text = GLib.Markup.escape_text (text, -1);
224+
escaped_text = escaped_text.replace ("&lt;b&gt;", "<b>").replace ("&lt;/b&gt;", "</b>");
225+
escaped_text = escaped_text.replace ("&amp;amp;", "&amp;");
226+
return escaped_text;
227+
}
186228
}
187229
}

0 commit comments

Comments
 (0)