mythtvguide.py :  » Game-2D-3D » XBMC-MythTV » xbmcmythtv » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Game 2D 3D » XBMC MythTV 
XBMC MythTV » xbmcmythtv » mythtvguide.py
"""
$Id: mythtvguide.py,v 1.11 2007/05/17 01:43:01 frooby Exp $

Copyright (C) 2005 Tom Warkentin <tom@ixionstudios.com>

"""
from mythtvgui import Dialog
from singleton import getInstance
from time import strftime,strptime
import datetime
import mythtv
import mythtvgui
import mythtvscheduledetails
import mythtvstruct
import mythtvutil
import traceback
import os
import xbmc
import xbmcgui

def debug( str ):
    mythtvutil.debug( mythtvutil.DEBUG_GUI, str )

def showWindow(winDialog):
    """
    Function to create the program guide window.
    """
    debug( "> mythtvguide.showWindow()" )

    mythtvgui.checkSettings()
    win = Window()
    win.loadskin( "programguide.xml" )
    win.loadGuide()
    winDialog.close()    
    win.doModal()
    del win

    debug( "< mythtvguide.showWindow()" )

class Window( mythtvgui.BaseWindow ):

    # Mapping of Myth TV category names to color names (used as a file prefix)
    # in the program guide.
    categoryColors = {
        "Adults only"       : "red",
        "Basketball"        : "blue",
        "Children"          : "green",
        "Children-music"    : "green",
        "Children-special"  : "green",
        "Fishing"           : "blue",
        "Hockey"            : "blue",
        "News"              : "olive",
        "Newsmagazine"      : "olive",
        "Romance"           : "purple",
        "Romance-comedy"    : "purple",
        "Science"           : "cyan",
        "Science fiction"   : "orange",
        "Sitcom"            : "yellow",
        "Soap"              : "purple",
        "Sports"            : "blue",
        "Sports event"      : "blue",
        "Sports non-event"  : "blue",
        "Talk"              : "purple",
        "Travel"            : "cyan",
    }
    
    def __init__( self ):
        mythtvgui.BaseWindow.__init__( self )
        self.programs = []
        self.startTime = None
        self.endTime = None
        self.startChan = None
        self.endChan = None
        self.channels = None
        self.channelSpan = 2
        self.hourSpan = 2.0
        self.initialized = False
        self.channelCtls = []
        self.timeLabelCtls = []
        self.progButtonCtls = []
        self.topCtls = []
        self.bottomCtls = []
        self.leftCtls = []
        self.rightCtls = []
        self.prevFocus = None
        self.prevButtonInfo = None
        self.lock = 0

    def addProgramControl(  self,
                            program, info,
                            relX, relY, width, height ):
        """
        Method to add a control for a program in the guide.
        """
        debug( "> addProgramControl(program=[%s],info=[%s],relX=[%d],relY=[%d],"\
                "width=[%d],height=[%d])"%(
                program,info,relX,relY,width,height) )
        info['program'] = program
        if not program:
            info['nodata'] = True
            info['starttime'] = None
            info['title'] = mythtvutil.getLocalizedString( 108 )
            category = None
        else:
            info['nodata'] = False
            info['starttime'] = program.starttime()
            info['title'] = program.title()
            if program.starttimeAsTime() < self.startTime:
                info['title'] = "< " + info['title']
            if program.endtimeAsTime() > self.endTime:
                info['title'] += " >"
            category = program.category()
        info['start'] = relX
        info['end'] = relX + width
        # Create a button for navigation and hilighting. For some reason,
        # button labels don't get truncated properly.
        info['control'] = c = xbmcgui.ControlButton(
            relX + self.guide_x, relY + self.guide_y, width, height, "",
            mythtvutil.findMediaFile( self.getTexture(category, isFocus=True) ),
            mythtvutil.findMediaFile( self.getTexture(category, isFocus=False) ),
            alignment=(
                mythtvgui.ALIGN_CENTER_Y |
                mythtvgui.ALIGN_TRUNCATED ) )
        self.addControl( c )
        # Create a label to hold the name of the program.  Label text seems to
        # get truncated correctly...
        info['label'] = c = xbmcgui.ControlLabel(
            relX + self.guide_x, relY + self.guide_y, width, height,
            info['title'],
            alignment=mythtvgui.ALIGN_CENTER_Y | mythtvgui.ALIGN_TRUNCATED )
        self.addControl( c )
        self.progButtonCtls.append( info )
        debug( "< addProgramControl()" )
        return c

    def checkPageUp( self, focusControl ):
        """
        Method to check and to do a page up in the program guide.

        Returns:
        - False if no page change was done.
        - True if a page change was done.
        """
        paged = False
        if focusControl in self.topCtls:
            debug( "page up detected" )
            paged = True
            if self.startChan == 0:
                # wrap around
                pages = len( self.channels ) // self.channelSpan
                index = len( self.channels ) - (
                    len( self.channels ) % self.channelSpan) - pages
                self.setChannel( index )
            else:
                self.setChannel( self.startChan - (self.channelSpan - 1) )
            self.loadGuide()

            # check if we need to fix focus
            if not self.prevFocus:
                # find the control in the bottom row where previous button's
                # start falls within start/end range of control
                ctls = list( self.progButtonCtls )
                ctls.reverse()
                chanid = ctls[0]['chanid']
                start = self.prevButtonInfo['start']
                for c in ctls:
                    if chanid == c['chanid']:
                        if start >= c['start'] and \
                            start < c['end']:
                            self.prevFocus = c['control']
                            self.setFocus( self.prevFocus )
                            break
                    else:
                        break
        return paged

    def checkPageDown( self, focusControl ):
        """
        Method to check and to do a page down in the program guide.

        Returns:
        - False if no page change was done.
        - True if a page change was done.
        """
        paged = False
        if focusControl in self.bottomCtls:
            debug( "page down detected" )
            paged = True
            if self.endChan == len( self.channels ) - 1:
                # wrap around
                self.setChannel( 0 )
            else:
                self.setChannel( self.startChan + (self.channelSpan - 1) )
            self.loadGuide()

            # check if we need to fix focus
            if not self.prevFocus:
                # find the control in the top row where previous button's start
                # falls within start/end range of control
                chanid = self.progButtonCtls[0]['chanid']
                start = self.prevButtonInfo['start']
                for c in self.progButtonCtls:
                    if chanid == c['chanid']:
                        if start >= c['start'] and \
                            start < c['end']:
                            self.prevFocus = c['control']
                            self.setFocus( self.prevFocus )
                            break
                    else:
                        break
        return paged

    def checkPageLeft( self, focusControl ):
        """
        Method to check and to do a page left in the program guide.

        Returns:
        - False if no page change was done.
        - True if a page change was done.
        """
        paged = False
        if focusControl in self.leftCtls:
            debug( "page left detected" )
            paged = True
            delta = self.hourSpan - 0.5
            startTime = self.startTime - datetime.timedelta( hours=delta )
            self.setTime( startTime )
            self.loadGuide()

            # check if we need to fix focus
            if not self.prevFocus:
                chanid = self.prevButtonInfo['chanid']
                found = False
                prev = None
                # find the right most program on the same channel
                for c in self.progButtonCtls:
                    if not found and c['chanid'] == chanid:
                        found = True
                    elif found and c['chanid'] != chanid:
                        break
                    prev = c
                self.prevFocus = prev['control']
                self.setFocus( self.prevFocus )
                self.prevButtonInfo = None
        return paged

    def checkPageRight( self, focusControl ):
        """
        Method to check and to do a page right in the program guide.

        Returns:
        - False if no page change was done.
        - True if a page change was done.
        """
        paged = False
        if focusControl in self.rightCtls:
            debug( "page right detected" )
            paged = True
            delta = self.hourSpan - 0.5
            startTime = self.startTime + datetime.timedelta( hours=delta )
            self.setTime( startTime )
            self.loadGuide()

            # check if we need to fix focus
            if not self.prevFocus:
                chanid = self.prevButtonInfo['chanid']
                found = False
                prev = None
                ctls = self.progButtonCtls
                ctls.reverse()
                # find the left most program on the same channel
                for c in ctls:
                    if not found and c['chanid'] == chanid:
                        found = True
                    elif found and c['chanid'] != chanid:
                        break
                    prev = c
                self.prevFocus = prev['control']
                self.setFocus( self.prevFocus )
                self.prevButtonInfo = None
        return paged

    def doNavigation( self ):
        """
        Method to do navigation between controls and store lists of top,
        bottom, left, and right controls to detect when page changes must
        occur.
        """
        count = 0
        self.topCtls = []
        self.bottomCtls = []
        self.leftCtls = []
        self.rightCtls = []
        topChanId = None
        prevChanId = None
        prevCtl = None
        #
        # Loop through all buttons doing left to right, right to left, and
        # top to bottom navigation. Also keep track of top, left, and right
        # controls that are used to detect page up, left, and right.
        #
        for c in self.progButtonCtls:
            #debug( "title=[%s]"%c['title'] )
            if not topChanId:
                topChanId = c['chanid']
            if c['chanid'] == topChanId:
                # first row of controls are top controls
                self.topCtls.append( c['control'] )
                #debug( "top ctl=[%s]"%c['control'] )

            # do left to right and right to left navigation
            if not prevChanId:
                prevChanId = c['chanid']
            elif prevChanId != c['chanid']:
                # changed channel rows so previous control is a control on
                # right edge
                self.rightCtls.append( prevCtl )
                prevCtl = None
                prevChanId = c['chanid']
            if prevCtl:
                prevCtl.controlRight( c['control'] )
                c['control'].controlLeft( prevCtl )
                prevCtl = c['control']
            if not prevCtl:
                # control not set so this must be a control on left edge
                self.leftCtls.append( c['control'] )
                prevCtl = c['control']

            # now find the appropriate control below current one
            chanid = None
            found = False
            for c2 in self.progButtonCtls:
                if not found and c2['control'] == c['control']:
                    found = True
                elif found and not chanid and c2['chanid'] != c['chanid']:
                    chanid = c2['chanid']
                if found and chanid and chanid == c2['chanid']:
                    if c['start'] >= c2['start'] and c['start'] < c2['end']:
                        c['control'].controlDown( c2['control'] )
                        #debug( "%s VVV %s"%(c['title'],c2['title']) )
                        count += 1
                        break
                elif found and chanid and chanid != c2['chanid']:
                    break
        debug( "down count=%d"%count )
        count = 0
        ctls = list(self.progButtonCtls)
        ctls.reverse()
        bottomChanId = None
        #
        # Loop through all buttons in reverse to do bottom to top navigation.
        #
        for c in ctls:
            #debug( "title=[%s]"%c['title'] )
            if not bottomChanId:
                bottomChanId = c['chanid']
            if c['chanid'] == bottomChanId:
                # first row of controls are bottom controls
                self.bottomCtls.append( c['control'] )
                #debug( "bottom ctl=[%s]"%c['control'] )

            # now find the control that is above the current one
            chanid = None
            found = False
            for c2 in ctls:
                if not found and c2['control'] == c['control']:
                    found = True
                elif found and not chanid and c2['chanid'] != c['chanid']:
                    chanid = c2['chanid']
                if found and chanid and chanid == c2['chanid']:
                    if c['start'] >= c2['start'] and c['start'] < c2['end']:
                        c['control'].controlUp( c2['control'] )
                        #debug( "%s ^^^ %s"%(c['title'],c2['title']) )
                        count += 1
                        break
                elif found and chanid and chanid != c2['chanid']:
                    break
        debug( "up count=%d"%count )

        # if we have any controls, then the very last control on right edge
        # was missed in first loop (right controls are detected by row changes
        # but the last row quits the loop before detecting the control)
        if len( ctls ) > 0:
            # Note: This grabs last control from the reverse list of controls.
            self.rightCtls.append( ctls[0]['control'] )
        #debug( "right ctl=[%s]"%ctls[0]['control'] )

        debug( "top count=%d"%len(self.topCtls) )
        debug( "bottom count=%d"%len(self.bottomCtls) )
        debug( "left count=%d"%len(self.leftCtls) )
        debug( "right count=%d"%len(self.rightCtls) )

    def getTexture( self, category, isFocus ):
        """
        Method to figure out name of texture to use for the passed category.
        """
        # determine color
        if not category:
            color = "shade"
        else:
            if self.categoryColors.has_key(category):
                color = self.categoryColors[category]
            else:
                color = "shade"

        # determine alpha value
        if isFocus:
            alpha = "50"
        else:
            alpha = "25"

        # build texture file name
        return "%s_%s.png"%(color,alpha)

    def loadGuide( self ):
        """
        Method to load and display the program guide information.  If this is
        the first time being called, it initializes the program guide
        parameters.
        """
        debug( '> mythtvguide.Window.loadGuide()' )

        db = getInstance( mythtv.Database )

        if self.prevFocus:
            for c in self.progButtonCtls:
                if c['control'] == self.prevFocus:
                    self.prevButtonInfo = c
                    self.prevFocus = None
                    break

        if not self.initialized:
            # load variables from skin
            self.channel_x = int(self.getvalue( self.getoption( "channel_x" ) ))
            self.channel_h = int(self.getvalue( self.getoption("channel_h" ) ))
            self.channel_w = int(self.getvalue( self.getoption( "channel_w" ) ))
            self.channel_dx = int(self.getvalue( self.getoption( "channel_dx" )) )
            self.time_y = int(self.getvalue( self.getoption( "time_y" ) ))
            self.time_h = int(self.getvalue( self.getoption( "time_h" ) ))
            self.guide_x = int(self.getvalue( self.getoption( "guide_x" ) ))
            self.guide_y = int(self.getvalue( self.getoption( "guide_y" ) ))
            self.guide_dx = int(self.getvalue( self.getoption( "guide_dx" ) ))
            self.guide_dy = int(self.getvalue( self.getoption( "guide_dy" ) ))
            self.guide_w = int(self.getvalue( self.getoption( "guide_w" ) ))
            self.guide_h = int(self.getvalue( self.getoption( "guide_h" ) ))

            # calculate pixels per hour used repeatedly
            self.widthPerHour = self.guide_w / self.hourSpan 

            # calculate channel span that fits into guide height
            self.channelSpan = int(
                self.guide_h /
                (self.guide_dy+self.channel_h) )
            debug( "channelSpan=[%d]"%self.channelSpan )

            # allocate the remainder to vertical spacing between channels
            remainder = self.guide_h // (self.guide_dy+self.channel_h)
            self.guide_dy += (remainder / self.channelSpan)

            # initialize channel range and time range
            self.channels = db.getChannelList()
            self.setChannel( 0 )
            self.setTime(
                datetime.datetime.now() - datetime.timedelta( minutes=30 ) )

            self.initialized = True

        self.programs = db.getProgramListings(
            self.startTime, self.endTime,
            self.channels[self.startChan].chanid(),
            self.channels[self.endChan].chanid() )
        debug( "found %d rows"%len(self.programs) )

        self.render()

        if not self.prevButtonInfo:
            # set focus to the first control on the screen
            if len( self.progButtonCtls ) > 0:
                self.prevFocus = self.progButtonCtls[0]['control']
                self.setFocus( self.prevFocus )
            else:
                raise Exception, "No program information available."

    def onActionHook( self, action ):
        """
        Method that is called whenever an event occurs in the GUI.
        """
        debug( "> mythtvguide.Window.onActionHook( action=[%s] )"%action )
        ctl = self.getFocus()

        actionConsumed = False
        if action == mythtvgui.ACTION_MOVE_DOWN:
            actionConsumed = self.checkPageDown( self.prevFocus )
        elif action == mythtvgui.ACTION_MOVE_UP:
            actionConsumed =  self.checkPageUp( self.prevFocus )
        elif action == mythtvgui.ACTION_MOVE_LEFT:
            actionConsumed = self.checkPageLeft( self.prevFocus )
        elif action == mythtvgui.ACTION_MOVE_RIGHT:
            actionConsumed = self.checkPageRight( self.prevFocus )
        if not actionConsumed:
            self.prevFocus = ctl

        debug( "< mythtvguide.Window.onActionHook()" )
        return actionConsumed

    def onControlHook( self, control ):
        """
        Method called when a control is selected/clicked.
        """
        debug( "> mythtvguide.Window.onControlHook()" )

        actionConsumed = 1
        id = self.getcontrolid( control )
        program = None
        for c in self.progButtonCtls:
            if c['control'] == control:
                program = c['program']
                break
        if program:
            debug( "converting program to schedule" )
            schedule = mythtvstruct.ScheduleFromProgram( program )
            debug( "launching schedule details window" )
            rc = mythtvscheduledetails.showWindow( schedule )

        debug( "< mythtvguide.Window.onControlHook()" )
        return actionConsumed

    def render( self ):
        """
        Method to draw all the dynamic controls that represent the program
        guide information.
        """
        xbmcgui.lock()
        try:
            title = mythtvutil.getLocalizedString( 107 )
            title += ": %s - %s"%(
                self.startTime.strftime( "%x %X" ),
                self.endTime.strftime( "%x %X" ) )
            self.controls['title'].control.setLabel( title )
            self.renderChannels()
            self.renderTime()
            self.renderPrograms()
            self.doNavigation()
            xbmcgui.unlock()
        except:
            xbmcgui.unlock()
            raise

    def renderChannels( self ):
        """
        Method to draw the channel labels.
        """
        try:
            for c in self.channelCtls:
                if c.has_key( 'icon' ):
                    self.removeControl( c['icon'] )
                if c.has_key( 'label' ):
                    self.removeControl( c['label'] )
                if c.has_key( 'shade' ):
                    self.removeControl( c['shade'] )
                del c
            self.channelCtls = []

            cic = getInstance( mythtvgui.ChannelIconCache )
            x = self.channel_x
            y = self.guide_y
            h = (self.guide_h - self.channelSpan * self.guide_dy) / self.channelSpan
            iconW = h
            labelW = self.channel_w - iconW - self.guide_dx
            for i in range( self.startChan, self.endChan+1 ):
                c = {}
                # create shade image around channel label/icon
                c['shade'] = xbmcgui.ControlImage(
                    x, y, self.channel_w, h,
                    mythtvutil.findMediaFile( "shade_50.png" ) )
                self.addControl( c['shade'] )

                # create label control
                l = "%s %s"%(self.channels[i].channum(),self.channels[i].callsign())
                c['label'] = xbmcgui.ControlLabel(
                    x+iconW+self.channel_dx, y, labelW, h,
                    l, self.getoption( "channel_font" ),
                    alignment=mythtvgui.ALIGN_CENTER_Y )
                self.addControl( c['label'] )
                shost = str(getInstance( mythtv.Settings ).getSetting( "mythtv_host" ))
                file = mythtvgui.picBase + 'channels\\' + str(self.channels[i].channum()) + mythtvgui.picType
                if not os.path.exists(file):
                    try:
                        file = cic.findFile( self.channels[i], shost )
                    except:
                        debug(" renderChannels: nothing assigned to file")
                    
                debug( "file=[%s]"%file )
                if file:
                    # set channel icon
                    c['icon'] = xbmcgui.ControlImage( x, y, iconW, h, file )
                    self.addControl( c['icon'] )

                self.channelCtls.append( c )
                y += h + self.guide_dy
        except:
            debug("*** Failed to render channels ***")
            raise
        
    def renderPrograms( self ):
        """
        Method to draw the program buttons.  This manufactures buttons for
        missing guide data.
        """
        try:
            # clear out old controls
            for c in self.progButtonCtls:
                self.removeControl( c['control'] )
                del c['control']
                self.removeControl( c['label'] )
                del c['label']
            self.progButtonCtls = []

            self.widthPerHour = self.guide_w / self.hourSpan 
            chanH = (self.guide_h-self.channelSpan*self.guide_dy)/self.channelSpan

            # Loop through each channel filling the program guide area with
            # buttons.
            for i in range( self.startChan, self.endChan+1 ):
                noData = False
                chanX = 0
                chanY = (i-self.startChan) * (chanH + self.guide_dy)
                chanid = self.channels[i].chanid()
            
                # loop until we've filled the row for the channel
                while chanX < self.guide_w:
                    ctlInfo = {}
                    ctlInfo['chanid'] = chanid
                    p = None
                    if not noData:
                        # find the next program for the channel - this assumes
                        # programs are sorted in ascending time order for the channel
                        for prog in self.programs:
                            if prog.chanid() == chanid:
                                p = prog
                                self.programs.remove( prog )
                                break
                    if not p:
                        # no program found - create a no data control for the rest of
                        # the row
                        noData = True
                        w = self.guide_w - chanX
                        self.addProgramControl(
                            program=None, info=ctlInfo,
                            relX=chanX, relY=chanY, width=w, height=chanH )
                        chanX += w
                    else:
                        # found a program but we don't know if it start at the
                        # current spot in the row for the channel

                        # clamp start time
                        start = p.starttimeAsTime()
                        if start < self.startTime:
                            start = self.startTime

                        # clamp end time
                        end = p.endtimeAsTime()
                        if end > self.endTime:
                            end = self.endTime

                        # calculate x coord and width of label
                        start = start - self.startTime
                        debug( "start=%s"%start )
                        progX = start.seconds / (60.0*60.0) * self.widthPerHour
                        end = end - self.startTime
                        debug( "end=%s"%end )
                        progEndX = end.seconds / (60.0*60.0) * self.widthPerHour
                        progW = progEndX - progX

                        # check if we need no data before control 
                        if progX != chanX:
                            self.addProgramControl(
                                program=None, info=ctlInfo,
                                relX=chanX, relY=chanY,
                                width=(progX - chanX), height=chanH )
                            chanX = progX
                            ctlInfo = {}
                            ctlInfo['chanid'] = chanid

                        # add the control for the program
                        self.addProgramControl(
                            program=p, info=ctlInfo,
                            relX=progX, relY=chanY, width=progW, height=chanH )
                        chanX += progW
        except:
            debug("*** Failed to render programs ***")
            raise

    def renderTime( self ):
        """
        Method to draw the time labels for the program guide.
        """
        try:
            doInit = False
            if len( self.timeLabelCtls ) == 0:
                doInit = True

            numCols = int( self.hourSpan * 2 )
            x = self.guide_x
            y = self.time_y
            h = self.time_h
            w = (self.guide_w - numCols * self.guide_dx) / numCols
            t = self.startTime
            lastDay = t.day
            i = 0
            debug( "numCols=%d guide_w=%d"%(numCols, self.guide_w) )
            while i < numCols:
                if doInit:
                    debug( "x=%d y=%d w=%d h=%d"%(x,y,w,h) )
                    c = xbmcgui.ControlLabel(
                        x, y, w, h,
                        "", self.getoption("time_font") )
                    self.timeLabelCtls.append( c )
                    self.addControl( c )

                l = t.strftime( "%H:%M" )
                if t.day != lastDay:
                    l += "+1"
                debug( "l=[%s]"%l )
                self.timeLabelCtls[i].setLabel( l )
                t += datetime.timedelta( minutes=30 )
                i += 1
                x = x + w + self.guide_dx
                lastDay = t.day
        except:
            debug("*** Failed to render time ***")
            raise
            
        
    def setTime( self, startTime ):
        """
        Method to change the starting time of the program guide.  This is used
        to change pages horizontally.
        """
        self.startTime = startTime - datetime.timedelta(
            seconds=startTime.second,
            microseconds=startTime.microsecond )
        min = self.startTime.minute
        if min != 0:
            if min > 30:
                delta = 60 - min
            else:
                delta = 30 - min
            self.startTime = self.startTime + \
                datetime.timedelta( minutes=delta )
        self.endTime = self.startTime + \
            datetime.timedelta( hours=self.hourSpan )

        debug( "startTime=[%s] endTime=[%s]"%(self.startTime,self.endTime) )
        
    def setChannel( self, chanIndex ):
        """
        Method to change the starting channel index of the program guide.
        This is used to change pages vertically.
        """
        self.startChan = chanIndex
        if self.startChan < 0:
            self.startChan = 0
        self.endChan = self.startChan + self.channelSpan - 1
        if self.endChan > len(self.channels)-1:
            self.endChan = len(self.channels)-1

        debug( "start channel=[%s]"%self.channels[self.startChan].channum() )
        debug( "end channel=[%s]"%self.channels[self.endChan].channum() )

if __name__ == "__main__":
    try:
        mythtvutil.debugSetLevel( mythtvutil.DEBUG_SKIN | mythtvutil.DEBUG_GUI )
        mythtvutil.initialize()

        showWindow()

    except Exception, ex:
        traceback.print_exc()
        Dialog().ok( mythtvutil.getLocalizedString( 27 ), str( ex ) )

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.