示例#1
0
    def onPlayBackStarted(self):
        from resources.lib.zattooDB import ZattooDB
        _zattooDB_ = ZattooDB()
        live = 'false'
        streams = xbmc.getInfoLabel('Player.Filenameandpath')
        showID = xbmc.getInfoLabel('VideoPlayer.Writer')
        channel = xbmc.getInfoLabel('VideoPlayer.Director')
        _zattooDB_.set_playing(channel, showID, streams, 0)

        # load Keymap for liveTV
        if streams.find('dash-live') > -1 or streams.find(
                'hls5-live') > -1 or streams.find(
                    'dashenc-live') > -1 or streams.find('hls7-live') > -1:
            live = 'true'
            self.loadKeymap()
        else:
            self.unloadKeymap()

        ret = xbmcgui.Window(12005).getProperty('after_recall')

        if ret == "2":
            program = _zattooDB_.get_showID(showID)
            nextprog = _zattooDB_.getPrograms(
                {'index': [channel]}, True,
                program[0]['end_date'] + datetime.timedelta(seconds=20),
                program[0]['end_date'] + datetime.timedelta(seconds=50))
            debug('Nextprog' + str(nextprog))
            start = to_seconds(nextprog[0]['start_date']) + 60
            now = to_seconds(datetime.datetime.now())
            while start > to_seconds(datetime.datetime.now()):
                xbmc.sleep(100)
            channel = nextprog[0]['channel']
            showID = nextprog[0]['showID']
            add = 'true'
            restart = 'true'
            start = 0
            end = 0
            xbmc.executebuiltin('RunPlugin("plugin://' + __addonId__ +
                                '/?mode=watch_c&id=' + channel + '&showID=' +
                                showID + '&restart=' + restart + '&add=' +
                                add + '")')
        elif ret == "1" and live == 'false':
            add = 'true'
            restart = 'false'
            showID = '1'
            end = 0
            start = 0
            xbmc.executebuiltin('RunPlugin("plugin://' + __addonId__ +
                                '/?mode=watch_c&id=' + channel + '&add=' +
                                add + '")')
示例#2
0
class EPG(xbmcgui.WindowXML):
    CHANNELS_PER_PAGE = 8

    C_MAIN_DATE = 4000
    C_MAIN_TITLE = 4020
    C_MAIN_TIME = 4021
    C_MAIN_DESCRIPTION = 4022
    C_MAIN_IMAGE = 4023
    C_MAIN_LOGO = 4024
    C_MAIN_TIMEBAR = 4100
    C_MAIN_LOADING = 4200
    C_MAIN_LOADING_PROGRESS = 4201
    C_MAIN_LOADING_TIME_LEFT = 4202
    C_MAIN_LOADING_CANCEL = 4203
    C_MAIN_MOUSE_CONTROLS = 4300
    C_MAIN_MOUSE_HOME = 4301
    C_MAIN_MOUSE_LEFT = 4302
    C_MAIN_MOUSE_UP = 4303
    C_MAIN_MOUSE_DOWN = 4304
    C_MAIN_MOUSE_RIGHT = 4305
    C_MAIN_MOUSE_EXIT = 4306
    C_MAIN_BACKGROUND = 4600
    C_MAIN_EPG = 5000
    C_MAIN_EPG_VIEW_MARKER = 5001
    C_MAIN_OSD = 6000
    C_MAIN_OSD_TITLE = 6001
    C_MAIN_OSD_TIME = 6002
    C_MAIN_OSD_DESCRIPTION = 6003
    C_MAIN_OSD_CHANNEL_LOGO = 6004
    C_MAIN_OSD_CHANNEL_TITLE = 6005

    def __new__(cls, currentNr):
        # GreenAir: change path
       if __addon__.getSetting('livetv') == "true":
           return super(EPG, cls).__new__(cls, 'script-tvguide-main-livetv.xml', ADDON.getAddonInfo('path'))
       else:
           return super(EPG, cls).__new__(cls, 'script-tvguide-main.xml', ADDON.getAddonInfo('path'))
    def __init__(self, currentNr):
        super(EPG, self).__init__()
