X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/4b6920178646027cbc442e4e45d8a4e707f225d9..beee99ffe9fc10811f2d84b531081ef81d4b6518:/lib/python/Plugins/Extensions/CutListEditor/plugin.py?ds=sidebyside
diff --git a/lib/python/Plugins/Extensions/CutListEditor/plugin.py b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
index 0d2454e4..efe9f761 100644
--- a/lib/python/Plugins/Extensions/CutListEditor/plugin.py
+++ b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
@@ -7,15 +7,18 @@ from Components.ActionMap import HelpableActionMap
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 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
@@ -23,16 +26,17 @@ def CutListEntry(where, what):
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
@@ -42,6 +46,7 @@ class CutListContextMenu(FixedMenu):
RET_DELETEMARK = 4
RET_REMOVEBEFORE = 5
RET_REMOVEAFTER = 6
+ RET_GRABFRAME = 7
SHOW_STARTCUT = 0
SHOW_ENDCUT = 1
@@ -75,6 +80,7 @@ class CutListContextMenu(FixedMenu):
else:
menu.append((_("remove this mark"), self.removeMark))
+ menu.append((_("grab this frame as bitmap"), self.grabFrame))
FixedMenu.__init__(self, session, _("Cut"), menu)
self.skinName = "Menu"
@@ -99,50 +105,8 @@ class CutListContextMenu(FixedMenu):
def removeAfter(self):
self.close(self.RET_REMOVEAFTER)
-
-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)
+ def grabFrame(self):
+ self.close(self.RET_GRABFRAME)
class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, HelpableScreen):
skin = """
@@ -156,12 +120,23 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
Name
-
+
Position,Detailed
-
-
-
+
+
+
+
+
+ {"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
+ }
+
+
"""
@@ -186,8 +161,11 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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)
@@ -211,13 +189,17 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
})
# 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)
+ def updateStateLabel(self, state):
+ self["SeekState"].setText(state[3].strip())
+
def showTutorial(self):
if not self.tutorial_seen:
self.tutorial_seen = True
@@ -229,20 +211,20 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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()
@@ -250,7 +232,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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)
@@ -265,44 +247,46 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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):
@@ -344,7 +328,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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))
@@ -356,11 +340,11 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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:
@@ -368,28 +352,38 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
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()
# we modify the "play" behavior a bit:
# if we press pause while being in slowmotion, we will pause (and not play)
@@ -399,6 +393,14 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
else:
self.pauseService()
+ def grabFrame(self):
+ path = self.session.nav.getCurrentlyPlayingServiceReference().getPath()
+ from Components.Console import Console
+ grabConsole = Console()
+ cmd = 'grab -vblpr%d "%s"' % (180, path.rsplit('.',1)[0] + ".png")
+ grabConsole.ePopen(cmd)
+ self.playpauseService()
+
def main(session, service, **kwargs):
session.open(CutListEditor, service)