Index: ipk/source/editors_moviecutlistcollection_1_0/CONTROL/control
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/CONTROL/control	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/CONTROL/control	(revision 2752)
@@ -0,0 +1,10 @@
+Package: enigma2-plugin-editors-moviecutcollection
+Version: 1.0
+Architecture: sh4
+OE: CutListEditor , MovieCut and ReconstructApSc to cut movies
+Section: extra
+Priority: optional
+Maintainer: AAF
+Homepage: http://www.aaf-digital.info
+Source: http://www.aaf-digital.info
+Description: CutListEditor , MovieCut and ReconstructApSc to cut movies
Index: ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postinst
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postinst	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postinst	(revision 2752)
@@ -0,0 +1,30 @@
+#!/bin/sh
+TMP=/tmp/.editors
+
+echo "successfully installed"
+echo "syncing disk"
+sync
+if [ `df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1 | wc -l` -eq 1 ]; then
+	SPACE=`df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1`
+	FREE=`expr $SPACE - 100`
+	echo new freespace size $FREE kb
+fi
+
+echo "---------------------------------"
+echo "-----------PLEASE READ-----------"
+echo "---------------------------------"
+echo "now you can fins the editors in the menu of the movielist!!!"
+echo "....(press PLAY Button -> MENU Button)...."
+echo "---------------------------------"
+echo "---------------------------------"
+echo "---------------------------------"
+echo ""
+echo "---------------------------------"
+echo "-----------Bitte lesen-----------"
+echo "---------------------------------"
+echo "du kannst die Erweiterungen nun im Menue der Filmliste finden!!!"
+echo "....(drücke PLAY Taste -> MENU Taste)...."
+echo "---------------------------------"
+echo "---------------------------------"
+echo "---------------------------------"
+exit 0
Index: ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postrm
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postrm	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/CONTROL/postrm	(revision 2752)
@@ -0,0 +1,16 @@
+#!/bin/sh
+TMP=/tmp/.editors
+
+rm -r /usr/lib/enigma2/python/Plugins/Extensions/CutListEditor > /dev/null 2>&1
+rm -r /usr/lib/enigma2/python/Plugins/Extensions/MovieCut > /dev/null 2>&1
+rm -r /usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc > /dev/null 2>&1
+
+echo "successfully removed"
+echo "syncing disk"
+sync
+if [ `df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1 | wc -l` -eq 1 ]; then
+	SPACE=`df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1`
+	FREE=`expr $SPACE - 100`
+	echo new freespace size $FREE kb
+fi
+exit 0
Index: ipk/source/editors_moviecutlistcollection_1_0/CONTROL/preinst
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/CONTROL/preinst	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/CONTROL/preinst	(revision 2752)
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+TMP=/tmp/.editors
+echo "syncing disk"
+sync
+
+if [ `df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1 | wc -l` -eq 1 ]; then
+	SPACE=`df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1`
+	FREE=`expr $SPACE - 50`
+	SIZE=130
+	echo "checking freespace"
+	echo packege size $SIZE kb
+	echo freespace size $FREE kb
+	if  [ "$FREE" -lt "$SIZE" ]; then
+		echo "sorry no freespace left on device"
+		exit 1
+	else
+		echo ok
+	fi
+fi   
+echo "installing CutListEditor , MovieCut and ReconstructApSc to cut movies ..."
+echo "checking OS"
+if  [ `cat /etc/motd | grep AAF | grep M | grep rev | wc -l` -eq 0 ]; then                      
+	echo ---------------------------
+	echo DONT USE this IPK Package!!
+	echo ---
+	echo Only for AAF Image!!
+	echo ---------------------------
+	exit 1
+fi
+exit 0
Index: ipk/source/editors_moviecutlistcollection_1_0/CONTROL/prerm
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/CONTROL/prerm	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/CONTROL/prerm	(revision 2752)
@@ -0,0 +1,11 @@
+#!/bin/sh
+TMP=/tmp/.editors
+echo "syncing disk"
+sync
+if [ `df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1 | wc -l` -eq 1 ]; then
+	SPACE=`df | grep /dev/mtdblock | grep var | sed 's/ \+/ /g' | cut -d ' ' -f4 | tail -n1`
+	FREE=`expr $SPACE - 100`
+	echo freespace size $FREE kb
+fi
+echo "removing CutListEditor , MovieCut and ReconstructApSc..."
+exit 0
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/LICENSE
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/LICENSE	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/LICENSE	(revision 2752)
@@ -0,0 +1,12 @@
+This plugin is licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/keymap.xml
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/keymap.xml	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/keymap.xml	(revision 2752)
@@ -0,0 +1,45 @@
+<keymap>
+	<map context="CutlistSeekActions">
+<!--		<device name="dreambox remote control (native)">   -->
+			<key id="KEY_YELLOW" mapto="pauseService" flags="m" />
+			<key id="KEY_GREEN" mapto="unPauseService" flags="m" />
+			<key id="KEY_RED" mapto="seekBack" flags="b" />
+			<key id="KEY_BLUE" mapto="seekFwd" flags="b" />
+			<key id="KEY_RED" mapto="seekBackManual" flags="l" />
+			<key id="KEY_BLUE" mapto="seekFwdManual" flags="l" />
+<!--		</device>   -->
+		<device name="dreambox advanced remote control (native)">
+			<key id="KEY_PLAY" mapto="playpauseService" flags="m" />
+			<!--key id="KEY_GREEN" mapto="unPauseService" flags="m" /-->
+			<key id="KEY_PREVIOUSSONG" mapto="seekBack" flags="b" />
+			<key id="KEY_PREVIOUSSONG" mapto="seekBackManual" flags="l" />
+			<key id="KEY_NEXTSONG" mapto="seekFwd" flags="b" />
+			<key id="KEY_NEXTSONG" mapto="seekFwdManual" flags="l" />
+		</device>
+		
+		<key id="KEY_LEFT" mapto="seek:-1" flags="m" />
+		<key id="KEY_RIGHT" mapto="seek:1" flags="m" />
+
+		<key id="KEY_1" mapto="seek:-10" flags="m" />
+		<key id="KEY_3" mapto="seek:10" flags="m" />
+		<key id="KEY_4" mapto="seek:-30" flags="m" />
+		<key id="KEY_6" mapto="seek:30" flags="m" />
+		<key id="KEY_7" mapto="seek:-90" flags="m" />
+		<key id="KEY_9" mapto="seek:90" flags="m" />
+		<key id="KEY_PREVIOUS" mapto="seek:-300" flags="m" />
+		<key id="KEY_NEXT" mapto="seek:300" flags="m" />
+	</map>
+
+	<map context="CutListEditorActions">
+<!--		<key id="KEY_NEXT" mapto="setIn" flags="m" />
+		<key id="KEY_PREVIOUS" mapto="setOut" flags="m" /> -->
+<!--		<key id="KEY_0" mapto="setMark" flags="m" />  -->
+<!--		<key id="KEY_CHANNELUP" mapto="addMark" flags="m" />
+		<key id="KEY_CHANNELDOWN" mapto="removeMark" flags="m" /> -->
+		<key id="KEY_HOME" mapto="leave" flags="m" />
+		<key id="KEY_EXIT" mapto="leave" flags="m" />
+		<key id="KEY_ESC" mapto="leave" flags="m" />
+		<key id="KEY_OK" mapto="showMenu" flags="m" />
+		<key id="KEY_ENTER" mapto="showMenu" flags="m" />
+	</map>
+</keymap>
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/plugin.py
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/plugin.py	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/CutListEditor/plugin.py	(revision 2752)
@@ -0,0 +1,409 @@
+from Plugins.Plugin import PluginDescriptor
+
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Components.ServicePosition import ServicePositionGauge
+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, 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):
+	w = where / 90
+	ms = w % 1000
+	s = (w / 1000) % 60
+	m = (w / 60000) % 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"
+		type_col = 0x000000
+	return ((where, what), "%dh:%02dm:%02ds:%03d" % (h, m, s, ms), type, type_col)
+
+class CutListContextMenu(FixedMenu):
+	RET_STARTCUT = 0
+	RET_ENDCUT = 1
+	RET_DELETECUT = 2
+	RET_MARK = 3
+	RET_DELETEMARK = 4
+	RET_REMOVEBEFORE = 5
+	RET_REMOVEAFTER = 6
+	RET_GRABFRAME = 7
+
+	SHOW_STARTCUT = 0
+	SHOW_ENDCUT = 1
+	SHOW_DELETECUT = 2
+
+	def __init__(self, session, state, nearmark):
+		menu = [(_("back"), self.close)] #, (None, )]
+
+		if state == self.SHOW_STARTCUT:
+			menu.append((_("start cut here"), self.startCut))
+		else:
+			menu.append((_("start cut here"), ))
+
+		if state == self.SHOW_ENDCUT:
+			menu.append((_("end cut here"), self.endCut))
+		else:
+			menu.append((_("end cut here"), ))
+
+		if state == self.SHOW_DELETECUT:
+			menu.append((_("delete cut"), self.deleteCut))
+		else:
+			menu.append((_("delete cut"), ))
+
+		menu.append((_("remove before this position"), self.removeBefore))
+		menu.append((_("remove after this position"), self.removeAfter))
+
+#		menu.append((None, ))
+
+		if not nearmark:
+			menu.append((_("insert mark here"), self.insertMark))
+		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"
+
+	def startCut(self):
+		self.close(self.RET_STARTCUT)
+
+	def endCut(self):
+		self.close(self.RET_ENDCUT)
+
+	def deleteCut(self):
+		self.close(self.RET_DELETECUT)
+
+	def insertMark(self):
+		self.close(self.RET_MARK)
+
+	def removeMark(self):
+		self.close(self.RET_DELETEMARK)
+
+	def removeBefore(self):
+		self.close(self.RET_REMOVEBEFORE)
+
+	def removeAfter(self):
+		self.close(self.RET_REMOVEAFTER)
+
+	def grabFrame(self):
+		self.close(self.RET_GRABFRAME)
+
+class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, HelpableScreen):
+	skin = """
+	<screen position="0,0" size="720,576" title="Cutlist editor" flags="wfNoBorder">
+		<eLabel text="Cutlist editor" position="65,60" size="300,25" font="Regular;20" />
+		<widget source="global.CurrentTime" render="Label" position="268,60" size="394,20" font="Regular;20" halign="right">
+			<convert type="ClockToText">Format:%A %B %d, %H:%M</convert>
+		</widget>
+		<eLabel position="268,98" size="394,304" backgroundColor="#505555" />
+		<widget name="Video" position="270,100" zPosition="1" size="390,300" backgroundColor="transparent" />
+		<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="320,450" zPosition="1" size="420,25" font="Regular;20" halign="left" valign="center">
+			<convert type="ServicePosition">Position,Detailed</convert>
+		</widget>
+		<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>"""
+
+	def __init__(self, session, service):
+		self.skin = CutListEditor.skin
+		Screen.__init__(self, session)
+		InfoBarSeek.__init__(self, actionmap = "CutlistSeekActions")
+		InfoBarCueSheetSupport.__init__(self)
+		InfoBarBase.__init__(self, steal_current_service = True)
+		HelpableScreen.__init__(self)
+		self.old_service = session.nav.getCurrentlyPlayingServiceReference()
+		session.nav.playService(service)
+
+		service = session.nav.getCurrentService()
+		cue = service and service.cueSheet()
+		if cue is not None:
+			# disable cutlists. we want to freely browse around in the movie
+			print "cut lists disabled!"
+			cue.setCutListEnable(0)
+
+		self.downloadCuesheet()
+
+		self["Timeline"] = ServicePositionGauge(self.session.nav)
+		self["cutlist"] = List(self.getCutlist())
+		self["cutlist"].onSelectionChanged.append(self.selectionChanged)
+		self["SeekState"] = Label()
+		self.onPlayStateChanged.append(self.updateStateLabel)
+		self.updateStateLabel(self.seekstate)
+
+		desktopSize = getDesktop(0).size()
+		self["Video"] = VideoWindow(decoder = 0, fb_width=desktopSize.width(), fb_height=desktopSize.height())
+
+		self["actions"] = HelpableActionMap(self, "CutListEditorActions",
+			{
+				"setIn": (self.setIn, _("Make this mark an 'in' point")),
+				"setOut": (self.setOut, _("Make this mark an 'out' point")),
+				"setMark": (self.setMark, _("Make this mark just a mark")),
+				"addMark": (self.__addMark, _("Add a mark")),
+				"removeMark": (self.__removeMark, _("Remove a mark")),
+				"leave": (self.exit, _("Exit editor")),
+				"showMenu": (self.showMenu, _("menu")),
+			}, prio=-4)
+
+		self.tutorial_seen = False
+
+		self.onExecBegin.append(self.showTutorial)
+		self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
+			{
+				iPlayableService.evCuesheetChanged: self.refillList
+			})
+
+		# to track new entries we save the last version of the cutlist
+		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
+			self.session.open(MessageBox,_("Welcome to the Cutlist editor.\n\nSeek to the start of the stuff you want to cut away. Press OK, select 'start cut'.\n\nThen seek to the end, press OK, select 'end cut'. That's it."), MessageBox.TYPE_INFO)
+
+	def checkSkipShowHideLock(self):
+		pass
+
+	def setType(self, index, type):
+		if len(self.cut_list):
+			self.cut_list[index] = (self.cut_list[index][0], type)
+			self["cutlist"].modifyEntry(index, CutListEntry(*self.cut_list[index]))
+
+	def setIn(self):
+		m = self["cutlist"].getIndex()
+		self.setType(m, 0)
+		self.uploadCuesheet()
+
+	def setOut(self):
+		m = self["cutlist"].getIndex()
+		self.setType(m, 1)
+		self.uploadCuesheet()
+
+	def setMark(self):
+		m = self["cutlist"].getIndex()
+		self.setType(m, 2)
+		self.uploadCuesheet()
+
+	def __addMark(self):
+		self.toggleMark(onlyadd=True, tolerance=90000) # do not allow two marks in <1s
+
+	def __removeMark(self):
+		m = self["cutlist"].getCurrent()
+		m = m and m[0]
+		if m is not None:
+			self.removeMark(m)
+
+	def exit(self):
+		self.close()
+
+	def getCutlist(self):
+		r = [ ]
+		for e in self.cut_list:
+			r.append(CutListEntry(*e))
+		return r
+
+	def selectionChanged(self):
+		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, counted from the end, and select it
+		new_list = self.getCutlist()
+		self["cutlist"].list = new_list
+
+		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 = -1
+		for (where, what) in self.cut_list:
+			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):
+		curpos = self.cueGetCurrentPosition()
+		if curpos is None:
+			return
+
+		self.setSeekState(self.SEEK_STATE_PAUSE)
+
+		self.context_position = curpos
+
+		self.context_nearest_mark = self.toggleMark(onlyreturn=True)
+
+		cur_state = self.getStateForPosition(curpos)
+		if cur_state == 0:
+			print "currently in 'IN'"
+			if self.cut_start is None or self.context_position < self.cut_start:
+				state = CutListContextMenu.SHOW_STARTCUT
+			else:
+				state = CutListContextMenu.SHOW_ENDCUT
+		else:
+			print "currently in 'OUT'"
+			state = CutListContextMenu.SHOW_DELETECUT
+
+		if self.context_nearest_mark is None:
+			nearmark = False
+		else:
+			nearmark = True
+
+		self.session.openWithCallback(self.menuCallback, CutListContextMenu, state, nearmark)
+
+	def menuCallback(self, *result):
+		if not len(result):
+			return
+		result = result[0]
+
+		if result == CutListContextMenu.RET_STARTCUT:
+			self.cut_start = self.context_position
+		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):
+					self.cut_list.remove((where, what))
+
+			bisect.insort(self.cut_list, (self.cut_start, 1))
+			bisect.insort(self.cut_list, (self.context_position, 0))
+			self.uploadCuesheet()
+			self.cut_start = None
+		elif result == CutListContextMenu.RET_DELETECUT:
+			out_before = None
+			in_after = None
+
+			for (where, what) in self.cut_list:
+				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:
+					in_after = (where, what)
+
+			if out_before is not None:
+				self.cut_list.remove(out_before)
+
+			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):
+					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):
+					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)
+	def playpauseService(self):
+		if self.seekstate != self.SEEK_STATE_PLAY and not self.isStateSlowMotion(self.seekstate):
+			self.unPauseService()
+		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)
+
+def Plugins(**kwargs):
+ 	return PluginDescriptor(name="Cutlist Editor", description=_("Cutlist editor..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/maintainer.info
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/maintainer.info	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/maintainer.info	(revision 2752)
@@ -0,0 +1,2 @@
+aho@sics.se
+MovieCut-1.2.1
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/plugin.py
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/plugin.py	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/plugin.py	(revision 2752)
@@ -0,0 +1,310 @@
+from Plugins.Plugin import PluginDescriptor
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Screens.ChoiceBox import ChoiceBox
+from Screens.LocationBox import MovieLocationBox
+import Screens.Standby
+from Components.config import config, ConfigText, ConfigSelection, ConfigNothing, getConfigListEntry
+from Components.ActionMap import ActionMap
+from Components.ConfigList import ConfigList, ConfigListScreen
+from Components.Sources.StaticText import StaticText
+from enigma import eTimer, eServiceCenter, iServiceInformation, eConsoleAppContainer
+from os import access, chmod, X_OK
+
+mcut_path = "/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/bin/mcut"
+# Hack to make sure it is executable
+if not access(mcut_path, X_OK):
+	chmod(mcut_path, 493)
+
+def main(session, service, **kwargs):
+	session.open(MovieCut, service, **kwargs)
+
+def Plugins(**kwargs):
+	return PluginDescriptor(name="MovieCut", description=_("Execute cuts..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
+
+
+class MovieCut(ChoiceBox):
+	def __init__(self, session, service):
+		self.service = service
+		serviceHandler = eServiceCenter.getInstance()
+		path = self.service.getPath()
+		info = serviceHandler.info(self.service)
+		if not info:
+			self.name = path
+		else:
+			self.name = info.getName(self.service)
+		tlist = [
+			(_("Don't cut"), "CALLFUNC", self.confirmed0),
+			(_("Replace the original movie with the cut movie"), "CALLFUNC", self.confirmed1),
+			(_("Place the cut movie in a new file ending with \" cut\""), "CALLFUNC", self.confirmed2),
+			(_("Advanced cut specification..."), "CALLFUNC", self.confirmed3),
+		]
+		ChoiceBox.__init__(self, session, _("How would you like to cut \"%s\"?") % (self.name), list = tlist, selection = 0)
+		self.skinName = "ChoiceBox"
+
+	def confirmed0(self, arg):
+		self.close()
+
+	def confirmed1(self, arg):
+		MovieCutSpawn(self.session, self, [mcut_path, "-r", self.service.getPath()], self.name)
+
+	def confirmed2(self, arg):
+		MovieCutSpawn(self.session, self, [mcut_path, self.service.getPath()], self.name)
+
+	def confirmed3(self, arg):
+		serviceHandler = eServiceCenter.getInstance()
+		info = serviceHandler.info(self.service)
+		path = self.service.getPath()
+		self.name = info.getName(self.service)
+		descr = info.getInfoString(self.service, iServiceInformation.sDescription)
+		self.session.openWithCallback(self.advcutConfirmed, AdvancedCutInput, self.name, path, descr)
+
+	def advcutConfirmed(self, ret):
+		if len(ret) <= 1 or not ret[0]:
+			self.close()
+			return
+		clist = [mcut_path]
+		if ret[1] == True:
+			clist.append("-r")
+		clist.append(self.service.getPath())
+		if ret[2] != False:
+			clist += ["-o", ret[2]]
+		if ret[3] != False:
+			clist += ["-n", ret[3]]
+		if ret[4] != False:
+			clist += ["-d", ret[4]]
+		if ret[5] != False:
+			clist.append("-c")
+			clist += ret[5]
+		MovieCutSpawn(self.session, self, clist, self.name)
+		
+class AdvancedCutInput(Screen, ConfigListScreen):
+	def __init__(self, session, name, path, descr):
+		Screen.__init__(self, session)
+		self.skinName = [ "AdvancedCutInput", "Setup" ]
+
+		self["key_green"] = StaticText(_("OK"))
+		self["key_red"] = StaticText(_("Cancel"))
+
+		if self.baseName(path) == self.baseName(name):
+			title = ""
+		else:
+			title = name
+		dir = self.dirName(path)
+		file = self.baseName(path) + " cut"
+		self.input_replace = ConfigSelection(choices = [("no", _("No")), ("yes", _("Yes"))], default = "no")
+		self.input_file = ConfigText(default = file, fixed_size = False, visible_width = 45)
+		self.input_title = ConfigText(default = title, fixed_size = False, visible_width = 45)
+		self.input_descr = ConfigText(default = descr, fixed_size = False, visible_width = 45)
+		tmp = config.movielist.videodirs.value
+		if not dir in tmp:
+			tmp.append(dir)
+		self.input_dir = ConfigSelection(choices = tmp, default = dir)
+		self.input_manual = ConfigSelection(choices = [("no", _("Cutlist")), ("yes", _("Manual specification"))], default = "no")
+		self.input_space = ConfigNothing()
+		self.input_manualcuts = ConfigText(default = "", fixed_size = False)
+		self.input_manualcuts.setUseableChars(" 0123456789:.")
+
+		self["actions"] = ActionMap(["SetupActions"],
+		{
+			"ok": self.keySelectOrGo,
+			"save": self.keyGo,
+			"cancel": self.keyCancel,
+		}, -2)
+
+		self.list = []
+		ConfigListScreen.__init__(self, self.list)
+		self.entry_replace = getConfigListEntry(_("Replace original:"), self.input_replace)
+		self.entry_file = getConfigListEntry(_("New filename:"), self.input_file)
+		self.entry_title = getConfigListEntry(_("New title:"), self.input_title)
+		self.entry_descr = getConfigListEntry(_("New description:"), self.input_descr)
+		self.entry_dir = getConfigListEntry(_("New location:"), self.input_dir)
+		self.entry_manual = getConfigListEntry(_("Cut source:"), self.input_manual)
+		self.entry_space = getConfigListEntry(_("Cuts (an IN OUT IN OUT ... sequence of hour:min:sec)"), self.input_space)
+		self.entry_manualcuts = getConfigListEntry(":", self.input_manualcuts)
+		self.createSetup(self["config"])
+
+		self.onLayoutFinish.append(self.layoutFinished)
+
+	def layoutFinished(self):
+		self.setTitle(_("Cut Parameter Input"))
+
+	def createSetup(self, configlist):
+		list = [
+			self.entry_replace
+		]
+		if self.input_replace.value == "no":
+			list.extend((
+				self.entry_file,
+				self.entry_dir,
+			))
+		list.extend((
+			self.entry_title,
+			self.entry_descr,
+			self.entry_manual,
+		))
+		if self.input_manual.value == "yes":
+			list.extend((
+				self.entry_space,
+				self.entry_manualcuts,
+			))
+		self.list = list
+		configlist.list = list
+		configlist.l.setList(list)
+
+	def keyLeft(self):
+		ConfigListScreen.keyLeft(self)
+		cc = self["config"].getCurrent()
+		if cc is self.entry_replace or cc is self.entry_manual:
+			self.createSetup(self["config"])
+
+	def keyRight(self):
+		ConfigListScreen.keyRight(self)
+		cc = self["config"].getCurrent()
+		if cc is self.entry_replace or cc is self.entry_manual:
+			self.createSetup(self["config"])
+
+	def pathSelected(self, res):
+		if res is not None:
+			if config.movielist.videodirs.value != self.input_dir.choices:
+				self.input_dir.setChoices(config.movielist.videodirs.value, default=res)
+			self.input_dir.value = res
+
+	def keySelectOrGo(self):
+		if self["config"].getCurrent() == self.entry_dir:
+			self.session.openWithCallback(
+				self.pathSelected,
+				MovieLocationBox,
+				_("Choose target folder"),
+				self.input_dir.value,
+			)
+		else:
+			self.keyGo()
+
+	def keyGo(self):
+		if self.input_replace.value == "yes":
+			path = False
+		else:
+			path = self.rejoinName(self.input_dir.value, self.input_file.value)
+		if self.input_manual.value == "no":
+			cuts = False
+		else:
+			cuts = self.input_manualcuts.value.split(' ')
+			while "" in cuts:
+				cuts.remove("")
+		self.close((True, self.input_replace.value, path, self.input_title.value, self.input_descr.value, cuts))
+
+	def keyCancel(self):
+		self.close((False,))
+
+	def baseName(self, str):
+		name = str.split('/')[-1]
+		if name.endswith(".ts") is True:
+			return name[:-3]
+		else:
+			return name
+
+	def dirName(self, str):
+		return '/'.join(str.split('/')[:-1]) + '/'
+
+	def rejoinName(self, dir, name):
+		name = name.strip()
+		if name.endswith(".ts") is True:
+			return dir + name[:-3]
+		else:
+			return dir + name
+
+class MovieCutQueue:
+	def __init__(self):
+		self.container = eConsoleAppContainer()
+		self.container.appClosed.append(self.runDone)
+		self.queue = []
+		self.running = False
+
+	def enqueue(self, cb, cmd):
+		self.queue.append((cb, cmd))
+		if not self.running:
+			self.running = True
+			self.runNext()
+			return True
+		else:
+			return False
+
+	def runNext(self):
+		if not self.queue:
+			self.running = False
+		else:
+			self.container.execute(*self.queue[0][1])
+
+	def runDone(self, retval):
+		cb = self.queue[0][0]
+		self.queue = self.queue[1:]
+		cb(retval)
+		self.runNext()
+
+global_mcut_errors = [_("The movie \"%s\" is successfully cut"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Bad arguments"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .ts file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .cuts file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .ap file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .ts file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .cuts file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .ap file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Empty .ap file"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("No cuts specified"),
+		      _("Cutting failed for movie \"%s\"")+":\n"+_("Read/write error (disk full?)"),
+		      _("Cutting was aborted for movie \"%s\"")]
+
+global_mcut_queue = MovieCutQueue()
+
+global_mcut_block = False
+
+class MovieCutSpawn:
+	def __init__(self, session, parent, clist, name):
+		global global_mcut_queue
+		global global_mcut_block
+		self.session = session
+		self.parent = parent
+		self.name = name
+		self.clist = [clist[0]] + clist
+		self.mess = ""
+		self.dialog = False
+		self.waitTimer = eTimer()
+		self.waitTimer.callback.append(self.doWaitAck)
+		if global_mcut_queue.enqueue(self.doAck, self.clist):
+			mess = _("The movie \"%s\" is cut in the background.") % (self.name)
+		else:
+			mess = _("Another movie is currently cut.\nThe movie \"%s\" will be cut in the background after it.") % (self.name)
+		global_mcut_block = True
+		self.dialog = self.session.openWithCallback(self.endc, MessageBox, mess, MessageBox.TYPE_INFO)
+
+	def doAck(self, retval):
+		global global_mcut_errors
+#		if WIFEXITED(retval):
+#			self.mess = global_mcut_errors[WEXITSTATUS(retval)] % (self.name)
+#		else:
+#			self.mess = global_mcut_errors[-1] % (self.name)
+		self.mess = global_mcut_errors[retval] % (self.name)
+		self.doWaitAck()
+
+	def doWaitAck(self):
+		global global_mcut_block
+		if Screens.Standby.inStandby or not self.session.in_exec or (global_mcut_block and not self.dialog):
+			self.waitTimer.start(2000, True)
+		else:
+			global_mcut_block = True
+			self.session.openWithCallback(self.endw, MessageBox, self.mess, MessageBox.TYPE_INFO)
+
+	def endw(self, arg = 0):
+		global global_mcut_block
+		global_mcut_block = False
+		if self.session.current_dialog == self.dialog:
+			self.session.current_dialog.close(True)
+			self.endc(arg)
+
+	def endc(self, arg = 0):
+		global global_mcut_block
+		global_mcut_block = False
+		self.dialog = False
+		self.parent.close()
+#		self.session.current_dialog.close()
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/maintainer.info
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/maintainer.info	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/maintainer.info	(revision 2752)
@@ -0,0 +1,2 @@
+aho@sics.se
+ReconstructApSc
Index: ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/plugin.py
===================================================================
--- ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/plugin.py	(revision 2752)
+++ ipk/source/editors_moviecutlistcollection_1_0/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/plugin.py	(revision 2752)
@@ -0,0 +1,154 @@
+from Plugins.Plugin import PluginDescriptor
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Screens.ChoiceBox import ChoiceBox
+import Screens.Standby
+from Components.ActionMap import ActionMap
+from enigma import eTimer, eServiceCenter, iServiceInformation, eConsoleAppContainer
+from os import access, chmod, X_OK
+
+recons_path = "/usr/lib/enigma2/python/Plugins/Extensions/ReconstructApSc/bin/reconstruct_apsc"
+
+def main(session, service, **kwargs):
+	# Hack to make sure it is executable
+	if not access(recons_path, X_OK):
+		chmod(recons_path, 493)
+	session.open(ReconstructApSc, service, **kwargs)
+
+def Plugins(**kwargs):
+	return PluginDescriptor(name="ReconstructApSc", description=_("Reconstruct AP/SC ..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
+
+
+class ReconstructApSc(ChoiceBox):
+	def __init__(self, session, service):
+		self.service = service
+		serviceHandler = eServiceCenter.getInstance()
+		path = self.service.getPath()
+		info = serviceHandler.info(self.service)
+		if not info:
+			self.name = path
+		else:
+			self.name = info.getName(self.service)
+		tlist = [
+			(_("Don't reconstruct"), "CALLFUNC", self.confirmed0),
+			(_("Reconstruct the .ap and .sc files of the selected movie"), "CALLFUNC", self.confirmed1),
+			(_("Reconstruct all missing .ap and .sc files in this directory"), "CALLFUNC", self.confirmed2),
+			(_("Check any running reconstruct process"), "CALLFUNC", self.confirmed3),
+		]
+		ChoiceBox.__init__(self, session, _("What would you like to reconstruct?  (\"%s\")") % (self.name), list = tlist, selection = 0)
+		self.skinName = "ChoiceBox"
+
+	def confirmed0(self, arg):
+		self.close()
+
+	def confirmed1(self, arg):
+		ReconstructApScSpawn(self.session, self, [recons_path, self.service.getPath()], self.name, _("movie"))
+
+	def confirmed2(self, arg):
+		dir = self.dirName(self.service.getPath())
+		ReconstructApScSpawn(self.session, self, [recons_path, "-d", dir], dir, _("directory"))
+
+	def confirmed3(self, arg):
+		output = global_recons_queue.checkOutput()
+		if output == False:
+			mess = "There is no running reconstruction process"
+		else:
+			mess = "Current reconstruction process output:\n%s" % output
+		self.session.openWithCallback(self.close, MessageBox, mess, MessageBox.TYPE_INFO)
+
+	def dirName(self, str):
+		return '/'.join(str.split('/')[:-1]) + '/'
+
+
+class ReconstructApScQueue:
+	def __init__(self):
+		self.container = eConsoleAppContainer()
+		self.container.appClosed.append(self.runDone)
+		self.container.dataAvail.append(self.collOutput)
+		self.queue = []
+		self.output = ""
+		self.running = False
+
+	def enqueue(self, cb, cmd):
+		self.queue.append((cb, cmd))
+		if not self.running:
+			self.runNext()
+			return True
+		else:
+			return False
+
+	def collOutput(self, data):
+		self.output += data
+
+	def checkOutput(self):
+		if not self.running:
+			return False
+		else:
+			return self.output
+
+	def runNext(self):
+		self.output = ""
+		if not self.queue:
+			self.running = False
+		else:
+			self.running = True
+			self.container.execute(*self.queue[0][1])
+
+	def runDone(self, retval):
+		cb = self.queue[0][0]
+		self.queue = self.queue[1:]
+		cb(retval, self.output)
+		self.runNext()
+
+global_recons_errors = [_("The %s \"%s\" is successfully processed:\n%s"),
+		      _("Processing failed for the %s \"%s\":\n%s")]
+
+global_recons_queue = ReconstructApScQueue()
+
+global_recons_block = False
+
+class ReconstructApScSpawn:
+	def __init__(self, session, parent, clist, name, typename):
+		global global_recons_queue
+		global global_recons_block
+		self.session = session
+		self.parent = parent
+		self.name = name
+		self.typename = typename
+		self.clist = [clist[0]] + clist
+		self.mess = ""
+		self.dialog = False
+		self.waitTimer = eTimer()
+		self.waitTimer.callback.append(self.doWaitAck)
+		if global_recons_queue.enqueue(self.doAck, self.clist):
+			mess = _("The %s \"%s\" is processed in the background.") % (self.typename, self.name)
+		else:
+			mess = _("Another movie or directory is currently processed.\nThe %s \"%s\" will be processed in the background after it.") % (self.typename, self.name)
+		global_recons_block = True
+		self.dialog = self.session.openWithCallback(self.endc, MessageBox, mess, MessageBox.TYPE_INFO)
+
+	def doAck(self, retval, output):
+		global global_recons_errors
+		self.mess = global_recons_errors[retval] % (self.typename, self.name, output)
+		self.doWaitAck()
+
+	def doWaitAck(self):
+		global global_recons_block
+		if Screens.Standby.inStandby or not self.session.in_exec or (global_recons_block and not self.dialog):
+			self.waitTimer.start(2000, True)
+		else:
+			global_recons_block = True
+			self.session.openWithCallback(self.endw, MessageBox, self.mess, MessageBox.TYPE_INFO)
+
+	def endw(self, arg = 0):
+		global global_recons_block
+		global_recons_block = False
+		if self.session.current_dialog == self.dialog:
+			self.session.current_dialog.close(True)
+			self.endc(arg)
+
+	def endc(self, arg = 0):
+		global global_recons_block
+		global_recons_block = False
+		self.dialog = False
+		self.parent.close()
