|
| >
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 | # api: streamtuner2
# title: Search feature
# description: Provides the quick search box, and server/cache search window.
# version: 0.9
# type: feature
# category: ui
# config: -
# priority: core
#
# Configuration dialog for audio applications,
# general settings, and plugin activation and
# associated options.
#
from uikit import *
import channels
from config import *
from copy import copy
# Search window, and quicksearch box handler.
#
# Aux win: search dialog - keeps search text in self.q
# Quick search textbox - uses main.q instead
#
class search (AuxiliaryWindow):
# either current channel, or last channel (avoid searching in bookmarks)
current = None
# show search dialog
def menu_search(self, w):
self.search_dialog.show();
if not self.current or self.main.current_channel != "bookmarks":
self.current = self.main.current_channel
self.search_dialog_current.set_label("just %s" % self.main.channels[self.current].meta["title"])
# hide dialog box again
def cancel(self, *args):
self.search_dialog.hide()
return True # stop any other gtk handlers
# prepare variables
def prepare_search(self):
self.main.status("Searching... Stand back.")
self.cancel()
self.q = self.search_full.get_text().lower()
if self.search_dialog_all.get_active():
self.targets = self.main.channels.keys()
else:
self.targets = [self.current]
self.main.bookmarks.streams["search"] = []
# perform search
def cache_search(self, *w):
self.prepare_search()
entries = []
# which fields?
fields = ["title", "playing", "homepage"]
for i,cn in enumerate([self.main.channels[c] for c in self.targets]):
if cn.streams: # skip disabled plugins
# categories
for cat in cn.streams.keys():
# stations
for row in cn.streams[cat]:
# assemble text fields to compare
text = " ".join([str(row.get(f, " ")) for f in fields])
if text.lower().find(self.q) >= 0:
row = copy(row)
row["genre"] = c + " " + row.get("genre", "")
entries.append(row)
self.show_results(entries)
# display "search" in "bookmarks"
def show_results(self, entries):
self.main.status(1.0)
self.main.channel_switch(None, "bookmarks", 0)
self.main.bookmarks.set_category("search")
# insert data and show
self.main.channels["bookmarks"].streams["search"] = entries # we have to set it here, else .currentcat() might reset it
self.main.bookmarks.load("search")
# live search on directory server homepages
def server_search(self, w):
self.prepare_search()
entries = []
for i,cn in enumerate([self.main.channels[c] for c in self.targets]):
if cn.has_search: # "search" in cn.update_streams.func_code.co_varnames:
__print__(dbg.PROC, "has_search:", cn.module)
try:
add = cn.update_streams(cat=None, search=self.q)
for row in add:
row["genre"] = cn.meta["title"] + " " + row.get("genre", "")
entries += add
except:
continue
#main.status(main, 1.0 * i / 15)
self.show_results(entries)
# search text edited in text entry box
def quicksearch_set(self, w, *eat, **up):
# keep query string
self.main.q = self.search_quick.get_text().lower()
# get streams
c = self.main.channel()
rows = c.stations()
col = c.rowmap.index("search_col") # this is the gtk.ListStore index # which contains the highlighting color
# callback to compare (+highlight) rows
m = c.gtk_list.get_model()
m.foreach(self.quicksearch_treestore, (rows, self.main.q, col, col+1))
search_set = quicksearch_set
# callback that iterates over whole gtk treelist,
# looks for search string and applies TreeList color and flag if found
def quicksearch_treestore(self, model, path, iter, extra_data):
i = path[0]
(rows, q, color, flag) = extra_data
# compare against interesting content fields:
text = rows[i].get("title", "") + " " + rows[i].get("homepage", "")
# config.quicksearch_fields
text = text.lower()
# simple string match (probably doesn't need full search expression support)
if len(q) and text.find(q) >= 0:
model.set_value(iter, color, "#fe9") # highlighting color
model.set_value(iter, flag, True) # background-set flag
# color = 12 in liststore, flag = 13th position
else:
model.set_value(iter, color, "") # for some reason the cellrenderer colors get applied to all rows, even if we specify an iter (=treelist position?, not?)
model.set_value(iter, flag, False) # that's why we need the secondary -set option
#??
return False
|