from Components.MultiContent import MultiContentEntryText
from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
from Components.VideoWindow import VideoWindow
+from Components.Label import Label
from Screens.InfoBarGenerics import InfoBarSeek, InfoBarCueSheetSupport
from Components.GUIComponent import GUIComponent
-from enigma import eListboxPythonMultiContent, eListbox, gFont, iPlayableService, RT_HALIGN_RIGHT
+from enigma import eListboxPythonMultiContent, eListbox, getDesktop, gFont, iPlayableService, RT_HALIGN_RIGHT
from Screens.FixedMenu import FixedMenu
from Screens.HelpMenu import HelpableScreen
from ServiceReference import ServiceReference
+from Components.Sources.List import List
+
import bisect
def CutListEntry(where, what):
- res = [ (where, what) ]
w = where / 90
ms = w % 1000
s = (w / 1000) % 60
h = w / 3600000
if what == 0:
type = "IN"
+ type_col = 0x004000
elif what == 1:
type = "OUT"
+ type_col = 0x400000
elif what == 2:
type = "MARK"
+ type_col = 0x000040
elif what == 3:
type = "LAST"
- res.append(MultiContentEntryText(size=(400, 20), text = "%dh:%02dm:%02ds:%03d" % (h, m, s, ms)))
- res.append(MultiContentEntryText(pos=(400,0), size=(130, 20), text = type, flags = RT_HALIGN_RIGHT))
-
- return res
+ type_col = 0x000000
+ return ((where, what), "%dh:%02dm:%02ds:%03d" % (h, m, s, ms), type, type_col)
class CutListContextMenu(FixedMenu):
RET_STARTCUT = 0
else:
menu.append((_("remove this mark"), self.removeMark))
- menu.append((("grab this frame as bitmap"), self.grabFrame))
+ menu.append((_("grab this frame as bitmap"), self.grabFrame))
FixedMenu.__init__(self, session, _("Cut"), menu)
self.skinName = "Menu"
def grabFrame(self):
self.close(self.RET_GRABFRAME)
-class CutList(GUIComponent):
- def __init__(self, list):
- GUIComponent.__init__(self)
- self.l = eListboxPythonMultiContent()
- self.setList(list)
- self.l.setFont(0, gFont("Regular", 20))
- self.onSelectionChanged = [ ]
-
- def getCurrent(self):
- return self.l.getCurrentSelection()
-
- def getCurrentIndex(self):
- return self.l.getCurrentSelectionIndex()
-
- GUI_WIDGET = eListbox
-
- def postWidgetCreate(self, instance):
- instance.setContent(self.l)
- instance.setItemHeight(30)
- instance.selectionChanged.get().append(self.selectionChanged)
-
- def preWidgetRemove(self, instance):
- instance.setContent(None)
- instance.selectionChanged.get().remove(self.selectionChanged)
-
- def selectionChanged(self):
- for x in self.onSelectionChanged:
- x()
-
- def invalidateEntry(self, index):
- self.l.invalidateEntry(index)
-
- def setIndex(self, index, data):
- self.list[index] = data
- self.invalidateEntry(index)
-
- def setList(self, list):
- self.list = list
- self.l.setList(self.list)
-
- def setSelection(self, index):
- if self.instance is not None:
- self.instance.moveSelectionTo(index)
-
class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, HelpableScreen):
skin = """
<screen position="0,0" size="720,576" title="Cutlist editor" flags="wfNoBorder">
<widget source="session.CurrentService" render="Label" position="135,405" size="450,50" font="Regular;22" halign="center" valign="center">
<convert type="ServiceName">Name</convert>
</widget>
- <widget source="session.CurrentService" render="Label" position="50,450" zPosition="1" size="620,25" font="Regular;20" halign="center" valign="center">
+ <widget source="session.CurrentService" render="Label" position="320,450" zPosition="1" size="420,25" font="Regular;20" halign="left" valign="center">
<convert type="ServicePosition">Position,Detailed</convert>
</widget>
- <eLabel position="62,98" size="179,274" backgroundColor="#505555" />
- <eLabel position="64,100" size="175,270" backgroundColor="#000000" />
- <widget name="Cutlist" position="64,100" zPosition="1" size="175,270" scrollbarMode="showOnDemand" transparent="1" />
+ <widget name="SeekState" position="210,450" zPosition="1" size="100,25" halign="right" font="Regular;20" valign="center" />
+ <eLabel position="48,98" size="204,274" backgroundColor="#505555" />
+ <eLabel position="50,100" size="200,270" backgroundColor="#000000" />
+ <widget source="cutlist" position="50,100" zPosition="1" size="200,270" scrollbarMode="showOnDemand" transparent="1" render="Listbox" >
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(size=(125, 20), text = 1, backcolor = MultiContentTemplateColor(3)),
+ MultiContentEntryText(pos=(125,0), size=(50, 20), text = 2, flags = RT_HALIGN_RIGHT, backcolor = MultiContentTemplateColor(3))
+ ],
+ "fonts": [gFont("Regular", 18)],
+ "itemHeight": 20
+ }
+ </convert>
+ </widget>
<widget name="Timeline" position="50,485" size="615,20" backgroundColor="#505555" pointer="skin_default/position_arrow.png:3,5" foregroundColor="black" />
<ePixmap pixmap="skin_default/icons/mp_buttons.png" position="305,515" size="109,13" alphatest="on" />
</screen>"""
self.downloadCuesheet()
self["Timeline"] = ServicePositionGauge(self.session.nav)
- self["Cutlist"] = CutList(self.getCutlist())
- self["Cutlist"].onSelectionChanged.append(self.selectionChanged)
+ self["cutlist"] = List(self.getCutlist())
+ self["cutlist"].onSelectionChanged.append(self.selectionChanged)
+ self["SeekState"] = Label()
+ self.onPlayStateChanged.append(self.updateStateLabel)
+ self.updateStateLabel(self.seekstate)
- self["Video"] = VideoWindow(decoder = 0)
+ desktopSize = getDesktop(0).size()
+ self["Video"] = VideoWindow(decoder = 0, fb_width=desktopSize.width(), fb_height=desktopSize.height())
self["actions"] = HelpableActionMap(self, "CutListEditorActions",
{
})
# to track new entries we save the last version of the cutlist
- self.last_cuts = [ ]
+ self.last_cuts = self.getCutlist()
self.cut_start = None
+ self.inhibit_seek = False
self.onClose.append(self.__onClose)
def __onClose(self):
- self.session.nav.playService(self.old_service)
+ self.session.nav.playService(self.old_service, forceRestart=True)
+
+ def updateStateLabel(self, state):
+ self["SeekState"].setText(state[3].strip())
def showTutorial(self):
if not self.tutorial_seen:
def setType(self, index, type):
if len(self.cut_list):
self.cut_list[index] = (self.cut_list[index][0], type)
- self["Cutlist"].setIndex(index, CutListEntry(*self.cut_list[index]))
+ self["cutlist"].modifyEntry(index, CutListEntry(*self.cut_list[index]))
def setIn(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 0)
self.uploadCuesheet()
def setOut(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 1)
self.uploadCuesheet()
def setMark(self):
- m = self["Cutlist"].getCurrentIndex()
+ m = self["cutlist"].getIndex()
self.setType(m, 2)
self.uploadCuesheet()
self.toggleMark(onlyadd=True, tolerance=90000) # do not allow two marks in <1s
def __removeMark(self):
- m = self["Cutlist"].getCurrent()
+ m = self["cutlist"].getCurrent()
m = m and m[0]
if m is not None:
self.removeMark(m)
return r
def selectionChanged(self):
- where = self["Cutlist"].getCurrent()
- if where is None:
- print "no selection"
- return
- pts = where[0][0]
- seek = self.getSeek()
- if seek is None:
- print "no seek"
- return
- seek.seekTo(pts)
+ if not self.inhibit_seek:
+ where = self["cutlist"].getCurrent()
+ if where is None:
+ print "no selection"
+ return
+ pts = where[0][0]
+ seek = self.getSeek()
+ if seek is None:
+ print "no seek"
+ return
+ seek.seekTo(pts)
def refillList(self):
print "cue sheet changed, refilling"
self.downloadCuesheet()
- # get the first changed entry, and select it
+ # get the first changed entry, counted from the end, and select it
new_list = self.getCutlist()
- self["Cutlist"].setList(new_list)
+ self["cutlist"].list = new_list
- for i in range(min(len(new_list), len(self.last_cuts))):
- if new_list[i] != self.last_cuts[i]:
- self["Cutlist"].setSelection(i)
+ l1 = len(new_list)
+ l2 = len(self.last_cuts)
+ for i in range(min(l1, l2)):
+ if new_list[l1-i-1] != self.last_cuts[l2-i-1]:
+ self["cutlist"].setIndex(l1-i-1)
break
self.last_cuts = new_list
def getStateForPosition(self, pos):
- state = 0 # in
-
- # when first point is "in", the beginning is "out"
- if len(self.cut_list) and self.cut_list[0][1] == 0:
- state = 1
-
+ state = -1
for (where, what) in self.cut_list:
- if where < pos:
- if what == 0: # in
- state = 0
- elif what == 1: # out
+ if what in [0, 1]:
+ if where < pos:
+ state = what
+ elif where == pos:
state = 1
+ elif state == -1:
+ state = 1 - what
+ if state == -1:
+ state = 0
return state
def showMenu(self):
elif result == CutListContextMenu.RET_ENDCUT:
# remove in/out marks between the new cut
for (where, what) in self.cut_list[:]:
- if self.cut_start <= where <= self.context_position and what in [0,1]:
+ if self.cut_start <= where <= self.context_position and what in (0,1):
self.cut_list.remove((where, what))
bisect.insort(self.cut_list, (self.cut_start, 1))
in_after = None
for (where, what) in self.cut_list:
- if what == 1 and where < self.context_position: # out
+ if what == 1 and where <= self.context_position: # out
out_before = (where, what)
elif what == 0 and where < self.context_position: # in, before out
out_before = None
- elif what == 0 and where > self.context_position and in_after is None:
+ elif what == 0 and where >= self.context_position and in_after is None:
in_after = (where, what)
if out_before is not None:
if in_after is not None:
self.cut_list.remove(in_after)
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_MARK:
self.__addMark()
elif result == CutListContextMenu.RET_DELETEMARK:
self.cut_list.remove(self.context_nearest_mark)
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_REMOVEBEFORE:
# remove in/out marks before current position
for (where, what) in self.cut_list[:]:
- if where <= self.context_position and what in [0,1]:
+ if where <= self.context_position and what in (0,1):
self.cut_list.remove((where, what))
# add 'in' point
bisect.insort(self.cut_list, (self.context_position, 0))
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_REMOVEAFTER:
# remove in/out marks after current position
for (where, what) in self.cut_list[:]:
- if where >= self.context_position and what in [0,1]:
+ if where >= self.context_position and what in (0,1):
self.cut_list.remove((where, what))
# add 'out' point
bisect.insort(self.cut_list, (self.context_position, 1))
+ self.inhibit_seek = True
self.uploadCuesheet()
+ self.inhibit_seek = False
elif result == CutListContextMenu.RET_GRABFRAME:
self.grabFrame()