diff options
| author | Felix Domke <tmbinc@elitedvb.net> | 2008-11-17 15:42:54 +0100 |
|---|---|---|
| committer | Felix Domke <tmbinc@elitedvb.net> | 2008-11-17 15:42:54 +0100 |
| commit | a34ef895210161a8820e96829ac87806566e7858 (patch) | |
| tree | 55b9f104dbbdd8a1d72e598b989421f839576b9a /lib/python/Plugins | |
| parent | 588010098dbcc24b82ea736feec6b6056cffd2e3 (diff) | |
| parent | 153e0ed5048c79c600e1acd085b62015b7314ba7 (diff) | |
| download | enigma2-a34ef895210161a8820e96829ac87806566e7858.tar.gz enigma2-a34ef895210161a8820e96829ac87806566e7858.zip | |
Merge branch 'master' into tmbinc/FixTimingBugs
Conflicts:
lib/dvb/sec.cpp
lib/python/Components/Network.py
lib/python/Components/Playlist.py
lib/python/Plugins/Extensions/DVDBurn/Process.py
lib/python/Plugins/Extensions/MediaPlayer/plugin.py
lib/python/Screens/TimerEdit.py
po/lt.po
po/nl.po
po/tr.po
Diffstat (limited to 'lib/python/Plugins')
24 files changed, 793 insertions, 227 deletions
diff --git a/lib/python/Plugins/DemoPlugins/TestPlugin/Makefile.am b/lib/python/Plugins/DemoPlugins/TestPlugin/Makefile.am index 8173b373..2c52330f 100644 --- a/lib/python/Plugins/DemoPlugins/TestPlugin/Makefile.am +++ b/lib/python/Plugins/DemoPlugins/TestPlugin/Makefile.am @@ -4,3 +4,4 @@ install_PYTHON = \ __init__.py \ plugin.py +install_DATA = maintainer.info diff --git a/lib/python/Plugins/DemoPlugins/TestPlugin/maintainer.info b/lib/python/Plugins/DemoPlugins/TestPlugin/maintainer.info new file mode 100644 index 00000000..4f285613 --- /dev/null +++ b/lib/python/Plugins/DemoPlugins/TestPlugin/maintainer.info @@ -0,0 +1,2 @@ +tmbinc@elitedvb.net +Demo-Plugin diff --git a/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py b/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py index 1f49a9e3..a63562c8 100644 --- a/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py +++ b/lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py @@ -50,6 +50,8 @@ class Test(Screen): def mycallback(self, answer): print "answer:", answer + if answer: + raise "test-crash" self.close() def keyLeft(self): diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 8d02cb22..112a221e 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -1,5 +1,5 @@ from Tools.Directories import fileExists -from Components.config import config, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence +from Components.config import config, ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence class ConfigColor(ConfigSequence): def __init__(self): @@ -32,6 +32,7 @@ class DVDProject: self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size = False, visible_width = 40) self.settings.authormode = ConfigSelection(choices = [("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("Dreambox format data DVD (HDTV compatible)"))]) + self.settings.titlesetmode = ConfigSelection(choices = [("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") self.settings.output = ConfigSelection(choices = [("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) self.settings.isopath = ConfigText(fixed_size = False, visible_width = 40) self.settings.dataformat = ConfigSelection(choices = [("iso9660_1", ("ISO9660 Level 1")), ("iso9660_4", ("ISO9660 version 2")), ("udf", ("UDF"))]) @@ -46,7 +47,6 @@ class DVDProject: self.settings.font_size = ConfigPixelvals() self.settings.space = ConfigPixelvals() self.settings.vmgm = ConfigFilename() - self.settings.autochapter = ConfigInteger(default = 0, limits = (0, 99)) self.filekeys = ["vmgm", "menubg", "menuaudio", "font_face", "isopath"] def addService(self, service): diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py index 1bfb3d64..b1c627aa 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py @@ -1,17 +1,32 @@ +from Components.config import config, ConfigSubsection, ConfigSubList, ConfigInteger, ConfigText, ConfigSelection, getConfigListEntry, ConfigSequence, ConfigYesNo + +class ConfigFixedText(ConfigText): + def __init__(self, text, visible_width=60): + ConfigText.__init__(self, default = text, fixed_size = True, visible_width = visible_width) + def handleKey(self, key): + pass + class DVDTitle: def __init__(self): + self.properties = ConfigSubsection() + self.properties.menutitle = ConfigText(fixed_size = False, visible_width = 80) + self.properties.menusubtitle = ConfigText(fixed_size = False, visible_width = 80) + self.DVBname = _("Title") + self.DVBdescr = _("Description") + self.DVBchannel = _("Channel") + self.properties.aspect = ConfigSelection(choices = [("4:3", _("4:3")), ("16:9", _("16:9"))]) + self.properties.widescreen = ConfigSelection(choices = [("nopanscan", "nopanscan"), ("noletterbox", "noletterbox")]) + self.properties.autochapter = ConfigInteger(default = 0, limits = (0, 60)) + self.properties.audiotracks = ConfigSubList() self.cuesheet = [ ] self.source = None - self.name = "" - self.descr = "" self.filesize = 0 self.estimatedDiskspace = 0 self.inputfile = "" self.cutlist = [ ] self.chaptermarks = [ ] - self.audiotracks = [ ] self.timeCreate = None - self.sVideoType = -1 + self.VideoType = -1 def addService(self, service): from os import path @@ -21,18 +36,61 @@ class DVDTitle: self.source = service serviceHandler = eServiceCenter.getInstance() info = serviceHandler.info(service) - self.descr = info and " " + info.getInfoString(service, iServiceInformation.sDescription) or "" + sDescr = info and " " + info.getInfoString(service, iServiceInformation.sDescription) or "" + self.DVBdescr = sDescr sTimeCreate = info.getInfo(service, iServiceInformation.sTimeCreate) if sTimeCreate > 1: self.timeCreate = localtime(sTimeCreate) serviceref = ServiceReference(info.getInfoString(service, iServiceInformation.sServiceref)) - self.name = info and info.getName(service) or "Title" + t.descr - self.channel = serviceref.getServiceName() + name = info and info.getName(service) or "Title" + sDescr + self.DVBname = name + self.DVBchannel = serviceref.getServiceName() self.inputfile = service.getPath() self.filesize = path.getsize(self.inputfile) self.estimatedDiskspace = self.filesize self.length = info.getLength(service) + def initDVDmenuText(self, project, track): + self.properties.menutitle.setValue(self.formatDVDmenuText(project.settings.titleformat.getValue(), track)) + self.properties.menusubtitle.setValue(self.formatDVDmenuText(project.settings.subtitleformat.getValue(), track)) + + def formatDVDmenuText(self, template, track): + properties = self.properties + template = template.replace("$i", str(track)) + template = template.replace("$t", self.DVBname) + template = template.replace("$d", self.DVBdescr) + template = template.replace("$c", str(len(self.chaptermarks)+1)) + template = template.replace("$f", self.inputfile) + template = template.replace("$C", self.DVBchannel) + + #if template.find("$A") >= 0: + from TitleProperties import languageChoices + audiolist = [ ] + for audiotrack in self.properties.audiotracks: + active = audiotrack.active.getValue() + if active: + trackstring = audiotrack.format.getValue() + language = audiotrack.language.getValue() + if languageChoices.langdict.has_key(language): + trackstring += ' (' + languageChoices.langdict[language] + ')' + audiolist.append(trackstring) + audiostring = ', '.join(audiolist) + template = template.replace("$A", audiostring) + + if template.find("$l") >= 0: + l = self.length + lengthstring = "%d:%02d:%02d" % (l/3600, l%3600/60, l%60) + template = template.replace("$l", lengthstring) + if self.timeCreate: + template = template.replace("$Y", str(self.timeCreate[0])) + template = template.replace("$M", str(self.timeCreate[1])) + template = template.replace("$D", str(self.timeCreate[2])) + timestring = "%d:%02d" % (self.timeCreate[3], self.timeCreate[4]) + template = template.replace("$T", timestring) + else: + template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$T", "") + return template + def produceFinalCuesheet(self): CUT_TYPE_IN = 0 CUT_TYPE_OUT = 1 @@ -78,9 +136,21 @@ class DVDTitle: self.estimatedDiskspace = usedsize self.length = accumulated_in / 90000 - def produceAutoChapter(self, minutes): - if len(self.chaptermarks) < 1: - chapterpts = self.cutlist[0] - while chapterpts < self.length*90000: + def getChapterMarks(self, template="$h:$m:$s.$t"): + timestamps = [ ] + chapters = [ ] + minutes = self.properties.autochapter.getValue() + if len(self.chaptermarks) < 1 and minutes > 0: + chapterpts = 0 + while chapterpts < (self.length-60*minutes)*90000: chapterpts += 90000 * 60 * minutes - self.chaptermarks.append(chapterpts) + chapters.append(chapterpts) + else: + chapters = self.chaptermarks + for p in chapters: + timestring = template.replace("$h", str(p / (90000 * 3600))) + timestring = timestring.replace("$m", ("%02d" % (p % (90000 * 3600) / (90000 * 60)))) + timestring = timestring.replace("$s", ("%02d" % (p % (90000 * 60) / 90000))) + timestring = timestring.replace("$t", ("%03d" % ((p % 90000) / 90))) + timestamps.append(timestring) + return timestamps
\ No newline at end of file diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index d4e6a375..836c9fbd 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -9,6 +9,7 @@ from Components.Task import Task, Job, job_manager, Condition from Components.ScrollLabel import ScrollLabel from Components.Harddisk import harddiskmanager from Components.Console import Console +from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier class DVDToolbox(Screen): skin = """ @@ -54,6 +55,7 @@ class DVDToolbox(Screen): "pageDown": self.pageDown }) self.update() + hotplugNotifier.append(self.update) def pageUp(self): self["details"].pageUp() @@ -61,7 +63,7 @@ class DVDToolbox(Screen): def pageDown(self): self["details"].pageDown() - def update(self): + def update(self, dev="", media_state=""): self["space_label"].text = _("Please wait... Loading list...") self["info"].text = "" self["details"].setText("") @@ -141,6 +143,7 @@ class DVDToolbox(Screen): def exit(self): del self.Console + hotplugNotifier.remove(self.update) self.close() class DVDformatJob(Job): diff --git a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml index d9831e63..7d8de8ce 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml +++ b/lib/python/Plugins/Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml @@ -3,8 +3,9 @@ <settings name="Dreambox DVD record" authormode="menu_linked" + titlesetmode="multi" titleformat="$i. $t" - subtitleformat="$D.$M.$Y, $T $C, $d ($c chapters)" + subtitleformat="$D.$M.$Y, $T $C, $d" vmgm="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/vmgmdream.mpg" menubg="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/dreamdvd_boat.jpg" menuaudio="/usr/lib/enigma2/python/Plugins/Extensions/DVDBurn/silence.mp2" diff --git a/lib/python/Plugins/Extensions/DVDBurn/Makefile.am b/lib/python/Plugins/Extensions/DVDBurn/Makefile.am index cb65f56a..be89ebaa 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Makefile.am +++ b/lib/python/Plugins/Extensions/DVDBurn/Makefile.am @@ -3,7 +3,7 @@ installdir = $(LIBDIR)/enigma2/python/Plugins/Extensions/DVDBurn install_PYTHON = \ __init__.py \ plugin.py \ - DVDProject.py DVDTitle.py TitleCutter.py TitleList.py Process.py ProjectSettings.py DVDToolbox.py + DVDProject.py DVDTitle.py TitleCutter.py TitleList.py TitleProperties.py Process.py ProjectSettings.py DVDToolbox.py install_DATA = *.xml *.jpg *.mpg *.mp2 *.png diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index 49054596..89ca90fd 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -85,23 +85,34 @@ class DemuxTask(Task): title = job.project.titles[job.i] self.global_preconditions.append(DiskspacePrecondition(title.estimatedDiskspace)) self.setTool("/usr/bin/projectx") - self.generated_files = [ ] + self.args += [inputfile, "-demux", "-out", self.job.workspace ] self.end = 300 self.prog_state = 0 self.weighting = 1000 self.cutfile = self.job.workspace + "/cut_%d.Xcl" % (job.i+1) self.cutlist = title.cutlist - self.args += [inputfile, "-demux", "-out", self.job.workspace ] + self.currentPID = None + self.relevantAudioPIDs = [ ] + self.getRelevantAudioPIDs(title) + self.generated_files = [ ] + self.mplex_streamfiles = [ ] if len(self.cutlist) > 1: self.args += [ "-cut", self.cutfile ] def prepare(self): self.writeCutfile() + def getRelevantAudioPIDs(self, title): + for audiotrack in title.properties.audiotracks: + if audiotrack.active.getValue(): + self.relevantAudioPIDs.append(audiotrack.pid.getValue()) + def processOutputLine(self, line): line = line[:-1] MSG_NEW_FILE = "---> new File: " MSG_PROGRESS = "[PROGRESS] " + MSG_NEW_MP2 = "--> MPEG Audio (0x" + MSG_NEW_AC3 = "--> AC-3/DTS Audio on PID " if line.startswith(MSG_NEW_FILE): file = line[len(MSG_NEW_FILE):] @@ -111,10 +122,14 @@ class DemuxTask(Task): elif line.startswith(MSG_PROGRESS): progress = line[len(MSG_PROGRESS):] self.haveProgress(progress) + elif line.startswith(MSG_NEW_MP2) or line.startswith(MSG_NEW_AC3): + self.currentPID = str(int(line.rstrip()[-6:].rsplit('0x',1)[-1],16)) def haveNewFile(self, file): - print "PRODUCED FILE [%s]" % file + print "[DemuxTask] produced file:", file, self.currentPID self.generated_files.append(file) + if self.currentPID in self.relevantAudioPIDs or file.endswith("m2v"): + self.mplex_streamfiles.append(file) def haveProgress(self, progress): #print "PROGRESS [%s]" % progress @@ -131,7 +146,6 @@ class DemuxTask(Task): if p > self.progress: self.progress = p except ValueError: - print "val error" pass def writeCutfile(self): @@ -151,8 +165,8 @@ class DemuxTask(Task): def cleanup(self, failed): if failed: import os - for f in self.generated_files: - os.remove(f) + for file in self.generated_files.itervalues(): + os.remove(file) class MplexTaskPostcondition(Condition): def check(self, task): @@ -185,9 +199,9 @@ class MplexTask(Task): # we don't want the ReturncodePostcondition in this case because for right now we're just gonna ignore the fact that mplex fails with a buffer underrun error on some streams (this always at the very end) def prepare(self): - self.error = None + self.error = None if self.demux_task: - self.args += self.demux_task.generated_files + self.args += self.demux_task.mplex_streamfiles def processOutputLine(self, line): print "[MplexTask] ", line[:-1] @@ -206,7 +220,7 @@ class RemoveESFiles(Task): def prepare(self): self.args += ["-f"] - self.args += self.demux_task.generated_files + self.args += self.demux_task.generated_files.values() self.args += [self.demux_task.cutfile] class DVDAuthorTask(Task): @@ -411,27 +425,6 @@ class PreviewTaskPostcondition(Condition): def getErrorMessage(self, task): return "Cancel" -def formatTitle(template, title, track): - template = template.replace("$i", str(track)) - template = template.replace("$t", title.name) - template = template.replace("$d", title.descr) - template = template.replace("$c", str(len(title.chaptermarks)+1)) - template = template.replace("$A", str(title.audiotracks)) - template = template.replace("$f", title.inputfile) - template = template.replace("$C", title.channel) - l = title.length - lengthstring = "%d:%02d:%02d" % (l/3600, l%3600/60, l%60) - template = template.replace("$l", lengthstring) - if title.timeCreate: - template = template.replace("$Y", str(title.timeCreate[0])) - template = template.replace("$M", str(title.timeCreate[1])) - template = template.replace("$D", str(title.timeCreate[2])) - timestring = "%d:%02d" % (title.timeCreate[3], title.timeCreate[4]) - template = template.replace("$T", timestring) - else: - template = template.replace("$Y", "").replace("$M", "").replace("$D", "").replace("$T", "") - return template.decode("utf-8") - class ImagingPostcondition(Condition): def check(self, task): return task.returncode == 0 @@ -518,14 +511,13 @@ class MenuImageTask(Task): menu_end_title = nr_titles+1 menu_i = 0 for title_no in range( menu_start_title , menu_end_title ): - i = title_no-1 - top = s_top + ( menu_i * rowheight ) menu_i += 1 - title = self.job.project.titles[i] - titleText = formatTitle(s.titleformat.getValue(), title, title_no) + title = self.job.project.titles[title_no-1] + top = s_top + ( menu_i * rowheight ) + titleText = title.formatDVDmenuText(s.titleformat.getValue(), title_no).decode("utf-8") draw_bg.text((s_left,top), titleText, fill=self.Menus.color_button, font=fonts[1]) draw_high.text((s_left,top), titleText, fill=1, font=self.Menus.fonts[1]) - subtitleText = formatTitle(s.subtitleformat.getValue(), title, title_no) + subtitleText = title.formatDVDmenuText(s.subtitleformat.getValue(), title_no).decode("utf-8") draw_bg.text((s_left,top+36), subtitleText, fill=self.Menus.color_button, font=fonts[2]) bottom = top+rowheight if bottom > self.Menus.imgheight: @@ -607,7 +599,7 @@ class Menus: menuoutputfilename = job.workspace+"/dvdmenu"+num+".mpg" spumuxTask(job, spuxmlfilename, menubgmpgfilename, menuoutputfilename) -def CreateAuthoringXML(job): +def CreateAuthoringXML_singleset(job): nr_titles = len(job.project.titles) mode = job.project.settings.authormode.getValue() authorxml = [] @@ -649,9 +641,7 @@ def CreateAuthoringXML(job): authorxml.append(' </menus>\n') authorxml.append(' <titles>\n') for i in range( nr_titles ): - #for audiotrack in job.project.titles[i].audiotracks: - #authorxml.append(' <audio lang="'+audiotrack[0][:2]+'" format="'+audiotrack[1]+'" />\n') - chapters = ','.join(["%d:%02d:%02d.%03d" % (p / (90000 * 3600), p % (90000 * 3600) / (90000 * 60), p % (90000 * 60) / 90000, (p % 90000) / 90) for p in job.project.titles[i].chaptermarks]) + chapters = ','.join(job.project.titles[i].getChapterMarks()) title_no = i+1 title_filename = job.workspace + "/dvd_title_%d.mpg" % (title_no) if job.menupreview: @@ -677,6 +667,84 @@ def CreateAuthoringXML(job): f.write(x) f.close() +def CreateAuthoringXML_multiset(job): + nr_titles = len(job.project.titles) + mode = job.project.settings.authormode.getValue() + authorxml = [] + authorxml.append('<?xml version="1.0" encoding="utf-8"?>\n') + authorxml.append(' <dvdauthor dest="' + (job.workspace+"/dvd") + '" jumppad="yes">\n') + authorxml.append(' <vmgm>\n') + authorxml.append(' <menus>\n') + authorxml.append(' <video aspect="4:3"/>\n') + if mode.startswith("menu"): + for menu_count in range(1 , job.nr_menus+1): + authorxml.append(' <pgc>\n') + menu_start_title = (menu_count-1)*job.titles_per_menu + 1 + menu_end_title = (menu_count)*job.titles_per_menu + 1 + if menu_end_title > nr_titles: + menu_end_title = nr_titles+1 + for i in range( menu_start_title , menu_end_title ): + authorxml.append(' <button name="button' + (str(i).zfill(2)) + '"> jump titleset ' + str(i) +' title 1; </button>\n') + if menu_count > 1: + authorxml.append(' <button name="button_prev"> jump menu ' + str(menu_count-1) + '; </button>\n') + if menu_count < job.nr_menus: + authorxml.append(' <button name="button_next"> jump menu ' + str(menu_count+1) + '; </button>\n') + menuoutputfilename = job.workspace+"/dvdmenu"+str(menu_count)+".mpg" + authorxml.append(' <vob file="' + menuoutputfilename + '" pause="inf"/>\n') + authorxml.append(' </pgc>\n') + else: + authorxml.append(' <pgc>\n') + authorxml.append(' <vob file="' + job.project.settings.vmgm.getValue() + '" />\n' ) + authorxml.append(' <post> jump titleset 1 title 1; </post>\n') + authorxml.append(' </pgc>\n') + authorxml.append(' </menus>\n') + authorxml.append(' </vmgm>\n') + + for i in range( nr_titles ): + title = job.project.titles[i] + authorxml.append(' <titleset>\n') + authorxml.append(' <titles>\n') + for audiotrack in title.properties.audiotracks: + active = audiotrack.active.getValue() + if active: + format = audiotrack.format.getValue() + language = audiotrack.language.getValue() + audio_tag = ' <audio format="%s"' % format + if language != "nolang": + audio_tag += ' lang="%s"' % language + audio_tag += ' />\n' + authorxml.append(audio_tag) + aspect = title.properties.aspect.getValue() + video_tag = ' <video aspect="'+aspect+'"' + if title.properties.widescreen.getValue() == "4:3": + video_tag += ' widescreen="'+title.properties.widescreen.getValue()+'"' + video_tag += ' />\n' + authorxml.append(video_tag) + chapters = ','.join(title.getChapterMarks()) + title_no = i+1 + title_filename = job.workspace + "/dvd_title_%d.mpg" % (title_no) + if job.menupreview: + LinkTS(job, job.project.settings.vmgm.getValue(), title_filename) + else: + MakeFifoNode(job, title_no) + if mode.endswith("linked") and title_no < nr_titles: + post_tag = "jump titleset %d title 1;" % ( title_no+1 ) + elif mode.startswith("menu"): + post_tag = "call vmgm menu 1;" + else: post_tag = "" + + authorxml.append(' <pgc>\n') + authorxml.append(' <vob file="' + title_filename + '" chapters="' + chapters + '" />\n') + authorxml.append(' <post> ' + post_tag + ' </post>\n') + authorxml.append(' </pgc>\n') + authorxml.append(' </titles>\n') + authorxml.append(' </titleset>\n') + authorxml.append(' </dvdauthor>\n') + f = open(job.workspace+"/dvdauthor.xml", "w") + for x in authorxml: + f.write(x) + f.close() + def getISOfilename(isopath, volName): from Tools.Directories import fileExists i = 0 @@ -703,7 +771,10 @@ class DVDJob(Job): CheckDiskspaceTask(self) if self.project.settings.authormode.getValue().startswith("menu") or self.menupreview: Menus(self) - CreateAuthoringXML(self) + if self.project.settings.titlesetmode.getValue() == "multi": + CreateAuthoringXML_multiset(self) + else: + CreateAuthoringXML_singleset(self) DVDAuthorTask(self) @@ -713,14 +784,14 @@ class DVDJob(Job): PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") else: for self.i in range(nr_titles): - title = self.project.titles[self.i] + self.title = self.project.titles[self.i] link_name = self.workspace + "/source_title_%d.ts" % (self.i+1) title_filename = self.workspace + "/dvd_title_%d.mpg" % (self.i+1) - LinkTS(self, title.inputfile, link_name) + LinkTS(self, self.title.inputfile, link_name) demux = DemuxTask(self, link_name) self.mplextask = MplexTask(self, outputfile=title_filename, demux_task=demux) self.mplextask.end = self.estimateddvdsize - RemoveESFiles(self, demux) + #RemoveESFiles(self, demux) WaitForResidentTasks(self) PreviewTask(self, self.workspace + "/dvd/VIDEO_TS/") output = self.project.settings.output.getValue() diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py index 7491e046..b77383cf 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py +++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py @@ -148,8 +148,9 @@ class ProjectSettings(Screen,ConfigListScreen): self.list.append(getConfigListEntry(_("Menu")+' '+_("spaces (top, between rows, left)"), self.settings.space)) self.list.append(getConfigListEntry(_("Menu")+' '+_("Audio"), self.settings.menuaudio)) if authormode != "data_ts": - self.list.append(getConfigListEntry(_("VMGM (intro trailer)"), self.settings.vmgm)) - self.list.append(getConfigListEntry(_("Auto chapter split every ? minutes (0=never)"), self.settings.autochapter)) + self.list.append(getConfigListEntry(_("Titleset mode"), self.settings.titlesetmode)) + if self.settings.titlesetmode.getValue() == "single" or authormode == "just_linked": + self.list.append(getConfigListEntry(_("VMGM (intro trailer)"), self.settings.vmgm)) else: self.list.append(getConfigListEntry(("DVD data format"), self.settings.dataformat)) @@ -158,13 +159,13 @@ class ProjectSettings(Screen,ConfigListScreen): def keyLeft(self): ConfigListScreen.keyLeft(self) key = self.keydict[self["config"].getCurrent()[1]] - if key == "authormode" or key == "output": + if key == "authormode" or key == "output" or key=="titlesetmode": self.initConfigList() def keyRight(self): ConfigListScreen.keyRight(self) key = self.keydict[self["config"].getCurrent()[1]] - if key == "authormode" or key == "output": + if key == "authormode" or key == "output" or key=="titlesetmode": self.initConfigList() def exit(self): diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py b/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py index 163269c7..210a3d58 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleCutter.py @@ -20,16 +20,31 @@ class TitleCutter(CutListEditor): audio = service and service.audioTracks() n = audio and audio.getNumberOfTracks() or 0 if n > 0: + from DVDTitle import ConfigFixedText + from TitleProperties import languageChoices + from Components.config import config, ConfigSubsection, ConfigSubList, ConfigSelection, ConfigYesNo + self.t.properties.audiotracks = ConfigSubList() for x in range(n): i = audio.getTrackInfo(x) - language = i.getLanguage() + DVB_lang = i.getLanguage() description = i.getDescription() + pid = str(i.getPID()) if description == "MPEG": description = "MP2" - self.t.audiotracks.append((language, description)) - print "[DVDBurn getAudioTracks]", self.t.audiotracks - self.t.sVideoType = service.info().getInfo(iServiceInformation.sVideoType) - print "[DVDBurn getVideoType]", self.t.sVideoType + print "[audiotrack] pid:", pid, "description:", description, "language:", DVB_lang + self.t.properties.audiotracks.append(ConfigSubsection()) + self.t.properties.audiotracks[-1].active = ConfigYesNo(default = True) + self.t.properties.audiotracks[-1].format = ConfigFixedText(description) + self.t.properties.audiotracks[-1].language = ConfigSelection(choices = languageChoices.choices, default=languageChoices.getLanguage(DVB_lang)) + self.t.properties.audiotracks[-1].pid = ConfigFixedText(pid) + self.t.properties.audiotracks[-1].DVB_lang = ConfigFixedText(DVB_lang) + sAspect = service.info().getInfo(iServiceInformation.sAspect) + if sAspect in ( 1, 2, 5, 6, 9, 0xA, 0xD, 0xE ): + aspect = "4:3" + else: + aspect = "16:9" + self.t.properties.aspect.setValue(aspect) + self.t.VideoType = service.info().getInfo(iServiceInformation.sVideoType) def exit(self): self.session.nav.stopService() diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 19380af4..345af877 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -1,4 +1,4 @@ -import DVDProject, TitleList, TitleCutter, ProjectSettings, DVDToolbox, Process +import DVDProject, TitleList, TitleCutter, TitleProperties, ProjectSettings, DVDToolbox, Process from Screens.Screen import Screen from Screens.ChoiceBox import ChoiceBox from Screens.InputBox import InputBox @@ -41,7 +41,7 @@ class TitleList(Screen, HelpableScreen): self["titleactions"] = HelpableActionMap(self, "DVDTitleList", { "addTitle": (self.addTitle, _("Add a new title"), _("Add title")), - "editTitle": (self.editTitle, _("Edit chapters of current title"), _("Edit title")), + "titleProperties": (self.titleProperties, _("Properties of current title"), _("Title properties")), "removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")), "settings": (self.settings, _("Collection settings"), _("Settings")), "burnProject": (self.burnProject, _("Burn DVD"), _("Burn DVD")), @@ -59,7 +59,7 @@ class TitleList(Screen, HelpableScreen): self["key_red"] = StaticText(_("Remove title")) self["key_green"] = StaticText(_("Add title")) - self["key_yellow"] = StaticText(_("Edit title")) + self["key_yellow"] = StaticText(_("Title properties")) self["key_blue"] = StaticText(_("Settings")) self["title_label"] = StaticText() @@ -78,40 +78,31 @@ class TitleList(Screen, HelpableScreen): def showMenu(self): menu = [] if self.project.settings.output.getValue() == "dvd": - menu.append((_("Burn DVD"), "burn")); + menu.append((_("Burn DVD"), self.burnProject)) elif self.project.settings.output.getValue() == "iso": - menu.append((_("Create DVD-ISO"), "burn")); - menu.append((_("Preview menu"), "previewMenu")); - menu.append((_("DVD media toolbox"), "toolbox")); - menu.append((_("Collection settings"), "settings")); - menu.append((_("Add a new title"), "addtitle")); - menu.append((_("Remove title"), "removetitle")); - menu.append((_("Edit chapters of current title"), "edittitle")); - menu.append((_("Burn existing image to DVD"), "burniso")); - menu.append((_("Exit"), "exit")); + menu.append((_("Create DVD-ISO"), self.burnProject)) + menu.append((_("Burn existing image to DVD"), self.selectImage)) + menu.append((_("DVD media toolbox"), self.toolbox)) + menu.append((_("Preview menu"), self.previewMenu)) + menu.append((_("Collection settings"), self.settings)) + menu.append((_("Reset and renumerate title names"), self.resetTitles)) + menu.append((_("Edit chapters of current title"), self.editTitle)) + menu.append((_("Properties of current title"), self.titleProperties)) + menu.append((_("Add a new title"), self.addTitle)) + menu.append((_("Remove title"), self.removeCurrentTitle)) + menu.append((_("Exit"), self.leave)) self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu) def menuCallback(self, choice): - if choice is None: - return - if choice[1] == "removetitle": - self.removeCurrentTitle() - elif choice[1] == "addtitle": - self.addTitle() - elif choice[1] == "edittitle": - self.editTitle() - elif choice[1] == "toolbox": - self.toolbox() - elif choice[1] == "settings": - self.settings() - elif choice[1] == "previewMenu": - self.previewMenu() - elif choice[1] == "burn": - self.burnProject() - elif choice[1] == "burniso": - self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings) - elif choice[1] == "exit": - self.leave() + if choice: + choice[1]() + + def titleProperties(self): + if self.getCurrentTitle(): + self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex()) + + def selectImage(self): + self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings) def newProject(self): self.project = DVDProject.DVDProject() @@ -197,10 +188,6 @@ class TitleList(Screen, HelpableScreen): job_manager.in_background = False self.session.openWithCallback(self.JobViewCB, JobView, job) else: - autochapter = self.project.settings.autochapter.getValue() - if autochapter > 0: - for title in self.project.titles: - title.produceAutoChapter(autochapter) job = Process.DVDJob(self.project) job_manager.AddJob(job) job_manager.in_background = False @@ -225,7 +212,7 @@ class TitleList(Screen, HelpableScreen): res = [ ] totalsize = 0 for title in self.project.titles: - a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 10, 500, 50, 0, RT_HALIGN_LEFT, title.name) ] + a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 10, 500, 50, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue()) ] res.append(a) totalsize += title.estimatedDiskspace self["titles"].list = res @@ -263,13 +250,21 @@ class TitleList(Screen, HelpableScreen): def titleEditDone(self, cutlist): t = self.current_edit_title + t.initDVDmenuText(self.project,len(self.project.titles)) t.cuesheet = cutlist t.produceFinalCuesheet() - if t.sVideoType != 0: + if t.VideoType != 0: self.session.openWithCallback(self.DVDformatCB,MessageBox,text = _("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a Dreambox format data DVD (which will not play in stand-alone DVD players) instead?"), type = MessageBox.TYPE_YESNO) else: self.updateTitleList() + def resetTitles(self): + count = 0 + for title in self.project.titles: + count += 1 + title.initDVDmenuText(self.project,count) + self.updateTitleList() + def DVDformatCB(self, answer): t = self.current_edit_title if answer == True: diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py new file mode 100644 index 00000000..d5ba6c16 --- /dev/null +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py @@ -0,0 +1,169 @@ +from Screens.Screen import Screen +from Screens.ChoiceBox import ChoiceBox +from Screens.InputBox import InputBox +from Screens.MessageBox import MessageBox +from Screens.HelpMenu import HelpableScreen +from Components.ActionMap import HelpableActionMap, ActionMap +from Components.Sources.List import List +from Components.Sources.StaticText import StaticText +from Components.Sources.Progress import Progress +from Components.FileList import FileList +from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT +from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS, SCOPE_HDD +from Components.config import config, getConfigListEntry, ConfigInteger, ConfigSubsection, ConfigSelection +from Components.ConfigList import ConfigListScreen +import DVDTitle + +class TitleProperties(Screen,ConfigListScreen): + skin = """ + <screen position="90,83" size="560,445" title="Properties of current title" > + <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" /> + <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" /> + <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" /> + <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" /> + <widget name="config" position="10,50" size="540,300" scrollbarMode="showOnDemand" /> + <widget source="serviceinfo_headline" render="Label" position="20,360" size="520,20" font="Regular;20" /> + <widget source="serviceinfo" render="Label" position="20,382" size="520,66" font="Regular;16" /> + </screen>""" + + def __init__(self, session, parent, project, title_idx): + Screen.__init__(self, session) + self.parent = parent + self.project = project + self.title_idx = title_idx + + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("OK")) + self["key_blue"] = StaticText(_("Edit Title")) + self["serviceinfo_headline"] = StaticText("DVB info:") + self["serviceinfo"] = StaticText() + + self.properties = project.titles[title_idx].properties + ConfigListScreen.__init__(self, []) + self.properties.crop = DVDTitle.ConfigFixedText("crop") + self.properties.autochapter.addNotifier(self.initConfigList) + self.properties.aspect.addNotifier(self.initConfigList) + for audiotrack in self.properties.audiotracks: + audiotrack.active.addNotifier(self.initConfigList) + + self.initConfigList() + + self["setupActions"] = ActionMap(["SetupActions", "ColorActions"], + { + "green": self.exit, + "red": self.cancel, + "blue": self.editTitle, + "cancel": self.cancel, + "ok": self.ok, + }, -2) + + def initConfigList(self, element=None): + try: + self.properties.position = ConfigInteger(default = self.title_idx+1, limits = (1, len(self.project.titles))) + title = self.project.titles[self.title_idx] + self.list = [] + self.list.append(getConfigListEntry("DVD " + _("Track"), self.properties.position)) + self.list.append(getConfigListEntry("DVD " + _("Title"), self.properties.menutitle)) + self.list.append(getConfigListEntry("DVD " + _("Description"), self.properties.menusubtitle)) + for audiotrack in self.properties.audiotracks: + DVB_aud = audiotrack.DVB_lang.getValue() or audiotrack.pid.getValue() + self.list.append(getConfigListEntry(_("burn audio track (%s)") % DVB_aud, audiotrack.active)) + if audiotrack.active.getValue(): + self.list.append(getConfigListEntry(_("audio track (%s) format") % DVB_aud, audiotrack.format)) + self.list.append(getConfigListEntry(_("audio track (%s) language") % DVB_aud, audiotrack.language)) + + self.list.append(getConfigListEntry("DVD " + _("Aspect Ratio"), self.properties.aspect)) + if self.properties.aspect.getValue() == "16:9": + self.list.append(getConfigListEntry("DVD " + "widescreen", self.properties.widescreen)) + else: + self.list.append(getConfigListEntry("DVD " + "widescreen", self.properties.crop)) + + infotext = _("Available format variables") + ":\n$i=" + _("Track") + ", $t=" + _("Title") + ", $d=" + _("Description") + ", $l=" + _("length") + ", $c=" + _("chapters") + ",\n" + _("Record") + " $T=" + _("Begin time") + ", $Y=" + _("year") + ", $M=" + _("month") + ", $D=" + _("day") + ",\n$A=" + _("audio tracks") + ", $C=" + _("Channel") + ", $f=" + _("filename") + self["info"] = StaticText(infotext) + + if len(title.chaptermarks) == 0: + self.list.append(getConfigListEntry(_("Auto chapter split every ? minutes (0=never)"), self.properties.autochapter)) + infotext = _("Title") + ': ' + title.DVBname + "\n" + _("Description") + ': ' + title.DVBdescr + "\n" + _("Channel") + ': ' + title.DVBchannel + chaptermarks = title.getChapterMarks(template="$h:$m:$s") + chapters_count = len(chaptermarks) + if chapters_count >= 1: + infotext += ', ' + str(chapters_count+1) + ' ' + _("chapters") + ' (' + infotext += ' / '.join(chaptermarks) + ')' + self["serviceinfo"].setText(infotext) + self["config"].setList(self.list) + except AttributeError: + pass + + def editTitle(self): + self.parent.editTitle() + self.initConfigList() + + def changedConfigList(self): + self.initConfigList() + + def exit(self): + self.applySettings() + self.close() + + def applySettings(self): + for x in self["config"].list: + x[1].save() + current_pos = self.title_idx+1 + new_pos = self.properties.position.getValue() + if new_pos != current_pos: + print "title got repositioned from ", current_pos, "to", new_pos + swaptitle = self.project.titles.pop(current_pos-1) + self.project.titles.insert(new_pos-1, swaptitle) + + def ok(self): + #key = self.keydict[self["config"].getCurrent()[1]] + #if key in self.project.filekeys: + #self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, key, self.settings) + pass + + def cancel(self): + self.close() + +from Tools.ISO639 import LanguageCodes +class LanguageChoices(): + def __init__(self): + from Components.Language import language as syslanguage + syslang = syslanguage.getLanguage()[:2] + self.langdict = { } + self.choices = [] + for key, val in LanguageCodes.iteritems(): + if len(key) == 2: + self.langdict[key] = val[0] + for key, val in self.langdict.iteritems(): + if key not in [syslang, 'en']: + self.langdict[key] = val + self.choices.append((key, val)) + self.choices.sort() + self.choices.insert(0,("nolang", ("unspecified"))) + self.choices.insert(1,(syslang, self.langdict[syslang])) + self.choices.insert(2,("en", self.langdict["en"])) + + def getLanguage(self, DVB_lang): + DVB_lang = DVB_lang.lower() + stripwords = ["stereo", "audio", "description", "2ch", "dolby digital"] + for word in stripwords: + DVB_lang = DVB_lang.replace(word,"").strip() + for key, val in LanguageCodes.iteritems(): + if DVB_lang.find(key.lower()) == 0: + if len(key) == 2: + return key + else: + DVB_lang = (LanguageCodes[key])[0] + elif DVB_lang.find(val[0].lower()) > -1: + if len(key) == 2: + return key + else: + DVB_lang = (LanguageCodes[key])[0] + for key, val in self.langdict.iteritems(): + if val == DVB_lang: + return key + return "nolang" + +languageChoices = LanguageChoices()
\ No newline at end of file diff --git a/lib/python/Plugins/Extensions/DVDBurn/keymap.xml b/lib/python/Plugins/Extensions/DVDBurn/keymap.xml index 13fa3ee0..e8bc1045 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/keymap.xml +++ b/lib/python/Plugins/Extensions/DVDBurn/keymap.xml @@ -2,7 +2,7 @@ <map context="DVDTitleList"> <key id="KEY_RED" mapto="removeCurrentTitle" flags="m" /> <key id="KEY_GREEN" mapto="addTitle" flags="m" /> - <key id="KEY_YELLOW" mapto="editTitle" flags="m" /> + <key id="KEY_YELLOW" mapto="titleProperties" flags="m" /> <key id="KEY_BLUE" mapto="settings" flags="m" /> <key id="KEY_RECORD" mapto="burnProject" flags="m" /> <key id="KEY_0" mapto="burnProject" flags="m" /> diff --git a/lib/python/Plugins/Extensions/DVDBurn/plugin.py b/lib/python/Plugins/Extensions/DVDBurn/plugin.py index b658d804..29076cea 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/plugin.py +++ b/lib/python/Plugins/Extensions/DVDBurn/plugin.py @@ -12,5 +12,5 @@ def main_add(session, service, **kwargs): dvdburn.selectedSource(service) def Plugins(**kwargs): - return [PluginDescriptor(name="DVD Burn", description=_("Burn to DVD..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main_add), - PluginDescriptor(name="DVD Burn", description=_("Burn to DVD..."), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main) ] + return [PluginDescriptor(name="DVD Burn", description=_("Burn to DVD..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main_add, icon="dvdburn.png"), + PluginDescriptor(name="DVD Burn", description=_("Burn to DVD..."), where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main, icon="dvdburn.png") ] diff --git a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py index 4298642c..cb5f0e0d 100644 --- a/lib/python/Plugins/Extensions/DVDPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/DVDPlayer/plugin.py @@ -371,13 +371,25 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP if retval > 0: self.zapToNumber(retval) + def getServiceInterface(self, iface): + service = self.service + if service: + attr = getattr(service, iface, None) + if callable(attr): + return attr() + return None + def __serviceStopped(self): self.dvdScreen.hide() - self.service.subtitle().disableSubtitles(self.session.current_dialog.instance) + subs = self.getServiceInterface("subtitle") + if subs: + subs.disableSubtitles(self.session.current_dialog.instance) def serviceStarted(self): #override InfoBarShowHide function self.dvdScreen.show() - self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None) + subs = self.getServiceInterface("subtitle") + if subs: + subs.enableSubtitles(self.dvdScreen.instance, None) def doEofInternal(self, playing): if self.in_menu: @@ -435,17 +447,19 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP print "StringAvail" def __osdAudioInfoAvail(self): - audioTuple = self.service.info().getInfoObject(iServiceInformation.sUser+6) + info = self.getServiceInterface("info") + audioTuple = info and info.getInfoObject(iServiceInformation.sUser+6) print "AudioInfoAvail ", repr(audioTuple) if audioTuple: audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2]) self["audioLabel"].setText(audioString) if audioTuple != self.last_audioTuple and not self.in_menu: self.doShow() - self.last_audioTuple = audioTuple + self.last_audioTuple = audioTuple def __osdSubtitleInfoAvail(self): - subtitleTuple = self.service.info().getInfoObject(iServiceInformation.sUser+7) + info = self.getServiceInterface("info") + subtitleTuple = info and info.getInfoObject(iServiceInformation.sUser+7) print "SubtitleInfoAvail ", repr(subtitleTuple) if subtitleTuple: subtitleString = "" @@ -454,21 +468,25 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP self["subtitleLabel"].setText(subtitleString) if subtitleTuple != self.last_subtitleTuple and not self.in_menu: self.doShow() - self.last_subtitleTuple = subtitleTuple + self.last_subtitleTuple = subtitleTuple def __chapterUpdated(self): - self.currentChapter = self.service.info().getInfo(iServiceInformation.sCurrentChapter) - self.totalChapters = self.service.info().getInfo(iServiceInformation.sTotalChapters) - self.setChapterLabel() - print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters) + info = self.getServiceInterface("info") + if info: + self.currentChapter = info.getInfo(iServiceInformation.sCurrentChapter) + self.totalChapters = info.getInfo(iServiceInformation.sTotalChapters) + self.setChapterLabel() + print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters) def __titleUpdated(self): - self.currentTitle = self.service.info().getInfo(iServiceInformation.sCurrentTitle) - self.totalTitles = self.service.info().getInfo(iServiceInformation.sTotalTitles) - self.setChapterLabel() - print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles) - if not self.in_menu: - self.doShow() + info = self.getServiceInterface("info") + if info: + self.currentTitle = info.getInfo(iServiceInformation.sCurrentTitle) + self.totalTitles = info.getInfo(iServiceInformation.sTotalTitles) + self.setChapterLabel() + print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles) + if not self.in_menu: + self.doShow() def askLeavePlayer(self): choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")] @@ -476,73 +494,65 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP choices.insert(1,(_("Return to file browser"), "browser")) self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices) + def sendKey(self, key): + keys = self.getServiceInterface("keys") + if keys: + keys.keyPressed(key) + return keys + def nextAudioTrack(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser) + self.sendKey(iServiceKeys.keyUser) def nextSubtitleTrack(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+1) + self.sendKey(iServiceKeys.keyUser+1) def enterDVDAudioMenu(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+2) + self.sendKey(iServiceKeys.keyUser+2) def nextChapter(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+3) + self.sendKey(iServiceKeys.keyUser+3) def prevChapter(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+4) + self.sendKey(iServiceKeys.keyUser+4) def nextTitle(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+5) + self.sendKey(iServiceKeys.keyUser+5) def prevTitle(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+6) + self.sendKey(iServiceKeys.keyUser+6) def enterDVDMenu(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUser+7) + self.sendKey(iServiceKeys.keyUser+7) def seekBeginning(self): if self.service: seekable = self.getSeek() - if seekable is not None: + if seekable: seekable.seekTo(0) def zapToNumber(self, number): if self.service: seekable = self.getSeek() - if seekable is not None: + if seekable: print "seek to chapter %d" % number seekable.seekChapter(number) # MENU ACTIONS def keyRight(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyRight) + self.sendKey(iServiceKeys.keyRight) def keyLeft(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyLeft) + self.sendKey(iServiceKeys.keyLeft) def keyUp(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyUp) + self.sendKey(iServiceKeys.keyUp) def keyDown(self): - if self.service: - self.service.keys().keyPressed(iServiceKeys.keyDown) + self.sendKey(iServiceKeys.keyDown) def keyOk(self): - if self.service: - if not self.in_menu: - self.toggleInfo() - self.service.keys().keyPressed(iServiceKeys.keyOk) + if self.sendKey(iServiceKeys.keyOk) and not self.in_menu: + self.toggleInfo() def keyCancel(self): self.askLeavePlayer() @@ -606,9 +616,10 @@ class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarP def playLastCB(self, answer): # overwrite infobar cuesheet function print "playLastCB", answer, self.resume_point if self.service: - seek = self.service.seek() if answer == True: - seek.seekTo(self.resume_point) + seekable = self.getSeek() + if seekable: + seekable.seekTo(self.resume_point) pause = self.service.pause() pause.unpause() self.hideAfterResume() diff --git a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py index 7afbe14a..21d1bfe8 100644 --- a/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py +++ b/lib/python/Plugins/Extensions/GraphMultiEPG/plugin.py @@ -93,4 +93,4 @@ def main(session, servicelist, **kwargs): def Plugins(**kwargs): name = _("Graphical Multi EPG") descr = _("A graphical EPG for all services of an specific bouquet") - return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main) ] + return [ PluginDescriptor(name=name, description=descr, where = PluginDescriptor.WHERE_EVENTINFO, fnc=main) ] diff --git a/lib/python/Plugins/Extensions/MediaPlayer/Makefile.am b/lib/python/Plugins/Extensions/MediaPlayer/Makefile.am index e4ec5748..123df22d 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/Makefile.am +++ b/lib/python/Plugins/Extensions/MediaPlayer/Makefile.am @@ -1,5 +1,4 @@ installdir = $(LIBDIR)/enigma2/python/Plugins/Extensions/MediaPlayer install_PYTHON = \ - __init__.py \ - plugin.py + __init__.py plugin.py settings.py diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index ed1a8874..0d5305d7 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -1,25 +1,27 @@ from os import path as os_path, remove as os_remove, listdir as os_listdir from time import strftime -from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation +from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, loadPic +from ServiceReference import ServiceReference from Screens.Screen import Screen +from Screens.HelpMenu import HelpableScreen from Screens.MessageBox import MessageBox from Screens.InputBox import InputBox +from Screens.ChoiceBox import ChoiceBox +from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport from Components.ActionMap import NumberActionMap, HelpableActionMap from Components.Label import Label from Components.Pixmap import Pixmap,MultiPixmap -from Components.Label import Label from Components.FileList import FileList from Components.MediaPlayer import PlayList -from Tools.Directories import resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE from Components.ServicePosition import ServicePositionGauge from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS -from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport -from ServiceReference import ServiceReference -from Screens.ChoiceBox import ChoiceBox -from Screens.HelpMenu import HelpableScreen +from Components.AVSwitch import AVSwitch from Components.Harddisk import harddiskmanager -from Tools.Directories import fileExists, pathExists +from Components.config import config +from Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE +from settings import MediaPlayerSettings +from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier import random class MyPlayList(PlayList): @@ -42,6 +44,7 @@ class MediaPixmap(Pixmap): break if self.default_pixmap is None: self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png") + self.coverFileNames = ["folder.png", "folder.jpg"] return Pixmap.applySkin(self, desktop, screen) class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen): @@ -66,7 +69,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.addPlaylistParser(PlaylistIOInternal, "e2pls") # 'None' is magic to start at the list of mountpoints - self.filelist = FileList(None, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") + defaultDir = config.mediaplayer.defaultDir.getValue() + self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() @@ -92,8 +96,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self["coverArt"] = MediaPixmap() self["repeat"] = MultiPixmap() - self.repeat = False self.seek_target = None + hotplugNotifier.append(self.hotplugCB) class MoviePlayerActionMap(NumberActionMap): def __init__(self, player, contexts = [ ], actions = { }, prio=0): @@ -169,7 +173,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.coverArtFileName = "" self.isAudioCD = False self.AudioCD_albuminfo = {} - self.savePlaylistOnExit = True + self.cdAudioTrackFiles = [] + self.applySettings() self.playlistIOInternal = PlaylistIOInternal() list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) @@ -192,16 +197,16 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB return MediaPlayerLCDScreen def exit(self): - self.session.openWithCallback(self.exitCB, MessageBox, _("Do you really want to exit?"), timeout=5) - - def exitCB(self, answer): - if answer == True: - self.playlistIOInternal.clear() - for x in self.playlist.list: - self.playlistIOInternal.addService(ServiceReference(x[0])) - if self.savePlaylistOnExit: - self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) - self.close() + self.playlistIOInternal.clear() + for x in self.playlist.list: + self.playlistIOInternal.addService(ServiceReference(x[0])) + if self.savePlaylistOnExit: + self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) + if config.mediaplayer.saveDirOnExit.getValue(): + config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory()) + config.mediaplayer.defaultDir.save() + hotplugNotifier.remove(self.hotplugCB) + self.close() def checkSkipShowHideLock(self): self.updatedSeekState() @@ -283,13 +288,15 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def updateCoverArtPixmap(self, path): while not path.endswith("/"): path = path[:-1] - pngname = path + "folder.png" - - if not fileExists(pngname): - pngname = self["coverArt"].default_pixmap - if self.coverArtFileName != pngname: - self.coverArtFileName = pngname - self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName) + new_coverArtFileName = self["coverArt"].default_pixmap + for filename in self["coverArt"].coverFileNames: + if fileExists(path + filename): + new_coverArtFileName = path + filename + if self.coverArtFileName != new_coverArtFileName: + self.coverArtFileName = new_coverArtFileName + pixmap = loadPic(self.coverArtFileName, 116, 116, AVSwitch().getAspectRatioSetting()/2,1,0,0) + if pixmap is not None: + self["coverArt"].instance.setPixmap(pixmap.__deref__()) def leftDown(self): self.lefttimer = True @@ -441,27 +448,25 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def showMenu(self): menu = [] + if len(self.cdAudioTrackFiles): + menu.insert(0,(_("Play Audio-CD..."), "audiocd")) if self.currList == "filelist": if self.filelist.canDescent(): menu.append((_("add directory to playlist"), "copydir")) else: menu.append((_("add files to playlist"), "copyfiles")) menu.append((_("switch to playlist"), "playlist")) + menu.append((_("delete file"), "deletefile")) else: menu.append((_("switch to filelist"), "filelist")) - menu.append((_("shuffle playlist"), "shuffle")) - - menu.append((_("delete"), "delete")) + menu.append((_("Delete entry"), "deleteentry")) menu.append((_("clear playlist"), "clear")) menu.append((_("hide player"), "hide")); menu.append((_("save playlist"), "saveplaylist")); menu.append((_("load playlist"), "loadplaylist")); menu.append((_("delete saved playlist"), "deleteplaylist")); - menu.append((_("repeat playlist"), "repeat")); - drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) - if pathExists(drivepath): - menu.insert(0,(_("Play Audio-CD..."), "audiocd")) + menu.append((_("Edit settings"), "settings")) self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu) def menuCallback(self, choice): @@ -473,20 +478,19 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB elif choice[1] == "copyfiles": self.stopEntry() self.playlist.clear() + self.isAudioCD = False self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False) self.playServiceRefEntry(self.filelist.getServiceRef()) elif choice[1] == "playlist": self.switchToPlayList() elif choice[1] == "filelist": self.switchToFileList() - elif choice[1] == "delete": + elif choice[1] == "deleteentry": if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex(): self.stopEntry() self.deleteEntry() elif choice[1] == "clear": - self.stopEntry() - self.playlist.clear() - self.switchToFileList() + self.clear_playlist() elif choice[1] == "hide": self.hide() elif choice[1] == "saveplaylist": @@ -497,24 +501,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.delete_saved_playlist() elif choice[1] == "shuffle": self.playlist.PlayListShuffle() - elif choice[1] == "repeat": - if self.repeat == True: - self.repeat = False - self["repeat"].setPixmapNum(0) - else: - self.repeat = True - self["repeat"].setPixmapNum(1) + elif choice[1] == "deletefile": + self.deleteFile() + elif choice[1] == "settings": + self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self) elif choice[1] == "audiocd": - from Components.Scanner import scanDevice - drivepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) - self.cdAudioTrackFiles = [] - res = scanDevice(drivepath) - list = [ (r.description, r, res[r], self.session) for r in res ] - if list: - (desc, scanner, files, session) = list[0] - for file in files: - if file.mimetype == "audio/x-cda": - self.cdAudioTrackFiles.append(file.path) self.playAudioCD() def playAudioCD(self): @@ -533,6 +524,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.changeEntry(0) self.switchToPlayList() + def applySettings(self): + self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue() + if config.mediaplayer.repeat.getValue() == True: + self["repeat"].setPixmapNum(1) + else: + self["repeat"].setPixmapNum(0) + def showEventInformation(self): from Screens.EventView import EventViewSimple from ServiceReference import ServiceReference @@ -617,9 +615,14 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def deleteConfirmed(self, confirmed): if confirmed: - os_remove(self.delname) + try: + os_remove(self.delname) + except OSError,e: + print "delete failed:", e + self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR) def clear_playlist(self): + self.isAudioCD = False self.stopEntry() self.playlist.clear() self.switchToFileList() @@ -632,20 +635,78 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB if x[0][1] == True: #isDir if recursive: self.copyDirectory(x[0][0]) - else: + elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097: self.playlist.addFile(x[0][0]) self.playlist.updateList() + def deleteFile(self): + if self.currList == "filelist": + self.service = self.filelist.getServiceRef() + else: + self.service = self.playlist.getSelection() + if self.service is None: + return + if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None: + if self.service == self.session.nav.getCurrentlyPlayingServiceReference(): + self.stopEntry() + + serviceHandler = eServiceCenter.getInstance() + offline = serviceHandler.offlineOperations(self.service) + info = serviceHandler.info(self.service) + name = info and info.getName(self.service) + result = False + if offline is not None: + # simulate first + if not offline.deleteFromDisk(1): + result = True + if result == True: + self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name)) + else: + self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR) + + def deleteConfirmed_offline(self, confirmed): + if confirmed: + serviceHandler = eServiceCenter.getInstance() + offline = serviceHandler.offlineOperations(self.service) + result = False + if offline is not None: + # really delete! + if not offline.deleteFromDisk(0): + result = True + if result == False: + self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR) + else: + self.removeListEntry() + + def removeListEntry(self): + currdir = self.filelist.getCurrentDirectory() + self.filelist.changeDir(currdir) + deleteend = False + while not deleteend: + index = 0 + deleteend = True + if len(self.playlist) > 0: + for x in self.playlist.list: + if self.service == x[0]: + self.playlist.deleteFile(index) + deleteend = False + break + index += 1 + self.playlist.updateList() + if self.currList == "playlist": + if len(self.playlist) == 0: + self.switchToFileList() + def copyFile(self): if self.filelist.getServiceRef().type == 4098: # playlist ServiceRef = self.filelist.getServiceRef() extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:] - print "extension:", extension if self.playlistparsers.has_key(extension): playlist = self.playlistparsers[extension]() list = playlist.open(ServiceRef.getPath()) for x in list: self.playlist.addFile(x.ref) + self.playlist.updateList() else: self.playlist.addFile(self.filelist.getServiceRef()) self.playlist.updateList() @@ -659,7 +720,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB next = self.playlist.getCurrentIndex() + 1 if next < len(self.playlist): self.changeEntry(next) - elif ( len(self.playlist) > 0 ) and ( self.repeat == True ): + elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ): self.stopEntry() self.changeEntry(0) @@ -700,6 +761,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB else: self.stopEntry() self.playlist.clear() + self.isAudioCD = False sel = self.filelist.getSelection() if sel: if sel[1]: # can descent @@ -762,7 +824,8 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.unPauseService() if needsInfoUpdate == True: - self.updateCoverArtPixmap(currref.getPath()) + path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath() + self.updateCoverArtPixmap(path) else: pngname = self["coverArt"].default_pixmap self.coverArtFileName = pngname @@ -797,7 +860,20 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def subtitleSelection(self): from Screens.Subtitles import Subtitles - self.session.open(Subtitles) + self.session.open(Subtitles) + + def hotplugCB(self, dev, media_state): + if dev == harddiskmanager.getCD(): + from Components.Scanner import scanDevice + devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) + self.cdAudioTrackFiles = [] + res = scanDevice(devpath) + list = [ (r.description, r, res[r], self.session) for r in res ] + if list: + (desc, scanner, files, session) = list[0] + for file in files: + if file.mimetype == "audio/x-cda": + self.cdAudioTrackFiles.append(file.path) class MediaPlayerLCDScreen(Screen): skin = """ @@ -814,7 +890,6 @@ class MediaPlayerLCDScreen(Screen): self["text4"] = Label("") def setText(self, text, line): - print "lcd set text:", text, line if len(text) > 10: if text[-4:] == ".mp3": text = text[:-4] diff --git a/lib/python/Plugins/Extensions/MediaPlayer/settings.py b/lib/python/Plugins/Extensions/MediaPlayer/settings.py new file mode 100644 index 00000000..c6d274bd --- /dev/null +++ b/lib/python/Plugins/Extensions/MediaPlayer/settings.py @@ -0,0 +1,137 @@ +from Screens.Screen import Screen +from Screens.HelpMenu import HelpableScreen +from Components.Label import Label +from Components.FileList import FileList +from Components.MediaPlayer import PlayList +from Components.config import config, getConfigListEntry, ConfigSubsection, configfile, ConfigText, ConfigYesNo +from Components.ConfigList import ConfigListScreen +from Components.ActionMap import ActionMap + +class ConfigDirectory(ConfigText): + def __init__(self, default="", visible_width=60): + ConfigText.__init__(self, default, fixed_size = True, visible_width = visible_width) + def handleKey(self, key): + pass + def getValue(self): + if self.text == "": + return None + else: + return ConfigText.getValue(self) + def setValue(self, val): + if val == None: + val = "" + ConfigText.setValue(self, val) + def getMulti(self, selected): + if self.text == "": + return ("mtext"[1-selected:], _("List of Storage Devices"), range(0)) + else: + return ConfigText.getMulti(self, selected) + +config.mediaplayer = ConfigSubsection() +config.mediaplayer.repeat = ConfigYesNo(default=False) +config.mediaplayer.savePlaylistOnExit = ConfigYesNo(default=True) +config.mediaplayer.saveDirOnExit = ConfigYesNo(default=False) +config.mediaplayer.defaultDir = ConfigDirectory() + +class DirectoryBrowser(Screen, HelpableScreen): + skin = """ + <screen name="DirectoryBrowser" position="160,62" size="450,376" title="Directory browser" > + <ePixmap pixmap="skin_default/buttons/red.png" position="10,0" size="140,40" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/green.png" position="300,0" size="140,40" alphatest="on" /> + <widget source="key_red" render="Label" position="10,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" /> + <widget source="key_green" render="Label" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" /> + <widget name="filelist" position="0,44" size="440,322" scrollbarMode="showOnDemand" /> + </screen>""" + def __init__(self, session, currDir): + from Components.Sources.StaticText import StaticText + Screen.__init__(self, session) + HelpableScreen.__init__(self) + + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Use")) + + self.filelist = FileList(currDir, matchingPattern="") + self["filelist"] = self.filelist + + self["FilelistActions"] = ActionMap(["SetupActions", "ColorActions"], + { + "green": self.use, + "red": self.exit, + "ok": self.ok, + "cancel": self.exit + }) + + def ok(self): + if self.filelist.canDescent(): + self.filelist.descent() + + def use(self): + if self.filelist.canDescent() and len(self["filelist"].getFilename()) > len(self["filelist"].getCurrentDirectory()): + self.filelist.descent() + self.close(self["filelist"].getCurrentDirectory()) + + def exit(self): + self.close(False) + +class MediaPlayerSettings(Screen,ConfigListScreen): + skin = """ + <screen name="MediaPlayerSettings" position="160,150" size="450,200" title="Edit settings"> + <ePixmap pixmap="skin_default/buttons/red.png" position="10,0" size="140,40" alphatest="on" /> + <ePixmap pixmap="skin_default/buttons/green.png" position="300,0" size="140,40" alphatest="on" /> + <widget source="key_red" render="Label" position="10,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" /> + <widget source="key_green" render="Label" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" /> + <widget name="config" position="10,44" size="430,146" /> + </screen>""" + + def __init__(self, session, parent): + from Components.Sources.StaticText import StaticText + Screen.__init__(self, session) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Save")) + + ConfigListScreen.__init__(self, []) + self.parent = parent + self.initConfigList() + config.mediaplayer.saveDirOnExit.addNotifier(self.initConfigList) + + self["setupActions"] = ActionMap(["SetupActions", "ColorActions"], + { + "green": self.save, + "red": self.cancel, + "cancel": self.cancel, + "ok": self.ok, + }, -2) + + def initConfigList(self, element=None): + print "[initConfigList]", element + try: + self.list = [] + self.list.append(getConfigListEntry(_("repeat playlist"), config.mediaplayer.repeat)) + self.list.append(getConfigListEntry(_("save playlist on exit"), config.mediaplayer.savePlaylistOnExit)) + self.list.append(getConfigListEntry(_("save last directory on exit"), config.mediaplayer.saveDirOnExit)) + if not config.mediaplayer.saveDirOnExit.getValue(): + self.list.append(getConfigListEntry(_("start directory"), config.mediaplayer.defaultDir)) + self["config"].setList(self.list) + except KeyError: + print "keyError" + + def changedConfigList(self): + self.initConfigList() + + def ok(self): + if self["config"].getCurrent()[1] == config.mediaplayer.defaultDir: + self.session.openWithCallback(self.DirectoryBrowserClosed, DirectoryBrowser, self.parent.filelist.getCurrentDirectory()) + + def DirectoryBrowserClosed(self, path): + print "PathBrowserClosed:" + str(path) + if path != False: + config.mediaplayer.defaultDir.setValue(path) + + def save(self): + for x in self["config"].list: + x[1].save() + self.close() + + def cancel(self): + self.close() + diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index a9d61ed9..ea906f0d 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -155,7 +155,7 @@ class ThumbView(Screen): if not createDir(cachedir): cachefile = "" - ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1, cachefile) + ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value), 1, cachefile, 1) if ptr != None: self["thumb"+str(self.thumbindex)].show() self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr) @@ -486,7 +486,7 @@ class picmain(Screen): if not createDir(cachedir): cachefile = "" - ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile) + ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile, 1) if ptr != None: self["thumbnail"].show() self["thumbnail"].instance.setPixmap(ptr) diff --git a/lib/python/Plugins/Plugin.py b/lib/python/Plugins/Plugin.py index a0db1d66..6df4fce7 100644 --- a/lib/python/Plugins/Plugin.py +++ b/lib/python/Plugins/Plugin.py @@ -45,6 +45,10 @@ class PluginDescriptor: # or return a function which is called with session and the interface name for extended setup of this interface WHERE_NETWORKSETUP = 10 + # show up this plugin (or a choicebox with all of them) for long INFO keypress + # or return a function which is called with session and the interface name for extended setup of this interface + WHERE_EVENTINFO = 11 + def __init__(self, name = "Plugin", where = [ ], description = "", icon = None, fnc = None, wakeupfnc = None, internal = False): self.name = name self.internal = internal diff --git a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py index 469b1dd0..97ddf4a1 100644 --- a/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Hotplug/plugin.py @@ -8,6 +8,8 @@ DEVICEDB = \ "/devices/pci0000:00/0000:00:14.2/usb1/1-1/1-1:1.0/host0/target1:0:0/0:0:0:0": "SD Slot" } +hotplugNotifier = [ ] + class Hotplug(Protocol): def getUserfriendlyDeviceName(self, phys): return DEVICEDB.get(phys, "USB Storage") @@ -48,6 +50,12 @@ class Hotplug(Protocol): harddiskmanager.addHotplugPartition(dev, self.getUserfriendlyDeviceName(physdevpath)) elif media_state == '0': harddiskmanager.removeHotplugPartition(dev) + + for callback in hotplugNotifier: + try: + callback(dev, media_state) + except AttributeError: + hotplugNotifier.remove(callback) def autostart(reason, **kwargs): if reason == 0: diff --git a/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py b/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py index 7b3d08f6..ec223d3e 100644 --- a/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py +++ b/lib/python/Plugins/SystemPlugins/SatelliteEquipmentControl/plugin.py @@ -23,6 +23,8 @@ class SecParameterSetup(Screen, ConfigListScreen): Screen.__init__(self, session) list = [ + ("Delay after diseqc reset command", config.sec.delay_after_diseqc_reset_cmd), + ("Delay after diseqc peripherial poweron command", config.sec.delay_after_diseqc_peripherial_poweron_cmd), ("Delay after continuous tone change", config.sec.delay_after_continuous_tone_change), ("Delay after last voltage change", config.sec.delay_after_final_voltage_change), ("Delay between diseqc commands", config.sec.delay_between_diseqc_repeats), |