#        self.notification = None
        self.redrawingEPG = False
        self.isClosing = False
        self.controlAndProgramList = list()
        self.ignoreMissingControlIds = list()
        self.channelIdx = currentNr
        self.focusPoint = Point()
        self.epgView = EPGView()
        self.lastAction={'action':'', 'time':time.time(), 'count':0}

        # find nearest half hour
        self.viewStartDate = datetime.datetime.today()
        self.viewStartDate -= datetime.timedelta(minutes=self.viewStartDate.minute % 30, seconds=self.viewStartDate.second)
        xbmcgui.Window(10000).setProperty('zattoo_runningView',"epg")

    def getControl(self, controlId):
        try:
            return super(EPG, self).getControl(controlId)
            
        except:
            if controlId in self.ignoreMissingControlIds:
                return None
            if not self.isClosing:
                xbmcgui.Dialog().ok("Control not found "+str(controlId), strings(SKIN_ERROR_LINE1), strings(SKIN_ERROR_LINE2), strings(SKIN_ERROR_LINE3))
                self.close()
            return None

    def close(self):
        xbmcgui.Window(10000).setProperty('zattoo_runningView',"")
        #super(EPG, self).close()
        super(EPG, self).close()
        # if not self.isClosing:
            # self.isClosing = True
            # super(EPG, self).close()

    def onInit(self):
        self.db = ZattooDB()
        control = self.getControl(self.C_MAIN_EPG_VIEW_MARKER)
        if control:
            left, top = control.getPosition()
            self.focusPoint.x = left
            self.focusPoint.y = top
            self.epgView.left = left
            self.epgView.top = top
            self.epgView.right = left + control.getWidth()
            self.epgView.bottom = top + control.getHeight()
            self.epgView.width = control.getWidth()
            self.epgView.cellHeight = control.getHeight() / CHANNELS_PER_PAGE

            # draw epg on open
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)

#        self.notification = Notification(self.database, ADDON.getAddonInfo('path')+'/resources/epg')
        self.updateTimebar()
                
        self.getControl(4400).setVisible(False)
        self.getControl(4401).setVisible(True)



    def onAction(self, action):
        actionId=action.getId()
        #print('EPG:'+str(actionId))
        if actionId in [ACTION_PARENT_DIR, KEY_NAV_BACK, ACTION_PREVIOUS_MENU]:
            self.close()
            return

        elif actionId == ACTION_MOUSE_MOVE:
            # GreenAir: don't show mouse-move infowindow
            #self._showControl(self.C_MAIN_MOUSE_CONTROLS)
            return

        controlInFocus = None
        currentFocus = self.focusPoint

        try:
            controlInFocus = self.getFocus()
           
            if controlInFocus in [elem.control for elem in self.controlAndProgramList]:
                (left, top) = controlInFocus.getPosition()
                currentFocus = Point()
                currentFocus.x = left + (controlInFocus.getWidth() // 2)
                currentFocus.y = top + (controlInFocus.getHeight() // 2)
        except Exception:
            
            control = self._findControlAt(self.focusPoint)
            
            if control is None and len(self.controlAndProgramList) > 0:
                control = self.controlAndProgramList[0].control
            if control is not None:
                self.setFocus(control)
                return

        if actionId in [ACTION_LEFT, ACTION_4, ACTION_JUMP_SMS4]:
            self._left(currentFocus)
        elif actionId in [ACTION_RIGHT, ACTION_6, ACTION_JUMP_SMS6]:
            self._right(currentFocus)
        elif actionId in [ACTION_UP, ACTION_2, ACTION_JUMP_SMS2]:

            self._up(currentFocus)
        elif actionId in [ACTION_DOWN, ACTION_8, ACTION_JUMP_SMS8]:
            self._down(currentFocus)
        elif actionId in [ACTION_9, ACTION_JUMP_SMS9]:
            self.viewStartDate -= datetime.timedelta(hours=2)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
        elif actionId in [ACTION_3, ACTION_JUMP_SMS3]:
            self.viewStartDate += datetime.timedelta(hours=2)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
        elif actionId in NEXT_DAY:
            self._nextDay()
        elif actionId in PREV_DAY:
            self._previousDay()
        elif actionId in NEXT_SITE:
            self._moveUp(CHANNELS_PER_PAGE)
        elif actionId in PREV_SITE:
            self._moveDown(CHANNELS_PER_PAGE)
        elif actionId == ACTION_MOUSE_WHEEL_UP:
            self._moveUp(scrollEvent=True)
        elif actionId == ACTION_MOUSE_WHEEL_DOWN:
            self._moveDown(scrollEvent=True)
        elif actionId in [KEY_HOME, ACTION_5, ACTION_JUMP_SMS5]:
            self.viewStartDate = datetime.datetime.today()
            self.viewStartDate -= datetime.timedelta(minutes=self.viewStartDate.minute % 30,
                                                     seconds=self.viewStartDate.second)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
        elif actionId == ACTION_0:
            self.getDate()
        
            
    def onClick(self, controlId):
        if controlId in [self.C_MAIN_LOADING_CANCEL, self.C_MAIN_MOUSE_EXIT]:
            self.close()
            return
            
        elif controlId == 4350: #touch start
            self.getControl(4401).setVisible(False)
            self.getControl(4400).setVisible(True)
        
        elif controlId == 4303:
            self._moveUp(CHANNELS_PER_PAGE)
        elif controlId == 4304:
            self._moveDown(CHANNELS_PER_PAGE)
        elif controlId == 4302:
            self.viewStartDate -= datetime.timedelta(hours=2)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
            return
        elif controlId == 4305:
            self.viewStartDate += datetime.timedelta(hours=2)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
            return
        elif controlId == 4307:
            self._previousDay()
        elif controlId == 4308:
            self._nextDay()
        elif controlId == 4309:
            self.getDate()
        elif controlId == 4001:
            self.viewStartDate = datetime.datetime.today()
            self.viewStartDate -= datetime.timedelta(minutes=self.viewStartDate.minute % 30,
                                                     seconds=self.viewStartDate.second)
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
        
        if self.isClosing: return

        program = self._getProgramFromControl(self.getControl(controlId))
        if program is None: return

        start = int(time.mktime(program['start_date'].timetuple()))
        end = int(time.mktime(program['end_date'].timetuple()))
        now = time.time()
        url=''
        

        try:
            if accountData['nonlive']['recording_number_limit'] > 0:
                if _zattooDB_.getRecord(program['showID']) > datetime.datetime.now():
                    RECORD = True
                else:
                    RECORD = False
            else:
                RECORD = False
        except: 
            RECORD = False
        
        try:
            if accountData['nonlive']['replay_availability'] == 'available' and _zattooDB_.getRestart(program['showID']) > datetime.datetime.now():
                RECALL = True
            else:
                RECALL = False
        except:
            RECALL = False
        

        try:
          SERIE=accountData['nonlive']['recording_series_eligible']
        except KeyError:SERIE = False
        
        # Set String for SubMenu
        recall_func = __addon__.getSetting('after_recall')
        if recall_func == "3": RECALL_MENU = ADD_TO_PLAYLIST
        else: RECALL_MENU = PLAY_FROM_START
        
        # if startime is in the future -> setup recording
        if start > now :
        #if not self.premiumUser: xbmcgui.Dialog().ok('Error',' ',strings(ERROR_NO_PREMIUM))
            if RECORD:
                #print 'SERIES:  ' + str(_zattooDB_.getSeries(program['showID']))
                if SERIE and _zattooDB_.getSeries(program['showID']):#Series record avilable
                    ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'),[strings(RECORD_SHOW), strings(RECORD_SERIES)])
                    if ret==0: #recording
                        setup_recording({'program_id': program['showID']})
                        return
                    elif ret==1: #recording_series
                        setup_recording({'program_id': program['showID'], 'series': 'true'})
                        return
                    else: return
                elif xbmcgui.Dialog().ok(program['title'], strings(RECORD_SHOW) + "?"):
                    setup_recording({'program_id': program['showID']})
                    return
                else:return
            else: 
                xbmcgui.Dialog().ok('Error', strings(ERROR_NO_PREMIUM))
                return
        # else if endtime is in the past -> recall
        elif end < now:
            if RECALL and RECORD:
                if __addon__.getSetting('epgPlay')=='true':
                    url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&start=" + str(start) + "&end=" + str(end)
                else:
                    if SERIE and _zattooDB_.getSeries(program['showID']):#Series record avilable
                        ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'),[strings(RECALL_MENU), strings(RECORD_SHOW), strings(RECORD_SERIES)])
                        if ret==0:  #recall
                            url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                        elif ret==1: #record
                            #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                            setup_recording({'program_id': program['showID']})
                            return
                        elif ret==2: #record series
                            #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                            setup_recording({'program_id': program['showID'], 'series': 'true'})
                            return
                        else: return
                    else: 
                        ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'),[strings(RECALL_MENU), strings(RECORD_SHOW)])
                        if ret==0:  #recall
                            url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                        elif ret==1: #record
                            #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                            setup_recording({'program_id': program['showID']})
                            return
                        else: return
            elif RECALL:
                ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'),[strings(RECALL_MENU)])
                if ret==0:  #recall
                    url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                else: return
            else:
                xbmcgui.Dialog().ok('Error', strings(ERROR_NO_PREMIUM))
                return
        # else currently playing
        else:
            if __addon__.getSetting('epgPlay')=='true' :
                url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
            elif RECALL and RECORD:
                if _zattooDB_.getSeries(program['showID']): #Series record avilable
                    ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'), [strings(WATCH_CHANNEL), strings(RECALL_MENU), strings(RECORD_SHOW), strings(RECORD_SERIES)])
                    if ret==0:  #watch live
                        url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
                    elif ret==1:  #recall
                        url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                       
                    elif ret==2: #record
                        #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                        setup_recording({'program_id': program['showID']})
                        return
                    elif ret==3: #record series
                        #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                        setup_recording({'program_id': program['showID'], 'series': 'true'})
                        return
                    else: return
                else:
                    ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'), [strings(WATCH_CHANNEL), strings(RECALL_MENU), strings(RECORD_SHOW)])
                    if ret==0:  #watch live
                        url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
                    elif ret==1:  #recall
                        url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                    elif ret==2: #record
                        #url = "plugin://"+__addonId__+"/?mode=record_p&program_id=" + program['showID']
                        setup_recording({'program_id': program['showID']})
                        return
                    else: return

            elif RECORD: 
                ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'), [strings(WATCH_CHANNEL), strings(RECORD_SHOW)])
                if ret==0:  #watch live
                    url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
                
                elif ret==1: #record
                    
                    setup_recording({'program_id': program['showID']})
                    return
                else: return
            elif RECALL:
                ret = xbmcgui.Dialog().select(program['channel']+': '+program['title']+' '+program['start_date'].strftime('%H:%M')+' - '+program['end_date'].strftime('%H:%M'), [strings(WATCH_CHANNEL), strings(RECALL_MENU)])
                if ret==0:  #watch live
                    url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
                elif ret==1:  #recall
                    url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID'] + "&restart=true" 
                   
                
            else:
                url = "plugin://"+__addonId__+"/?mode=watch_c&id=" + program['channel'] + "&showID=" + program['showID']
                
        self.channelIdx = _zattooDB_.get_channelNr(program['channel'])
        ret = __addon__.getSetting('after_recall')
        
        if ret == '2':
            player = xbmc.Player()
            if player.isPlaying():
                debug('Player is playing')
                player.stop()
            del player
            
        xbmc.executebuiltin('RunPlugin(%s)' % url)
        

    def setFocusId(self, controlId):
        control = self.getControl(controlId)
        if control: self.setFocus(control)

    def setFocus(self, control):
        if control in [elem.control for elem in self.controlAndProgramList]:
          
            (left, top) = control.getPosition()
            if left > self.focusPoint.x or left + control.getWidth() < self.focusPoint.x:
                self.focusPoint.x = left
            self.focusPoint.y = top + (control.getHeight() // 2)

        super(EPG, self).setFocus(control)

    def onFocus(self, controlId):
        
        try:
            controlInFocus = self.getControl(controlId)
        except Exception:
            return
       
        program = self._getProgramFromControl(controlInFocus)
        if program is None: return

        if accountData['nonlive']['replay_availability'] == 'available':
            if program['restart'] > datetime.datetime.now() and program['start_date'] < datetime.datetime.now():
                RECALL = True
            else:
                RECALL = False
        else:
            RECALL = False

        # Test auf Restart
        if RECALL:
            
            if program['description'] == None:
                self.setControlLabel(self.C_MAIN_TITLE, '[B][COLOR gold]R[/COLOR][/B]  [B]%s[/B]' % program['title'])
            else:
                self.setControlLabel(self.C_MAIN_TITLE, '[B][COLOR gold]R[/COLOR][/B]  [B]%s[/B]  -  [B]%s[/B]' % (program['title'], program['description']))
        else:
            #debug("Showinfo test")
            if program['description'] == None:
                self.setControlLabel(self.C_MAIN_TITLE, '[B]%s[/B]' % program['title'])
            else:
                self.setControlLabel(self.C_MAIN_TITLE, '[B]%s[/B]  -  [B]%s[/B]' % (program['title'], program['description']))

        if program['start_date'] or program['end_date']:
            self.setControlLabel(self.C_MAIN_TIME,'[B]%s - %s[/B]' % (self.formatTime(program['start_date']), self.formatTime(program['end_date'])))
        else:
            self.setControlLabel(self.C_MAIN_TIME, '')

        self.setControlText(self.C_MAIN_DESCRIPTION, '')
        #if hasattr(self, 'descriptionTimer'):self.descriptionTimer.cancel() 
        #self.descriptionTimer= threading.Timer(0.2, self._showDescription, [program['showID']])
        #self.descriptionTimer.start()
        self._showDescription(program['showID'])
        #self.setControlImage(self.C_MAIN_LOGO, program['channel_logo'])

        if program['image_small'] is not None:
            self.setControlImage(self.C_MAIN_IMAGE, program['image_small'])
            #self.setControlImage(self.C_MAIN_BACKGROUND, program['image_small'])

#       if ADDON.getSetting('program.background.enabled') == 'true' and program['image_large'] is not None:
#           self.setControlImage(self.C_MAIN_BACKGROUND, program['image_large'])
    
    def _showDescription(self, id):
        description = ZattooDB().getShowInfo(id,'description')
        if description == '': description = strings(NO_DESCRIPTION)
        self.setControlText(self.C_MAIN_DESCRIPTION, description)


    def _pressed(self,action):
        pressed=False
        last=self.lastAction
        timeDiff=time.time()-last['time']

        if last['count']>0: checkDiff=1
        else: checkDiff=0.2

        if last['action']==action and (timeDiff<checkDiff):
            last['count']+=timeDiff
            if last['count']>1:
                pressed=2
                last['count']=0.01
            else: pressed=1
        else:
            last['action']=action
            last['count']=0

        last['time']=time.time()
        return pressed


    def _left(self, currentFocus):
        '''
        pressed=self._pressed('left')
        if pressed==1: return
        elif pressed==2: control=None
        else: control = self._findControlOnLeft(currentFocus)
        '''
        control = self._findControlOnLeft(currentFocus)
        
        if control is not None:
            self.setFocus(control)
        elif control is None:
            self.viewStartDate -= datetime.timedelta(hours=2)
            self.focusPoint.x = self.epgView.right
            self.onRedrawEPG(self.channelIdx, self.viewStartDate, focusFunction=self._findControlOnLeft)

    def _right(self, currentFocus):
        '''
        pressed=self._pressed('right')
        if pressed==1: return
        elif pressed==2: control=None
        else: control = self._findControlOnRight(currentFocus)
        '''
        control = self._findControlOnRight(currentFocus)

        if control is not None:
            self.setFocus(control)
        elif control is None:
            self.viewStartDate += datetime.timedelta(hours=2)
            self.focusPoint.x = self.epgView.left
            self.onRedrawEPG(self.channelIdx, self.viewStartDate, focusFunction=self._findControlOnRight)
        

    def _up(self, currentFocus):
        '''
        pressed=self._pressed('up')
        if pressed==1: return
        elif pressed==2:
            self._nextDay()
            return
        '''
        
        currentFocus.x = self.focusPoint.x
        control = self._findControlAbove(currentFocus)
        if control is not None:
            self.setFocus(control)
        elif control is None:
            self.focusPoint.y = self.epgView.top
            self.onRedrawEPG(self.channelIdx - 1, self.viewStartDate,
                             focusFunction=self._findControlBelow)

    def _down(self, currentFocus):
        '''
        pressed=self._pressed('down')
        if pressed==1: return
        elif pressed==2:
            self._previousDay()
            return
        ''' 
        currentFocus.x = self.focusPoint.x
        control = self._findControlBelow(currentFocus)
        if control is not None:
            self.setFocus(control)
        elif control is None:
            self.focusPoint.y = self.epgView.bottom
            self.onRedrawEPG(self.channelIdx + 1, self.viewStartDate,
                             focusFunction=self._findControlAbove)

    def _nextDay(self):
        date = (self.viewStartDate + datetime.timedelta(days=1))
        datehigh = (datetime.datetime.today() + datetime.timedelta(days=14))
        if date > datehigh:
            d = datetime.datetime.strftime(datetime.datetime.date(date), '%d.%m.%Y')
            xbmcgui.Dialog().notification(str(d), localString(31303), time=3000) 
            return
        self.viewStartDate = date
        self.onRedrawEPG(self.channelIdx, self.viewStartDate)

    def _previousDay(self):
        date = (self.viewStartDate - datetime.timedelta(days=1))
        datelow = (datetime.datetime.today() - datetime.timedelta(days=7))
        if date < datelow:
            d = datetime.datetime.strftime(datetime.datetime.date(date), '%d.%m.%Y')
            xbmcgui.Dialog().notification(str(d), localString(31304), time=3000) 
            return
        self.viewStartDate = date
        self.onRedrawEPG(self.channelIdx, self.viewStartDate)

    def _moveUp(self, count=1, scrollEvent=False):
        if scrollEvent:
            self.onRedrawEPG(self.channelIdx - count, self.viewStartDate)
        else:
            self.focusPoint.y = self.epgView.bottom
            self.onRedrawEPG(self.channelIdx - count, self.viewStartDate, focusFunction=self._findControlAbove)

    def _moveDown(self, count=1, scrollEvent=False):
        if scrollEvent:
            self.onRedrawEPG(self.channelIdx + count, self.viewStartDate)
        else:
            self.focusPoint.y = self.epgView.top
            self.onRedrawEPG(self.channelIdx + count, self.viewStartDate, focusFunction=self._findControlBelow)

    def loadChannels(self, favourites):
        self.favourites = favourites

    def onRedrawEPG(self, channelStart, startTime, focusFunction=None):
        
        import time, locale
        #print 'HeuteTIME  ' + str(time.strftime ('%B-%d/%A/%Y'))
        if self.redrawingEPG or self.isClosing:
            #debug('onRedrawEPG - already redrawing')
            return  # ignore redraw request while redrawing
        #debug('onRedrawEPG')

        self.redrawingEPG = True
        self._showControl(self.C_MAIN_EPG)
        self.updateTimebar(scheduleTimer=False)

        # remove existing controls
        self._clearEpg()

        channels = self.db.getChannelList(self.favourites)
       

        if channelStart < 0:
            channelStart = len(channels) - 9 # (int((float(len(channels))/8 - len(channels)/8)*8))
            self.focusPoint.y = 434
            focusFunktion = self._findControlAbove
        elif channelStart > len(channels) - 9:
            channelStart = 0
            focusFunction = None

        self.channelIdx = channelStart

        
        ret=self.db.updateProgram(startTime)
        #channels that are visible 
        channels={'index':[]}
        for nr in range(0, CHANNELS_PER_PAGE):
            id=allChannels['index'][channelStart+nr]
            channels[id]= allChannels[id]
            channels['index'].append(id)
        '''

        '''
        programs = self.db.getPrograms(channels, False, startTime, startTime + datetime.timedelta(hours=2))
        if programs is None:
            self.onEPGLoadError()
            return
#        channelsWithoutPrograms = list(channels)
        '''
        xbmc.executebuiltin("ActivateWindow(busydialog)")
        ret=self.db.updateProgram(startTime)
        xbmc.executebuiltin("Dialog.Close(busydialog)")
                
        # date and time row
        #Date = str(self.viewStartDate.strftime ('%A %d. %B %Y'))
        self.setControlLabel(self.C_MAIN_DATE, self.formatDate(self.viewStartDate))
        #self.setControlLabel(self.C_MAIN_DATE, Date)
        time=startTime
        for col in range(1, 5):
            self.setControlLabel(4000 + col, self.formatTime(time))
            time += HALF_HOUR

        # set channel logo or text
        for idx in range(0, CHANNELS_PER_PAGE):
            if (channelStart+idx) >= len(channels['index']):
                self.setControlImage(4110 + idx, ' ')
                self.setControlLabel(4010 + idx, ' ')
            else:
                channel = channels[channels['index'][channelStart+idx]]
                #print 'TEST  ' + str(channel['id'])
                self.setControlLabel(4010 + idx, channel['title'])
                if channel['logo'] is not None: self.setControlImage(4110 + idx, channel['logo'])
                else: self.setControlImage(4110 + idx, ' ')
                    
                programs = self.db.getPrograms( {'index':[channel['id']]}, False, startTime, startTime + datetime.timedelta(hours=2))
                for program in programs:
                    # add channel index and logo for control-handling
                    program['channel_index'] = idx
                    program['channel_logo'] = channel['logo']
        
                    startDelta = program['start_date'] - self.viewStartDate
                    stopDelta = program['end_date'] - self.viewStartDate
        
                    cellStart = self._secondsToXposition(startDelta.seconds)
                    if startDelta.days < 0: cellStart = self.epgView.left
                    cellWidth = self._secondsToXposition(stopDelta.seconds) - cellStart
                    if cellStart + cellWidth > self.epgView.right: cellWidth = self.epgView.right - cellStart
        
                    if cellWidth > 1:
                        noFocusTexture = 'tvguide-program-grey.png'
                        focusTexture = 'tvguide-program-grey-focus.png'
        
                        if cellWidth < 25: title = ''  # Text will overflow outside the button if it is too narrow
                        else: title = program['title']
                    
                        control = xbmcgui.ControlButton(
                            int(cellStart),
                            int(self.epgView.top + self.epgView.cellHeight * idx),
                            int(cellWidth - 2),
                            int(self.epgView.cellHeight - 2),
                            title,
                            noFocusTexture=noFocusTexture,
                            focusTexture=focusTexture
                        )
        
                        self.controlAndProgramList.append(ControlAndProgram(control, program))

#        for channel in channelsWithoutPrograms:
#            idx = channels.index(channel)
#
#            control = xbmcgui.ControlButton(
#                self.epgView.left,
#                self.epgView.top + self.epgView.cellHeight * idx,
#                (self.epgView.right - self.epgView.left) - 2,
#                self.epgView.cellHeight - 2,
#                strings(NO_PROGRAM_AVAILABLE),
#                noFocusTexture='tvguide-program-grey.png',
#                focusTexture='tvguide-program-grey-focus.png'
#            )
#
#            program = src.Program(channel, strings(NO_PROGRAM_AVAILABLE), None, None, None)
#            self.controlAndProgramList.append(ControlAndProgram(control, program))

        # add program controls
        if focusFunction is None:
            focusFunction = self._findControlAt
        focusControl = focusFunction(self.focusPoint)
        controls = [elem.control for elem in self.controlAndProgramList]
        self.addControls(controls)
        if focusControl is not None:
            debug('onRedrawEPG - setFocus %d' % focusControl.getId())
            self.setFocus(focusControl)

        self.ignoreMissingControlIds.extend([elem.control.getId() for elem in self.controlAndProgramList])

        if focusControl is None and len(self.controlAndProgramList) > 0:
            self.setFocus(self.controlAndProgramList[0].control)

        self.redrawingEPG = False

    def _clearEpg(self):
        controls = [elem.control for elem in self.controlAndProgramList]
        try:
            self.removeControls(controls)
        except RuntimeError:
            for elem in self.controlAndProgramList:
                try:
                    self.removeControl(elem.control)
                except RuntimeError:
                    pass  # happens if we try to remove a control that doesn't exist
        del self.controlAndProgramList[:]

    def onEPGLoadError(self):
        self.redrawingEPG = False
        xbmcgui.Dialog().ok(strings(LOAD_ERROR_TITLE), strings(LOAD_ERROR_LINE1), strings(LOAD_ERROR_LINE2))
        self.close()


    def _secondsToXposition(self, seconds):
        return self.epgView.left + (seconds * self.epgView.width // 7200)

    def _findControlOnRight(self, point):
        distanceToNearest = 10000
        nearestControl = None

        for elem in self.controlAndProgramList:
            control = elem.control
            (left, top) = control.getPosition()
            x = left + (control.getWidth() // 2)
            y = top + (control.getHeight() // 2)
            if left == point.x: continue
            if point.x < x and point.y == y:
                distance = abs(point.x - x)
                if distance < distanceToNearest:
                    distanceToNearest = distance
                    nearestControl = control
        return nearestControl

    def _findControlOnLeft(self, point):
        distanceToNearest = 10000
        nearestControl = None

        for elem in self.controlAndProgramList:
            control = elem.control
            (left, top) = control.getPosition()
            debug(control.getWidth() // 2)
            x = left + (control.getWidth() // 2)
            y = top + (control.getHeight() // 2)
            if point.x > x and point.y == y:
                distance = abs(point.x - x)
                if distance < distanceToNearest:
                    distanceToNearest = distance
                    nearestControl = control
        return nearestControl

    def _findControlBelow(self, point):
        nearestControl = None

        for elem in self.controlAndProgramList:
            control = elem.control
            (leftEdge, top) = control.getPosition()
            y = top + (control.getHeight() // 2)

            if point.y < y:
                rightEdge = leftEdge + control.getWidth()
                if leftEdge <= point.x < rightEdge and (nearestControl is None or nearestControl.getPosition()[1] > top):
                    nearestControl = control

        return nearestControl

    def _findControlAbove(self, point):
        nearestControl = None
        for elem in self.controlAndProgramList:
            control = elem.control
            (leftEdge, top) = control.getPosition()
            y = top + (control.getHeight() // 2)

            if point.y > y:
                rightEdge = leftEdge + control.getWidth()
                if leftEdge <= point.x < rightEdge and (nearestControl is None or nearestControl.getPosition()[1] < top):
                    nearestControl = control

        return nearestControl

    def _findControlAt(self, point):
        for elem in self.controlAndProgramList:
            control = elem.control
            (left, top) = control.getPosition()
            bottom = top + control.getHeight()
            right = left + control.getWidth()

            if left <= point.x <= right and top <= point.y <= bottom:
                return control

        return None

    def _getProgramFromControl(self, control):
        debug('old %d' % control.getId())
        for elem in self.controlAndProgramList:
            
            if elem.control.getId() == control.getId():
                return elem.program
        return None

    def _hideControl(self, *controlIds):
        """
        Visibility is inverted in skin
        """
        for controlId in controlIds:
            control = self.getControl(controlId)
            if control:
                control.setVisible(True)

    def _showControl(self, *controlIds):
        """
        Visibility is inverted in skin
        """
        for controlId in controlIds:
            control = self.getControl(controlId)
            if control:
                control.setVisible(False)

    def formatTime(self, timestamp):
        if timestamp:
            format = xbmc.getRegion('time').replace(':%S', '').replace('%H%H', '%H')
            return timestamp.strftime(format)
        else:
            return ''


    def formatDate(self, timestamp):
        if timestamp:
            format = xbmc.getRegion('datelong')
            date = timestamp.strftime(format)
            date = date.replace('Monday', local(11))
            date = date.replace('Tuesday', local(12))
            date = date.replace('Wednesday', local(13))
            date = date.replace('Thursday', local(14))
            date = date.replace('Friday', local(15))
            date = date.replace('Saturday', local(16))
            date = date.replace('Sunday', local(17))
            date = date.replace('January', local(21))
            date = date.replace('February', local(22))
            date = date.replace('March', local(23))
            date = date.replace('April', local(24))
            date = date.replace('May', local(25))
            date = date.replace('June', local(26))
            date = date.replace('July', local(27))
            date = date.replace('August', local(28))
            date = date.replace('September', local(29))
            date = date.replace('October', local(30))
            date = date.replace('November', local(31))
            date = date.replace('December', local(32))
            return date
        else:
            return ''

    def setControlImage(self, controlId, image):
        control = self.getControl(controlId)
        if control:
            control.setImage(image, False)

    def setControlLabel(self, controlId, label):
        control = self.getControl(controlId)
        if control and label:
            control.setLabel(label)

    def setControlText(self, controlId, text):
        control = self.getControl(controlId)
        if control:
            control.setText(text)

    def updateTimebar(self, scheduleTimer=True):
        try:
            # move timebar to current time
            timeDelta = datetime.datetime.today() - self.viewStartDate
            control = self.getControl(self.C_MAIN_TIMEBAR)
            if control:
                (x, y) = control.getPosition()
                try:
                    # Sometimes raises:
                    # exceptions.RuntimeError: Unknown exception thrown from the call "setVisible"
                    control.setVisible(timeDelta.days == 0)
                except:
                    pass
                control.setPosition(self._secondsToXposition(timeDelta.seconds), y)

            if scheduleTimer and not xbmc.abortRequested and not self.isClosing:
                threading.Timer(1, self.updateTimebar).start()
        except Exception:
            pass

    def getDate(self):
        
        format = xbmc.getRegion('dateshort')
        dialog = xbmcgui.Dialog()
        today = datetime.date.today()
        date = dialog.numeric(1, localString(31924)).replace(' ','0').replace('/','.')
        if date == today.strftime('%d.%m.%Y'): return
        datelow = (datetime.date.today() - datetime.timedelta(days=7))
        datehigh = (datetime.date.today() + datetime.timedelta(days=14))

        debug('date EPG '+ str(date))
        
        if time.strptime(date, '%d.%m.%Y') < time.strptime(str(datelow), '%Y-%m-%d'):
            xbmcgui.Dialog().notification(str(date), localString(31304), time=3000) 
            return
        if time.strptime(date, '%d.%m.%Y') > time.strptime(str(datehigh), '%Y-%m-%d'):
            xbmcgui.Dialog().notification(str(date), localString(31303), time=3000) 
            return
        date = time.strptime(date, '%d.%m.%Y')
        current = time.strptime(str(self.viewStartDate.strftime ('%Y-%m-%d')), '%Y-%m-%d')
        timedelta = datetime.timedelta(seconds=time.mktime(date) - time.mktime(current))
        if timedelta.seconds == 82800: 
            timedelta += datetime.timedelta(hours=1)
        debug('Timedelta '+str(timedelta))
        if date > current:
            self.viewStartDate += datetime.timedelta(days=int(str(timedelta)[:2]))
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)
        elif date < current:
            delta = str(timedelta).replace('-','')[:2]
            self.viewStartDate -= datetime.timedelta(days=int(delta))
            self.onRedrawEPG(self.channelIdx, self.viewStartDate)