def __init__(self, *args, **kwargs): self.epgdata = EPGData() self.epgdata.epgwindow = self self.focusRow = 0 self.focusIndex = 0 self.shownTime = 0 self.centerChannel = 0 self.rowCount = 6 self.channelButtons = [None] * self.rowCount self.actionSemaphore = threading.BoundedSemaphore() self.lastActionTime = time.time() self.textcolor = "FFFFFFFF" self.focusedcolor = "FF7d7d7d" self.clockMode = "0" self.channelLabel = [] #adding channel numbers self.inputChannel = -1 # Decide whether to use the current skin or the default skin. If the current skin has the proper # image, then it should work. if os.path.exists(xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', xbmc.getSkinDir(), 'media'))): self.mediaPath = xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', xbmc.getSkinDir(), 'media')) + '/' elif os.path.exists(xbmc.translatePath('special://skin/media/' + TIME_BAR)): self.mediaPath = xbmc.translatePath('special://skin/media/') elif xbmc.skinHasImage(TIME_BAR): self.mediaPath = '' else: self.mediaPath = xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', 'default', 'media')) + '/' self.log('Media Path is ' + self.mediaPath) # Use the given focus and non-focus textures if they exist. Otherwise use the defaults. if os.path.exists(self.mediaPath + BUTTON_FOCUS): self.textureButtonFocus = self.mediaPath + BUTTON_FOCUS else: self.textureButtonFocus = 'button-focus.png' if os.path.exists(self.mediaPath + BUTTON_NO_FOCUS): self.textureButtonNoFocus = self.mediaPath + BUTTON_NO_FOCUS else: self.textureButtonNoFocus = 'button-nofocus.png' for i in range(self.rowCount): self.channelButtons[i] = []
class EPGWindow(xbmcgui.WindowXMLDialog): def __init__(self, *args, **kwargs): self.epgdata = EPGData() self.epgdata.epgwindow = self self.focusRow = 0 self.focusIndex = 0 self.shownTime = 0 self.centerChannel = 0 self.rowCount = 6 self.channelButtons = [None] * self.rowCount self.actionSemaphore = threading.BoundedSemaphore() self.lastActionTime = time.time() self.textcolor = "FFFFFFFF" self.focusedcolor = "FF7d7d7d" self.clockMode = "0" self.channelLabel = [] #adding channel numbers self.inputChannel = -1 # Decide whether to use the current skin or the default skin. If the current skin has the proper # image, then it should work. if os.path.exists(xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', xbmc.getSkinDir(), 'media'))): self.mediaPath = xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', xbmc.getSkinDir(), 'media')) + '/' elif os.path.exists(xbmc.translatePath('special://skin/media/' + TIME_BAR)): self.mediaPath = xbmc.translatePath('special://skin/media/') elif xbmc.skinHasImage(TIME_BAR): self.mediaPath = '' else: self.mediaPath = xbmc.translatePath(os.path.join(ADDON_INFO, 'resources', 'skins', 'default', 'media')) + '/' self.log('Media Path is ' + self.mediaPath) # Use the given focus and non-focus textures if they exist. Otherwise use the defaults. if os.path.exists(self.mediaPath + BUTTON_FOCUS): self.textureButtonFocus = self.mediaPath + BUTTON_FOCUS else: self.textureButtonFocus = 'button-focus.png' if os.path.exists(self.mediaPath + BUTTON_NO_FOCUS): self.textureButtonNoFocus = self.mediaPath + BUTTON_NO_FOCUS else: self.textureButtonNoFocus = 'button-nofocus.png' for i in range(self.rowCount): self.channelButtons[i] = [] def setTimeLabels(self, thetime): self.log('setTimeLabels') now = datetime.datetime.fromtimestamp(thetime) self.getControl(104).setLabel(now.strftime('%A, %b %d')) delta = datetime.timedelta(minutes=30) for i in range(3): if self.clockMode == "0": self.getControl(101 + i).setLabel(now.strftime("%I:%M%p").lower()) else: self.getControl(101 + i).setLabel(now.strftime("%H:%M")) now = now + delta self.log('setTimeLabels return') def log(self, msg, level = xbmc.LOGDEBUG): log('EPGWindow: ' + msg, level) def onInit(self): self.log('onInit') timex, timey = self.getControl(120).getPosition() timew = self.getControl(120).getWidth() timeh = self.getControl(120).getHeight() self.currentTimeBar = xbmcgui.ControlImage(timex, timey, timew, timeh, self.mediaPath + TIME_BAR) self.addControl(self.currentTimeBar) self.channelLabelTimer = threading.Timer(2.0, self.hideChannelLabel) try: textcolor = int(self.getControl(100).getLabel(), 16) focusedcolor = int(self.getControl(100).getLabel2(), 16) if textcolor > 0: self.textcolor = hex(textcolor)[2:-1] if focusedcolor > 0: self.focusedcolor = hex(focusedcolor)[2:-1] except: pass try: if self.setChannelButtons(time.time(), self.MyOverlayWindow.currentChannel) == False: self.log('Unable to add channel buttons') return curtime = time.time() self.focusIndex = -1 basex, basey = self.getControl(113).getPosition() basew = self.getControl(113).getWidth() # set the button that corresponds to the currently playing show for i in range(len(self.channelButtons[2])): left, top = self.channelButtons[2][i].getPosition() width = self.channelButtons[2][i].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) if curtime >= starttime and curtime <= endtime: self.focusIndex = i self.setFocus(self.channelButtons[2][i]) self.focusTime = int(time.time()) self.focusEndTime = endtime break # If nothing was highlighted, just select the first button if self.focusIndex == -1: self.focusIndex = 0 self.setFocus(self.channelButtons[2][0]) left, top = self.channelButtons[2][0].getPosition() width = self.channelButtons[2][0].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) self.focusTime = int(starttime + 30) self.focusEndTime = endtime self.focusRow = 2 except: self.log("Unknown EPG Initialization Exception", xbmc.LOGERROR) self.log(traceback.format_exc(), xbmc.LOGERROR) try: self.close() except: self.log("Error closing", xbmc.LOGERROR) #self.MyOverlayWindow.sleepTimeValue = 1 #self.MyOverlayWindow.startSleepTimer() return # go through all of the labels and remove them for label in self.channelLabel: self.removeControl(label) self.log("deleted label") del self.channelLabel[:] for i in range(4): self.channelLabel.append(xbmcgui.ControlImage(50 + (50 * i), 50, 50, 50, IMAGES_LOC + 'solid.png', colorDiffuse='0xAA00ff00')) self.addControl(self.channelLabel[i]) self.channelLabel[i].setVisible(False) self.log('onInit return') # Display the current channel based on self.currentChannel. # Start the timer to hide it. def showChannelLabel(self, channel): self.log('showChannelLabel ' + str(channel)) if self.channelLabelTimer.isAlive(): self.channelLabelTimer.cancel() self.channelLabelTimer = threading.Timer(2.0, self.hideChannelLabel) tmp = self.inputChannel self.hideChannelLabel() self.inputChannel = tmp curlabel = 0 if channel > 999: self.channelLabel[curlabel].setImage(IMAGES_LOC + 'label_' + str(channel // 1000) + '.png') self.channelLabel[curlabel].setVisible(True) curlabel += 1 if channel > 99: self.channelLabel[curlabel].setImage(IMAGES_LOC + 'label_' + str((channel % 1000) // 100) + '.png') self.channelLabel[curlabel].setVisible(True) curlabel += 1 if channel > 9: self.channelLabel[curlabel].setImage(IMAGES_LOC + 'label_' + str((channel % 100) // 10) + '.png') self.channelLabel[curlabel].setVisible(True) curlabel += 1 self.channelLabel[curlabel].setImage(IMAGES_LOC + 'label_' + str(channel % 10) + '.png') self.channelLabel[curlabel].setVisible(True) self.channelLabelTimer.name = "ChannelLabel" self.channelLabelTimer.start() self.log('showChannelLabel return') # Called from the timer to hide the channel label. def hideChannelLabel(self): self.log('hideChannelLabel') self.channelLabelTimer = threading.Timer(2.0, self.hideChannelLabel) for i in range(4): self.channelLabel[i].setVisible(False) self.inputChannel = -1 self.log('hideChannelLabel return') # setup all channel buttons for a given time def setChannelButtons(self, starttime, curchannel, singlerow = -1): self.log('setChannelButtons ' + str(starttime) + ', ' + str(curchannel)) xbmcgui.lock() self.removeControl(self.currentTimeBar) self.centerChannel = self.MyOverlayWindow.fixChannel(curchannel) # This is done twice to guarantee we go back 2 channels. If the previous 2 channels # aren't valid, then doing a fix on curchannel - 2 may result in going back only # a single valid channel. curchannel = self.MyOverlayWindow.fixChannel(curchannel - 1, False) curchannel = self.MyOverlayWindow.fixChannel(curchannel - 1, False) starttime = self.roundToHalfHour(int(starttime)) self.setTimeLabels(starttime) self.shownTime = starttime basex, basey = self.getControl(111).getPosition() basew = self.getControl(111).getWidth() timex, timey = self.getControl(120).getPosition() timew = self.getControl(120).getWidth() #mycode self.epgdata.loadEPGData(curchannel,self.rowCount,starttime) #endmycode for i in range(self.rowCount): if singlerow == -1 or singlerow == i: self.setButtons(starttime, curchannel, i) self.getControl(301 + i).setLabel(self.MyOverlayWindow.channels[curchannel].name) try: self.getControl(311 + i).setLabel(str(self.MyOverlayWindow.channels[curchannel].channelNumber)) except: pass try: self.getControl(321 + i).setImage(self.channelLogos + self.MyOverlayWindow.channels[curchannel].name + ".png") except: pass curchannel = self.MyOverlayWindow.fixChannel(curchannel + 1) if time.time() >= starttime and time.time() < starttime + 5400: dif = int((starttime + 5400 - time.time())) self.currentTimeBar.setPosition(int((basex + basew - 2) - (dif * (basew / 5400.0))), timey) else: if time.time() < starttime: self.currentTimeBar.setPosition(basex + 2, timey) else: self.currentTimeBar.setPosition(basex + basew - 2 - timew, timey) self.addControl(self.currentTimeBar) xbmcgui.unlock() self.log('setChannelButtons return') # round the given time down to the nearest half hour def roundToHalfHour(self, thetime): n = datetime.datetime.fromtimestamp(thetime) delta = datetime.timedelta(minutes=30) if n.minute > 29: n = n.replace(minute=30, second=0, microsecond=0) else: n = n.replace(minute=0, second=0, microsecond=0) return time.mktime(n.timetuple()) # create the buttons for the specified channel in the given row def setButtons(self, starttime, curchannel, row): self.log('setButtons ' + str(starttime) + ", " + str(curchannel) + ", " + str(row)) try: basex, basey = self.getControl(111 + row).getPosition() baseh = self.getControl(111 + row).getHeight() basew = self.getControl(111 + row).getWidth() # go through all of the buttons and remove them for button in self.channelButtons[row]: self.removeControl(button) self.log("deleted buttons") del self.channelButtons[row][:] # Find the show that was running at the given time # Use the current time and show offset to calculate it # At timedif time, channelShowPosition was playing at channelTimes # The only way this isn't true is if the current channel is curchannel since # it could have been fast forwarded or rewinded (rewound)? #playlistpos = self.MyOverlayWindow.channels[curchannel - 1].playlistPosition #videotime = self.MyOverlayWindow.channels[curchannel - 1].showTimeOffset #reftime = self.MyOverlayWindow.channels[curchannel - 1].lastAccessTime epg_data = self.epgdata.getChannelEPG(curchannel,starttime) print starttime print epg_data #if self.MyOverlayWindow.epg_data["curchannel"]: # normalize reftime to the beginning of the video #reftime -= videotime #self.log("while reftime: current is " + str(reftime)) #while reftime > starttime: #playlistpos -= 1 # No need to check bounds on the playlistpos, the duration function makes sure it is correct #reftime -= self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos) self.log("while reftime again") #while reftime + self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos) < starttime: #reftime += self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos) #playlistpos += 1 # create a button for each show that runs in the next hour and a half endtime = starttime + 5400 totaltime = 0 self.log("while reftime part 3") totalloops = 0 #begin my lines #reftime = starttime playlistpos = 0 while epg_data[playlistpos][u"end_time"]<starttime: playlistpos += 1 print playlistpos reftime = epg_data[playlistpos][u"start_time"] #end my lines while reftime < endtime and totalloops < 1000: xpos = int(basex + (totaltime * (basew / 5400.0))) #tmpdur = 1800#self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos) tmpdur = epg_data[playlistpos][u"end_time"]-epg_data[playlistpos][u"start_time"] shouldskip = False # this should only happen the first time through this loop # it shows the small portion of the show before the current one if reftime < starttime: tmpdur -= starttime - reftime reftime = starttime if tmpdur < 60 * 3: shouldskip = True # Don't show very short videos #if self.MyOverlayWindow.hideShortItems and shouldskip == False: #if self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos) < self.MyOverlayWindow.shortItemLength: #shouldskip = True #tmpdur = 0 #else: #nextlen = self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos + 1) #prevlen = self.MyOverlayWindow.channels[curchannel - 1].getItemDuration(playlistpos - 1) #if nextlen < 60: #tmpdur += nextlen / 2 #if prevlen < 60: #tmpdur += prevlen / 2 width = int((basew / 5400.0) * tmpdur) if width < 30 and shouldskip == False: width = 30 tmpdur = int(30.0 / (basew / 5400.0)) if width + xpos > basex + basew: width = basex + basew - xpos if shouldskip == False and width >= 30 and playlistpos < len(epg_data): #self.channelButtons[row].append(xbmcgui.ControlButton(xpos, basey, width, baseh, self.MyOverlayWindow.channels[curchannel - 1].getItemTitle(playlistpos), focusTexture=self.textureButtonFocus, noFocusTexture=self.textureButtonNoFocus, alignment=4, textColor=self.textcolor, focusedColor=self.focusedcolor)) self.channelButtons[row].append(xbmcgui.ControlButton(xpos, basey, width, baseh, epg_data[playlistpos][u"program_title"], focusTexture=self.textureButtonFocus, noFocusTexture=self.textureButtonNoFocus, alignment=4, textColor=self.textcolor, focusedColor=self.focusedcolor)) self.addControl(self.channelButtons[row][-1]) totaltime += tmpdur reftime += tmpdur playlistpos += 1 totalloops += 1 if totalloops >= 1000: self.log("Broken big loop, too many loops, reftime is " + str(reftime) + ", endtime is " + str(endtime)) except: self.log("Exception in setButtons", xbmc.LOGERROR) self.log(traceback.format_exc(), xbmc.LOGERROR) self.log('setButtons return') return True def onAction(self, act): self.log('onAction ' + str(act.getId())) if self.actionSemaphore.acquire(False) == False: self.log('Unable to get semaphore') return action = act.getId() try: if action == ACTION_PREVIOUS_MENU or action == ACTION_NAV_BACK: self.closeEPG() elif action == ACTION_MOVE_DOWN: self.GoDown() elif action == ACTION_MOVE_UP: self.GoUp() elif action == ACTION_MOVE_LEFT: self.GoLeft() elif action == ACTION_MOVE_RIGHT: self.GoRight() elif action == ACTION_STOP: self.closeEPG() elif action == ACTION_SELECT_ITEM: # If we're manually typing the channel, set it now if self.inputChannel > 0: channel = -1; for i in range(len(self.MyOverlayWindow.channels)): if self.MyOverlayWindow.channels[i].channelNumber >= self.inputChannel: channel = i break if channel == -1: channel = 0 self.setChannelButtons(self.shownTime, channel) self.focusRow = 2 self.setProperButton(self.focusRow) self.inputChannel = -1 else: lastaction = time.time() - self.lastActionTime if lastaction >= 2: self.selectShow() self.closeEPG() self.lastActionTime = time.time() elif action >= ACTION_NUMBER_0 and action <= ACTION_NUMBER_9: if self.inputChannel < 0: self.inputChannel = action - ACTION_NUMBER_0 else: if self.inputChannel < 1000: self.inputChannel = self.inputChannel * 10 + action - ACTION_NUMBER_0 self.showChannelLabel(self.inputChannel) except: self.log("Unknown EPG Exception", xbmc.LOGERROR) self.log(traceback.format_exc(), xbmc.LOGERROR) try: self.close() except: self.log("Error closing", xbmc.LOGERROR) #self.MyOverlayWindow.sleepTimeValue = 1 #self.MyOverlayWindow.startSleepTimer() return self.actionSemaphore.release() self.log('onAction return') def closeEPG(self): self.log('closeEPG') try: if self.channelLabelTimer.isAlive(): self.channelLabelTimer.cancel() self.channelLabelTimer.join() except: pass try: self.removeControl(self.currentTimeBar) #self.MyOverlayWindow.startSleepTimer() except: pass self.close() def GoDown(self): self.log('goDown') # change controls to display the proper junks if self.focusRow == self.rowCount - 1: # self.setChannelButtons(self.shownTime, self.MyOverlayWindow.fixChannel(self.centerChannel + 1)) self.moveButtonsUp() self.setChannelButtons(self.shownTime, self.MyOverlayWindow.fixChannel(self.centerChannel + 1), self.rowCount - 1) self.focusRow = self.rowCount - 2 self.setProperButton(self.focusRow + 1) self.log('goDown return') def GoUp(self): self.log('goUp') # same as godown # change controls to display the proper junks if self.focusRow == 0: # self.setChannelButtons(self.shownTime, self.MyOverlayWindow.fixChannel(self.centerChannel - 1, False)) self.moveButtonsDown() self.setChannelButtons(self.shownTime, self.MyOverlayWindow.fixChannel(self.centerChannel - 1, False), 0) self.focusRow = 1 self.setProperButton(self.focusRow - 1) self.log('goUp return') def GoLeft(self): self.log('goLeft') basex, basey = self.getControl(111 + self.focusRow).getPosition() basew = self.getControl(111 + self.focusRow).getWidth() # change controls to display the proper junks if self.focusIndex == 0: left, top = self.channelButtons[self.focusRow][self.focusIndex].getPosition() width = self.channelButtons[self.focusRow][self.focusIndex].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) self.setChannelButtons(self.shownTime - 1800, self.centerChannel) curbutidx = self.findButtonAtTime(self.focusRow, starttime + 30) if (curbutidx - 1) >= 0: self.focusIndex = curbutidx - 1 else: self.focusIndex = 0 else: self.focusIndex -= 1 left, top = self.channelButtons[self.focusRow][self.focusIndex].getPosition() width = self.channelButtons[self.focusRow][self.focusIndex].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) self.setFocus(self.channelButtons[self.focusRow][self.focusIndex]) #self.setShowInfo() self.focusEndTime = endtime self.focusTime = starttime + 30 self.log('goLeft return') def GoRight(self): self.log('goRight') basex, basey = self.getControl(111 + self.focusRow).getPosition() basew = self.getControl(111 + self.focusRow).getWidth() # change controls to display the proper junks if self.focusIndex == len(self.channelButtons[self.focusRow]) - 1: left, top = self.channelButtons[self.focusRow][self.focusIndex].getPosition() width = self.channelButtons[self.focusRow][self.focusIndex].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) self.setChannelButtons(self.shownTime + 1800, self.centerChannel) curbutidx = self.findButtonAtTime(self.focusRow, starttime + 30) if (curbutidx + 1) < len(self.channelButtons[self.focusRow]): self.focusIndex = curbutidx + 1 else: self.focusIndex = len(self.channelButtons[self.focusRow]) - 1 else: self.focusIndex += 1 left, top = self.channelButtons[self.focusRow][self.focusIndex].getPosition() width = self.channelButtons[self.focusRow][self.focusIndex].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) self.setFocus(self.channelButtons[self.focusRow][self.focusIndex]) #self.setShowInfo() self.focusEndTime = endtime self.focusTime = starttime + 30 self.log('goRight return') def moveButtonsUp(self): self.log('moveButtonsUp') xbmcgui.lock() for button in self.channelButtons[0]: self.removeControl(button) del self.channelButtons[0][:] for i in range(self.rowCount - 1): basex, basey = self.getControl(111 + i).getPosition() for button in self.channelButtons[i + 1]: x, y = button.getPosition() button.setPosition(x, basey) self.channelButtons[i] = self.channelButtons[i + 1][:] del self.channelButtons[i + 1][:] xbmcgui.unlock() def moveButtonsDown(self): self.log('moveButtonsDown') xbmcgui.lock() for button in self.channelButtons[self.rowCount - 1]: self.removeControl(button) del self.channelButtons[self.rowCount - 1][:] for i in range(self.rowCount - 1): basex, basey = self.getControl(111 + (self.rowCount - 1 - i)).getPosition() for button in self.channelButtons[self.rowCount - i - 2]: x, y = button.getPosition() button.setPosition(x, basey) self.channelButtons[self.rowCount - 1 - i] = self.channelButtons[self.rowCount - 2 - i][:] del self.channelButtons[self.rowCount - 2 - i][:] xbmcgui.unlock() def findButtonAtTime(self, row, selectedtime): self.log('findButtonAtTime ' + str(row)) basex, basey = self.getControl(111 + row).getPosition() baseh = self.getControl(111 + row).getHeight() basew = self.getControl(111 + row).getWidth() for i in range(len(self.channelButtons[row])): left, top = self.channelButtons[row][i].getPosition() width = self.channelButtons[row][i].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) if selectedtime >= starttime and selectedtime <= endtime: return i return -1 # based on the current focus row and index, find the appropriate button in # the new row to set focus to def setProperButton(self, newrow, resetfocustime = False): self.log('setProperButton ' + str(newrow)) self.focusRow = newrow basex, basey = self.getControl(111 + newrow).getPosition() baseh = self.getControl(111 + newrow).getHeight() basew = self.getControl(111 + newrow).getWidth() for i in range(len(self.channelButtons[newrow])): left, top = self.channelButtons[newrow][i].getPosition() width = self.channelButtons[newrow][i].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) if self.focusTime >= starttime and self.focusTime <= endtime: self.focusIndex = i self.setFocus(self.channelButtons[newrow][i]) #self.setShowInfo() self.focusEndTime = endtime if resetfocustime: self.focusTime = starttime + 30 self.log('setProperButton found button return') return self.focusIndex = 0 self.setFocus(self.channelButtons[newrow][0]) left, top = self.channelButtons[newrow][0].getPosition() width = self.channelButtons[newrow][0].getWidth() left = left - basex starttime = self.shownTime + (left / (basew / 5400.0)) endtime = starttime + (width / (basew / 5400.0)) self.focusEndTime = endtime if resetfocustime: self.focusTime = starttime + 30 #self.setShowInfo() self.log('setProperButton return') # using the currently selected button, play the proper shows def selectShow(self): self.log('selectShow') chnoffset = self.focusRow - 2 newchan = self.centerChannel while chnoffset != 0: if chnoffset > 0: newchan = self.MyOverlayWindow.fixChannel(newchan + 1, True) chnoffset -= 1 else: newchan = self.MyOverlayWindow.fixChannel(newchan - 1, False) chnoffset += 1 self.MyOverlayWindow.newChannel = newchan self.log('selectShow return')