Author: duncan
Date: Wed Aug 8 15:47:41 2007
New Revision: 9807
Log:
[ 1768790 ] Text Entry and Program Search
Patch from Adam Charrett
Added:
branches/rel-1/freevo/src/skins/main/buttongroup_area.py (contents, props
changed)
branches/rel-1/freevo/src/skins/main/textentry_area.py (contents, props
changed)
branches/rel-1/freevo/src/tv/plugins/search_programs.py (contents, props
changed)
Modified:
branches/rel-1/freevo/ChangeLog
branches/rel-1/freevo/share/skins/main/basic.fxd
branches/rel-1/freevo/src/skin.py
branches/rel-1/freevo/src/skins/main/main.py
Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog (original)
+++ branches/rel-1/freevo/ChangeLog Wed Aug 8 15:47:41 2007
@@ -17,6 +17,7 @@
--------------------------------
* Updated German translation (F#1770195)
+ * New Text Entry and Program Search (F#1768790)
* Updated alsamixer with event args and synchronous mixer control (F#1767928)
== Release 1.7.3 (2007-08-01) ==
Modified: branches/rel-1/freevo/share/skins/main/basic.fxd
==============================================================================
--- branches/rel-1/freevo/share/skins/main/basic.fxd (original)
+++ branches/rel-1/freevo/share/skins/main/basic.fxd Wed Aug 8 15:47:41 2007
@@ -819,35 +819,62 @@
<image x="758" y="max-32" width="32" height="32"
label="downarrow" filename="down.png"/>
</scrollabletext>
</headlines>
- <!--
- *******************************************************
- ** Button Bar TVGuide Info
- ******************************************************* -->
+
+ <!--
+ *******************************************************
+ ** Button Bar TVGuide Info
+ ******************************************************* -->
- <tvguideinfo>
- <screen layout="screen" x="0" y="0" width="800" height="600"/>
- <info layout="tvguideinfo program details" x="10" y="70"
width="780" height="80"/>
- <scrollabletext layout="info" x="10" y="160" width="740" height="420 -
buttonbar_height">
- <image x="758" y="160" width="32" height="32" label="uparrow"
filename="up.png"/>
- <image x="758" y="max-32" width="32" height="32" label="downarrow"
filename="down.png"/>
- </scrollabletext>
- </tvguideinfo>
-
- <layout label="tvguideinfo program details">
- <content x="0" y="0" type="text" spacing="20" font="default">
- <item type="default">
- <if expression="time">
- <text font="info font" align="right" width="max"
expression="time"/>
- <newline/>
- </if>
- <if expression="title">
- <text font="tv title" align="left" expression="title"/>
- <newline/>
- </if>
- </item>
- </content>
- </layout>
+ <tvguideinfo>
+ <screen layout="screen" x="0" y="0" width="800" height="600"/>
+ <info layout="tvguideinfo program details" x="10" y="70"
width="780" height="80"/>
+ <scrollabletext layout="info" x="10" y="160" width="740"
height="420 - buttonbar_height">
+ <image x="758" y="160" width="32" height="32" label="uparrow"
filename="up.png"/>
+ <image x="758" y="max-32" width="32" height="32"
label="downarrow" filename="down.png"/>
+ </scrollabletext>
+ </tvguideinfo>
+
+ <searchprograms>
+ <screen layout="screen" x="0" y="0" width="800" height="600"/>
+ <textentry layout="program search" x="10" y="70" width="780"
height="40"/>
+ <buttongroup layout="keyboard" x="10" y="120" width="780"
height="400"/>
+ </searchprograms>
+
+ <layout label="tvguideinfo program details">
+ <content x="0" y="0" type="text" spacing="20" font="default">
+ <item type="default">
+ <if expression="time">
+ <text font="info font" align="right" width="max"
expression="time"/>
+ <newline/>
+ </if>
+ <if expression="title">
+ <text font="tv title" align="left"
expression="title"/>
+ <newline/>
+ </if>
+ </item>
+ </content>
+ </layout>
+ <layout label="program search">
+ <background >
+ <rectangle size="2" color="0x000000" bgcolor="0xff000000"
radius="0"/>
+ </background>
+ <content x="2" y="2" width="MAX-4" height="MAX-4" type="text"
spacing="20" font="default" />
+ </layout>
+ <layout label="keyboard">
+ <content font="default">
+ <item type="padding" width="5" height="5" />
+ <item type="default" font="tv" align="center" valign="center">
+ <rectangle bgcolor="0xff000000" color="0x000000" size="2"
radius="10" x="0"
+ y="0" width="max" height="max"/>
+ </item>
+
+ <item type="selected" font="tv selected" align="center"
valign="center">
+ <rectangle bgcolor="tv selection" size="2" radius="10"
color="0x000000" x="0"
+ y="0" width="max" height="max"/>
+ </item>
+ </content>
+ </layout>
</skin>
</freevo>
<!-- Keep this comment at the end of the file
Modified: branches/rel-1/freevo/src/skin.py
==============================================================================
--- branches/rel-1/freevo/src/skin.py (original)
+++ branches/rel-1/freevo/src/skin.py Wed Aug 8 15:47:41 2007
@@ -186,6 +186,215 @@
self.build_page()
+class TextEntry:
+ """
+ Data model for a single line of editable text.
+ """
+
+ def __init__(self, text, left_to_right=True):
+ """
+ Initialise the model with the specified text and direction of input.
+ """
+ self.text = text
+ self.left_to_right = left_to_right
+ self.caret_position = 0
+
+
+ def caret_left(self):
+ """
+ Moves the caret, marking the position the next character will be
+ inserted at, left one character.
+ """
+ self.caret_position -= 1
+ if self.caret_position < 0:
+ self.caret_position = 0
+
+
+ def caret_right(self):
+ """
+ Moves the caret, marking the position the next character will be
+ inserted at, right one character.
+ """
+ self.caret_position += 1
+ if self.caret_position > len(self.text):
+ self.caret_position = len(self.text)
+
+
+ def delete_char_at_caret(self):
+ """
+ Delete one character at the current caret position and possibly update
+ the caret position.
+ """
+ # TODO: Right to Left handling
+ if self.caret_position == 0:
+ return
+ if self.caret_position == 1:
+ self.text = self.text[self.caret_position:]
+ else:
+ self.text = self.text[:self.caret_position - 1] +
self.text[self.caret_position:]
+ self.caret_position -= 1
+
+ def insert_char_at_caret(self, char):
+ """
+ Insert one character at the current caret positon and possibly update
+ the caret position.
+ """
+ if self.caret_position == 0:
+ self.text = char + self.text
+ elif self.caret_position == len(self.text):
+ self.text = self.text + char
+ else:
+ self.text = self.text[:self.caret_position] + char +
self.text[self.caret_position:]
+
+ # TODO: Right to Left handling
+ self.caret_position += 1
+
+
+class Button:
+ """
+ Data model representing one button in a button group/grid.
+ """
+
+ def __init__(self, text, action, arg):
+ """
+ Initialise the model which will display the text specified and
+ call the action function with the specified argument when selected.
+ """
+ self.text = text
+ self.action = action
+ self.arg = arg
+
+
+ def select(self):
+ """
+ Call the action function associate with this button.
+ """
+ if self.action:
+ self.action(self.arg)
+
+
+class ButtonGroup:
+ """
+ Data model used to describe a grid of Buttons.
+
+ Instance varaiables:
+ buttons = List of buttons rows containing a list of buttons
(columns).
+ rows = Number of rows in the group.
+ columns = Number of columns per row.
+ selected_button = Currently Selected button.
+ selected_row = The row of the currently selected button.
+ selected_column =
+ """
+
+ def __init__(self, rows, columns):
+ """
+ Initialise the button group to contain the specified number of rows and
+ columns of buttons.
+ """
+ self.rows = rows
+ self.columns = columns
+ self.selected_row = -1
+ self.selected_column = -1
+ self.selected_button = None
+ self.buttons = []
+ for r in range(rows):
+ button_row = []
+ for c in range(columns):
+ button_row.append(None)
+ self.buttons.append(button_row)
+
+
+ def set_button(self, row, column, button):
+ """
+ Set the button at the specified row and column to be the one supplied.
+ The first button added to the group will be the first selected button.
+ """
+ self.buttons[row][column] = button
+ if self.selected_button == None:
+ self.selected_button = button
+ self.selected_row = row
+ self.selected_column = column
+
+
+ def get_button(self, row, column):
+ """
+ Retrieve the button at the specified row and column.
+ """
+ return self.buttons[row][column]
+
+
+ def move_up(self):
+ """
+ Select the button above the currently selected button.
+ """
+ if self.selected_row == 0:
+ return False
+ for r in range(self.selected_row-1, -1, -1):
+ if self.buttons[r][self.selected_column]:
+ self.selected_row = r
+ self.selected_button = self.buttons[r][self.selected_column]
+ return True
+ return False
+
+
+ def move_down(self):
+ """
+ Select the button below the currently selected button.
+ """
+ if self.selected_row + 1 == self.rows:
+ return False
+ for r in range(self.selected_row+1, self.rows):
+ if self.buttons[r][self.selected_column]:
+ self.selected_row = r
+ self.selected_button = self.buttons[r][self.selected_column]
+ return True
+ return False
+
+
+ def move_left(self):
+ """
+ Select the button to the left of the currently selected button.
+ """
+ if self.selected_column == 0:
+ return False
+ for c in range(self.selected_column - 1, -1, -1):
+ if self.buttons[self.selected_row][c]:
+ self.selected_column = c
+ self.selected_button = self.buttons[self.selected_row][c]
+ return True
+ return False
+
+
+ def move_right(self):
+ """
+ Select the button to the right of the currently selected button.
+ """
+ if self.selected_column + 1 == self.columns:
+ return False
+ for c in range(self.selected_column + 1, self.columns):
+ if self.buttons[self.selected_row][c]:
+ self.selected_column = c
+ self.selected_button = self.buttons[self.selected_row][c]
+ return True
+ return False
+
+
+ def set_selected(self, button):
+ """
+ Set the selected button to the one specified.
+ Returns True if the button was selected, False if the button is not in
+ the group.
+ """
+ for r in range(self.rows):
+ for c in range(self.columns):
+ if self.buttons[r][c] == button:
+ self.selected_row = r
+ self.selected_column = c
+ self.selected_button = button
+ return True
+ return False
+
+
def get_singleton():
"""
Returns an initialized skin object, containing the users preferred
Added: branches/rel-1/freevo/src/skins/main/buttongroup_area.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/skins/main/buttongroup_area.py Wed Aug 8
15:47:41 2007
@@ -0,0 +1,106 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# textentry_area.py - A text entry area for the Freevo skin
+# -----------------------------------------------------------------------
+# $Id$
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+import copy
+import types
+from area import Skin_Area
+from skin_utils import *
+from skin import eval_attr
+import config
+
+class Buttongroup_Area(Skin_Area):
+ """
+ this call defines the Button Group area
+ """
+
+ def __init__(self):
+ Skin_Area.__init__(self, 'buttongroup')
+ self.button_group = None
+
+ def update_content_needed(self):
+ """
+ check if the content needs an update
+ """
+ return True
+
+
+ def update_content(self):
+ """
+ update the listing area
+ """
+
+ menuw = self.menuw
+ settings = self.settings
+ layout = self.layout
+ area = self.area_val
+ content = self.calc_geometry(layout.content, copy_object=True)
+
+ if not hasattr(menuw, "button_group"):
+ return
+
+ button_group = menuw.button_group
+
+ if self.button_group != button_group:
+ self.button_group = button_group
+
+ unselected_style = content.types['default']
+ selected_style = content.types['selected']
+
+ # Overload the item type for the padding variables
+ padding_type = content.types['padding']
+ if padding_type:
+ padding_horizontal = padding_type.width
+ padding_vertical = padding_type.height
+ else:
+ padding_horizontal = 2
+ padding_vertical = 2
+
+ rows = button_group.rows
+ columns = button_group.columns
+ button_width = (content.width - (padding_horizontal * (columns - 1)))/
columns
+ button_height = (content.height - (padding_vertical * (rows - 1)))/
rows
+ y = content.y
+ for row in button_group.buttons:
+ x = content.x
+ for button in row:
+ if button is not None:
+ if button == button_group.selected_button:
+ style = selected_style
+ else:
+ style = unselected_style
+ if style.rectangle:
+ w,h,r = self.get_item_rectangle(style.rectangle,
button_width, button_height)
+ self.drawroundbox(x, y, r.width, r.height, r)
+ self.drawstring(button.text, style.font, content, x, y,
button_width, button_height,
+ align_h=style.align, align_v=style.valign)
+ x += button_width + padding_horizontal
+
+ y += button_height + padding_vertical
Modified: branches/rel-1/freevo/src/skins/main/main.py
==============================================================================
--- branches/rel-1/freevo/src/skins/main/main.py (original)
+++ branches/rel-1/freevo/src/skins/main/main.py Wed Aug 8 15:47:41 2007
@@ -80,8 +80,11 @@
from info_area import Info_Area
from default_areas import Screen_Area, Title_Area, Subtitle_Area,
Plugin_Area
from scrollabletext_area import Scrollabletext_Area
+ from textentry_area import Textentry_Area
+ from buttongroup_area import Buttongroup_Area
- for a in ( 'screen', 'title', 'subtitle', 'view', 'listing', 'info',
'plugin', 'scrollabletext'):
+ for a in ( 'screen', 'title', 'subtitle', 'view', 'listing', 'info',
+ 'plugin', 'scrollabletext', 'textentry',
'buttongroup'):
self.areas[a] = eval('%s_Area()' % a.capitalize())
self.areas['tvlisting'] = TVListing_Area()
Added: branches/rel-1/freevo/src/skins/main/textentry_area.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/skins/main/textentry_area.py Wed Aug 8
15:47:41 2007
@@ -0,0 +1,118 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# scrollabletext_area.py - A scrollable text area for the Freevo skin
+# -----------------------------------------------------------------------
+# $Id$
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+import copy
+import types
+from area import Skin_Area
+from skin_utils import *
+from skin import eval_attr
+import config
+
+class Textentry_Area(Skin_Area):
+ """
+ this call defines the Text Entry area
+ """
+
+ def __init__(self):
+ Skin_Area.__init__(self, 'textentry')
+ self.text_entry = None
+
+ def update_content_needed(self):
+ """
+ check if the content needs an update
+ """
+ return True
+
+
+ def update_content(self):
+ """
+ update the listing area
+ """
+
+ menuw = self.menuw
+ settings = self.settings
+ layout = self.layout
+ area = self.area_val
+ content = self.calc_geometry(layout.content, copy_object=True)
+
+ if not hasattr(menuw, "text_entry"):
+ return
+
+ text_entry = menuw.text_entry
+
+ if self.text_entry != text_entry:
+ self.text_entry = text_entry
+ self.offset = 0
+
+ text = ''
+ total_width = 0
+ font = content.font
+ width = content.width
+ caret_x = 0
+ offset = self.offset
+
+ caret_position = text_entry.caret_position
+ pygame_font = font.font.font
+
+ if offset > caret_position:
+ offset = caret_position - 1
+ if offset < 0:
+ offset = 0
+ else:
+ total_width = 0
+ new_offset = caret_position
+
+ for i in range(caret_position, -1, -1):
+ temp_text = text_entry.text[i:caret_position]
+ total_width = font.font.stringsize(temp_text)
+ if total_width > width:
+ break
+ offset = i
+
+ self.offset = offset
+
+ total_width = 0
+ for i in range(offset, len(text_entry.text)):
+ total_width = font.font.stringsize(text_entry.text[offset:i+1])
+ if total_width > width:
+ break
+ text = text_entry.text[offset:i+1]
+
+ caret_text = text[:caret_position - offset]
+ # We need a more exact position than is returned by the OSDFont class
(which
+ # caches character sizes but doesn't take account of kerning)
+ caret_x,h = pygame_font.size(caret_text)
+
+ # Draw Caret
+ self.drawroundbox(content.x + caret_x, content.y, 2, content.height,
(content.color, 0, 0x00000000, 0))
+
+ # Draw text
+ self.drawstring(text, font, content, x=content.x, align_v='center',
ellipses='', dim=False)
Added: branches/rel-1/freevo/src/tv/plugins/search_programs.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/tv/plugins/search_programs.py Wed Aug 8
15:47:41 2007
@@ -0,0 +1,286 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# view_recordings.py - Directory handling
+# -----------------------------------------------------------------------
+# $Id$
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+import os
+import os.path
+import datetime
+import traceback
+import re
+import stat
+import copy
+import time
+
+import rc
+import config
+import util
+import plugin
+import osd
+import tv.epg_xmltv
+
+from gui import sounds
+from gui.PopupBox import PopupBox
+from gui.AlertBox import AlertBox
+from item import Item
+from event import *
+from menu import MenuItem, Menu
+from tv.program_display import ProgramItem
+
+# Create the skin_object object
+import skin
+skin_object = skin.get_singleton()
+skin_object.register('searchprograms', ('screen', 'textentry', 'buttongroup',
'plugin'))
+
+class PluginInterface(plugin.MainMenuPlugin):
+ def __init__(self):
+ plugin.MainMenuPlugin.__init__(self)
+
+ self._type = 'mainmenu_tv'
+ self.parent = None
+
+ def items(self, parent):
+ self.parent = parent
+ return [SearchPrograms(parent)]
+
+class SearchPrograms(Item):
+ def __init__(self, parent):
+ Item.__init__(self, parent, skin_type='tv')
+ self.name = _('Search Programs')
+ self.text_entry = skin.TextEntry('')
+ self.type = 'searchprograms'
+
+ #
+ # Create button groups for alphabet/numbers/symbols
+ #
+
+ # Create common buttons
+ self.search_button = skin.Button(_('Search'),
self.search_for_programs, None)
+ self.left_button = skin.Button(_('Left'), self.move_caret, 'left')
+ self.right_button = skin.Button(_('Right'), self.move_caret, 'right')
+ self.delete_button = skin.Button(_('Delete'), self.delete_char, None)
+
+
+ self.alphabet_button_group = skin.ButtonGroup(6, 7)
+ keys = _('ABCDEFGHIJKLMNOPQRSTUVWXYZ ')
+ self.__init_keyboard_buttons(keys, self.alphabet_button_group)
+
+ self.numbers_button_group = skin.ButtonGroup(6, 7)
+ keys = _('1234567890')
+ self.__init_keyboard_buttons(keys, self.numbers_button_group)
+
+ self.symbols_button_group = skin.ButtonGroup(6, 7)
+ keys = _('!"#$%^&*();:\'@~?,.<>-=+\[]{}')
+ self.__init_keyboard_buttons(keys, self.symbols_button_group)
+
+ characters_button = skin.Button(_('ABC'), self.change_button_group,
self.alphabet_button_group)
+ numbers_button = skin.Button(_('123'), self.change_button_group,
self.numbers_button_group)
+ symbols_button = skin.Button(_('Symbls'), self.change_button_group,
self.symbols_button_group)
+
+ self.numbers_button_group.set_button(0, 5, characters_button)
+ self.symbols_button_group.set_button(0, 5, characters_button)
+
+ self.alphabet_button_group.set_button(1, 5, numbers_button)
+ self.symbols_button_group.set_button(1, 5, numbers_button)
+
+ self.alphabet_button_group.set_button(2, 5, symbols_button)
+ self.numbers_button_group.set_button(2, 5, symbols_button)
+
+ self.button_group = self.alphabet_button_group
+
+
+ def actions(self):
+ return [(self.show_search, self.name)]
+
+
+ def show_search(self, arg=None, menuw=None):
+ self.menuw = menuw
+ #self.__redraw = False
+ #rc.app(self)
+ #skin_object.draw('searchprograms', self)
+ menuw.pushmenu(self)
+
+ def refresh(self):
+ self.__redraw = False
+ skin_object.draw('searchprograms', self)
+
+ def eventhandler(self, event, menuw=None):
+ """
+ eventhandler
+ """
+ consumed = False
+
+# if event is MENU_BACK_ONE_MENU:
+# rc.app(None)
+# self.menuw.refresh()
+# consumed = True
+
+ if event is MENU_SELECT:
+ sounds.play_sound(sounds.MENU_SELECT)
+ self.button_group.selected_button.select()
+ consumed = True
+
+ elif event in (MENU_LEFT, MENU_RIGHT, MENU_DOWN, MENU_UP):
+ if event is MENU_LEFT:
+ self.__redraw = self.button_group.move_left()
+ elif event is MENU_RIGHT:
+ self.__redraw = self.button_group.move_right()
+ elif event is MENU_DOWN:
+ self.__redraw = self.button_group.move_down()
+ elif event is MENU_UP:
+ self.__redraw = self.button_group.move_up()
+
+ if self.__redraw:
+ sounds.play_sound(sounds.MENU_NAVIGATE)
+ consumed = True
+
+ if self.__redraw:
+ skin_object.draw('searchprograms', self)
+ self.__redraw = False
+ return consumed
+
+
+ def insert_key(self, arg):
+ self.text_entry.insert_char_at_caret(arg)
+ self.__redraw = True
+
+
+ def move_caret(self, arg):
+ if arg == 'left':
+ self.text_entry.caret_left()
+ elif arg == 'right':
+ self.text_entry.caret_right()
+ self.__redraw = True
+
+
+ def delete_char(self, arg):
+ self.text_entry.delete_char_at_caret()
+ self.__redraw = True
+
+
+ def change_button_group(self, arg):
+ self.button_group = arg
+ self.button_group.set_selected(self.button_group.buttons[0][0])
+ self.__redraw = True
+
+
+ def __init_keyboard_buttons(self, keys, button_group):
+ r = 0
+ c = 0
+ for key in keys:
+ if key == ' ':
+ text = _('Space')
+ else:
+ text = key
+ button_group.set_button(r, c, skin.Button(text, self.insert_key,
key))
+ c += 1
+ if c == 5:
+ r += 1
+ c = 0
+ # Add common buttons to the group
+ button_group.set_button(0,6, self.search_button)
+ button_group.set_button(1,6, self.left_button)
+ button_group.set_button(2,6, self.right_button)
+ button_group.set_button(3,6, self.delete_button)
+
+ def search_for_programs(self, arg):
+ text = self.text_entry.text
+ pop = PopupBox(text=_('Searching, please wait...'))
+ pop.show()
+ (result, matches) = self.findMatches(text)
+ pop.destroy()
+
+ items = []
+ if result:
+ _debug_('search found %s matches' % len(matches))
+
+ f = lambda a, b: cmp(a.start, b.start)
+ matches.sort(f)
+ for prog in matches:
+ items.append(ProgramItem(self, prog, context='search'))
+ else:
+ if matches == 'no matches':
+ msgtext = _('No matches found for %s') % text
+ AlertBox(text=msgtext).show()
+ return
+ AlertBox(text=_('findMatches failed: %s') % matches).show()
+ return
+ search_menu = Menu(_( 'Search Results' ), items,
+ item_types = 'tv program menu')
+
+ self.menuw.pushmenu(search_menu)
+ self.menuw.refresh()
+
+ def findMatches(self, find=None, movies_only=None):
+ global guide
+
+ _debug_('findMatches: %s' % find, config.DINFO)
+
+ matches = []
+ max_results = 500
+
+ if not find and not movies_only:
+ _debug_('nothing to find', config.DINFO)
+ return (FALSE, 'no search string')
+
+ self.updateGuide()
+
+ pattern = '.*' + find + '\ *'
+ regex = re.compile(pattern, re.IGNORECASE)
+ now = time.time()
+
+ for ch in guide.chan_list:
+ for prog in ch.programs:
+ if now >= prog.stop:
+ continue
+ if not find or regex.match(prog.title) or
regex.match(prog.desc) \
+ or regex.match(prog.sub_title):
+ if movies_only:
+ # We can do better here than just look for the MPAA
+ # rating. Suggestions are welcome.
+ if 'MPAA' in prog.utf2str().getattr('ratings').keys():
+ matches.append(prog.utf2str())
+ _debug_('PROGRAM MATCH 2: %s' % prog, config.DINFO)
+ else:
+ # We should never get here if not find and not
+ # movies_only.
+ matches.append(prog.utf2str())
+ _debug_('PROGRAM MATCH 3: %s' % prog, config.DINFO)
+ if len(matches) >= max_results:
+ break
+
+ _debug_('Found %d matches.' % len(matches), config.DINFO)
+
+ if matches:
+ return (TRUE, matches)
+ return (FALSE, 'no matches')
+
+
+ def updateGuide(self):
+ global guide
+ guide = tv.epg_xmltv.get_guide()
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog