1 import DVDProject, TitleList, TitleCutter, TitleProperties, ProjectSettings, DVDToolbox, Process
2 from Screens.Screen import Screen
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.InputBox import InputBox
5 from Screens.MessageBox import MessageBox
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.TaskView import JobView
8 from Components.Task import job_manager
9 from Components.ActionMap import HelpableActionMap, ActionMap
10 from Components.Sources.List import List
11 from Components.Sources.StaticText import StaticText
12 from Components.Sources.Progress import Progress
13 from Components.Label import Label
14 from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
15 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
17 class TitleList(Screen, HelpableScreen):
19 <screen position="90,83" size="560,445" title="DVD Tool" >
20 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
21 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
22 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
23 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
24 <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" />
25 <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" />
26 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
27 <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" />
28 <widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" />
29 <widget name="error_label" position="10,48" size="540,395" zPosition="3" font="Regular;20" />
30 <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="540,312">
31 <convert type="StaticMultiList" />
33 <widget source="space_bar" render="Progress" position="10,410" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
34 <widget source="space_label" render="Label" position="40,414" size="480,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
37 def __init__(self, session, project = None):
38 Screen.__init__(self, session)
39 HelpableScreen.__init__(self)
41 self["titleactions"] = HelpableActionMap(self, "DVDTitleList",
43 "addTitle": (self.addTitle, _("Add a new title"), _("Add title")),
44 "titleProperties": (self.titleProperties, _("Properties of current title"), _("Title properties")),
45 "removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")),
46 "settings": (self.settings, _("Collection settings"), _("Settings")),
47 "burnProject": (self.askBurnProject, _("Burn DVD"), _("Burn DVD")),
50 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
52 "contextMenu": (self.showMenu, _("menu")),
55 self["actions"] = ActionMap(["OkCancelActions"],
60 self["key_red"] = StaticText()
61 self["key_green"] = StaticText(_("Add title"))
62 self["key_yellow"] = StaticText()
63 self["key_blue"] = StaticText(_("Settings"))
65 self["title_label"] = StaticText()
66 self["error_label"] = Label("")
67 self["space_label"] = StaticText()
68 self["space_bar"] = Progress()
70 if project is not None:
71 self.project = project
75 self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)])
76 self.updateTitleList()
77 self.previous_size = 0
79 def checkBackgroundJobs(self):
80 for job in job_manager.getPendingJobs():
81 print "type(job):", type(job)
82 print "Process.DVDJob:", Process.DVDJob
83 if type(job) == Process.DVDJob:
84 self.backgroundJob = job
86 self.backgroundJob = None
90 self.checkBackgroundJobs()
91 if self.backgroundJob:
92 j = self.backgroundJob
93 menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
94 menu.append((_("DVD media toolbox"), self.toolbox))
95 menu.append((_("Preview menu"), self.previewMenu))
96 if self.project.settings.output.getValue() == "dvd":
97 if len(self["titles"].list):
98 menu.append((_("Burn DVD"), self.burnProject))
99 elif self.project.settings.output.getValue() == "iso":
100 menu.append((_("Create DVD-ISO"), self.burnProject))
101 menu.append((_("Burn existing image to DVD"), self.selectImage))
102 menu.append((_("Edit chapters of current title"), self.editTitle))
103 menu.append((_("Reset and renumerate title names"), self.resetTitles))
104 menu.append((_("Exit"), self.leave))
105 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
107 def menuCallback(self, choice):
111 def showBackgroundJob(self):
112 job_manager.in_background = False
113 self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob)
114 self.backgroundJob = None
116 def titleProperties(self):
117 if self.getCurrentTitle():
118 self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex())
120 def selectImage(self):
121 self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings)
123 def newProject(self):
124 self.project = DVDProject.DVDProject()
125 if self.loadTemplate():
126 self.project.session = self.session
130 from Screens.MovieSelection import MovieSelection
131 from Components.Button import Button
132 from Components.ActionMap import HelpableActionMap
133 class MovieSelectionNoMenu(MovieSelection):
134 def __init__(self, session):
135 MovieSelection.__init__(self, session)
136 self.skinName = "MovieSelection"
137 self["key_red"] = Button(_("Edit title"))
138 self["key_green"] = Button(_("Add"))
139 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
141 "red": (self.movieSelected, _("Add a new title")),
142 "green": (self.insertWithoutEdit, ("insert without cutlist editor"))
144 def updateTags(self):
147 print "context menu forbidden inside DVDBurn to prevent calling multiple instances"
148 def insertWithoutEdit(self):
149 current = self.getCurrent()
150 if current is not None:
153 def movieSelected(self):
154 current = self.getCurrent()
155 if current is not None:
158 self.session.openWithCallback(self.selectedSource, MovieSelectionNoMenu)
160 def selectedSource(self, source):
163 t = self.project.addService(source)
166 except AttributeError:
168 self.editTitle(t, editor)
170 def removeCurrentTitle(self):
171 title = self.getCurrentTitle()
172 self.removeTitle(title)
174 def removeTitle(self, title):
175 if title is not None:
176 self.project.titles.remove(title)
177 self.updateTitleList()
180 self.session.open(DVDToolbox.DVDToolbox)
183 self.session.openWithCallback(self.settingsCB, ProjectSettings.ProjectSettings, self.project)
185 def settingsCB(self, update=True):
188 self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
190 def loadTemplate(self):
191 filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
192 if self.project.load(filename):
193 self["error_label"].hide()
196 self["error_label"].text = self.project.error
197 self["error_label"].show()
200 def askBurnProject(self):
201 if len(self["titles"].list):
202 self.session.openWithCallback(self.burnProject,MessageBox,text = _("Do you want to burn this collection to DVD medium?"), type = MessageBox.TYPE_YESNO)
204 def burnProject(self, answer=True):
207 if self.project.settings.authormode.getValue() == "data_ts":
208 job = Process.DVDdataJob(self.project)
209 job_manager.AddJob(job)
210 job_manager.in_background = False
211 self.session.openWithCallback(self.JobViewCB, JobView, job)
213 job = Process.DVDJob(self.project)
214 job_manager.AddJob(job)
215 job_manager.in_background = False
216 self.session.openWithCallback(self.JobViewCB, JobView, job)
218 def burnISO(self, path, scope, configRef):
220 job = Process.DVDisoJob(self.project, path)
221 job_manager.AddJob(job)
222 job_manager.in_background = False
223 self.session.openWithCallback(self.JobViewCB, JobView, job)
225 def JobViewCB(self, in_background):
226 job_manager.in_background = in_background
228 def previewMenu(self):
229 job = Process.DVDJob(self.project, menupreview=True)
230 job_manager.in_background = False
231 job_manager.AddJob(job)
233 def updateTitleList(self):
235 for title in self.project.titles:
236 a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 5, 500, 25, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue()) ]
238 self["titles"].list = res
241 self["key_red"].text = _("Remove title")
242 self["key_yellow"].text = _("Title properties")
244 self["key_red"].text = ""
245 self["key_yellow"].text = ""
247 def updateSize(self):
248 size = self.project.size/(1024*1024)
249 MAX_DL = self.project.MAX_DL-100
250 MAX_SL = self.project.MAX_SL-100
251 print "updateSize:", size, "MAX_DL:", MAX_DL, "MAX_SL:", MAX_SL
253 percent = 100 * size / float(MAX_DL)
254 self["space_label"].text = "%d MB - " % size + _("exceeds dual layer medium!") + " (%.2f%% " % (100-percent) + _("free") + ")"
255 self["space_bar"].value = int(percent)
256 if self.previous_size < MAX_DL:
257 self.session.open(MessageBox,text = _("exceeds dual layer medium!"), type = MessageBox.TYPE_ERROR)
259 percent = 100 * size / float(MAX_DL)
260 self["space_label"].text = "%d MB " % size + _("of a DUAL layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
261 self["space_bar"].value = int(percent)
262 if self.previous_size < MAX_SL:
263 self.session.open(MessageBox,text = _("Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!"), type = MessageBox.TYPE_INFO)
265 percent = 100 * size / float(MAX_SL)
266 self["space_label"].text = "%d MB " % size + _("of a SINGLE layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
267 self["space_bar"].value = int(percent)
268 self.previous_size = size
270 def getCurrentTitle(self):
271 t = self["titles"].getCurrent()
274 def editTitle(self, title = None, editor = True):
275 t = title or self.getCurrentTitle()
277 self.current_edit_title = t
279 self.session.openWithCallback(self.titleEditDone, TitleCutter.TitleCutter, t)
281 self.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, t)
283 def titleEditDone(self, cutlist):
284 t = self.current_edit_title
285 t.initDVDmenuText(self.project,len(self.project.titles))
287 t.produceFinalCuesheet()
289 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)
291 self.updateTitleList()
293 def resetTitles(self):
295 for title in self.project.titles:
297 title.initDVDmenuText(self.project,count)
298 self.updateTitleList()
300 def DVDformatCB(self, answer):
301 t = self.current_edit_title
303 self.project.settings.authormode.setValue("data_ts")
304 self.updateTitleList()