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.MultiContent import MultiContentEntryText
14 from enigma import gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT
15 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
17 class TitleList(Screen, HelpableScreen):
19 <screen name="TitleList" position="center,center" size="560,470" 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;19" 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;19" 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;19" 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;19" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
28 <widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" transparent="1" />
29 <widget source="error_label" render="Label" position="10,48" size="540,296" zPosition="3" font="Regular;20" transparent="1" />
30 <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="546,296" zPosition="3" transparent="1" >
31 <convert type="TemplatedMultiContent">
33 MultiContentEntryText(pos = (0, 0), size = (420, 20), font = 0, flags = RT_HALIGN_LEFT, text = 1), # index 1 Title,
34 MultiContentEntryText(pos = (0, 20), size = (328, 17), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 description,
35 MultiContentEntryText(pos = (418, 6), size = (120, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 3), # index 3 channel,
36 MultiContentEntryText(pos = (326, 20), size = (154, 17), font = 1, flags = RT_HALIGN_RIGHT, text = 4), # index 4 begin time,
37 MultiContentEntryText(pos = (480, 20), size = (58, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 5), # index 5 duration,
39 "fonts": [gFont("Regular", 20), gFont("Regular", 14)],
44 <ePixmap pixmap="skin_default/div-h.png" position="0,390" zPosition="10" size="560,2" />
45 <ePixmap pixmap="skin_default/buttons/key_menu.png" position="10,394" size="35,25" alphatest="on" />
46 <widget source="hint" render="Label" position="50,396" size="540,22" font="Regular;18" halign="left" />
47 <widget source="medium" render="Label" position="10,420" size="540,22" font="Regular;18" halign="left" />
48 <widget source="space_bar_single" render="Progress" position="10,446" size="270,24" borderWidth="1" zPosition="2" backgroundColor="#254f7497" />
49 <widget source="space_label_single" render="Label" position="10,449" size="270,22" zPosition="3" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
50 <widget source="space_bar_dual" render="Progress" position="10,446" size="540,24" borderWidth="1" backgroundColor="#254f7497" />
51 <widget source="space_label_dual" render="Label" position="10,449" size="540,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
55 def __init__(self, session, project = None):
56 Screen.__init__(self, session)
57 HelpableScreen.__init__(self)
59 self["titleactions"] = HelpableActionMap(self, "DVDTitleList",
61 "addTitle": (self.addTitle, _("Add a new title"), _("Add title")),
62 "titleProperties": (self.titleProperties, _("Properties of current title"), _("Title properties")),
63 "removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")),
64 "settings": (self.settings, _("Collection settings"), _("Settings")),
65 "burnProject": (self.askBurnProject, _("Burn DVD"), _("Burn DVD")),
68 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
70 "contextMenu": (self.showMenu, _("menu")),
73 self["actions"] = ActionMap(["OkCancelActions"],
78 self["key_red"] = StaticText()
79 self["key_green"] = StaticText(_("Add title"))
80 self["key_yellow"] = StaticText()
81 self["key_blue"] = StaticText(_("Settings"))
83 self["title_label"] = StaticText()
84 self["error_label"] = StaticText()
85 self["space_label_single"] = StaticText()
86 self["space_label_dual"] = StaticText()
87 self["hint"] = StaticText(_("Advanced Options"))
88 self["medium"] = StaticText()
89 self["space_bar_single"] = Progress()
90 self["space_bar_dual"] = Progress()
92 self["titles"] = List([])
93 self.previous_size = 0
94 if project is not None:
95 self.project = project
98 self.onLayoutFinish.append(self.layoutFinished)
100 def layoutFinished(self):
101 self.setTitle(_("DVD Titlelist"))
103 def checkBackgroundJobs(self):
104 for job in job_manager.getPendingJobs():
105 print "type(job):", type(job)
106 print "Process.DVDJob:", Process.DVDJob
107 if type(job) == Process.DVDJob:
108 self.backgroundJob = job
110 self.backgroundJob = None
114 self.checkBackgroundJobs()
115 if self.backgroundJob:
116 j = self.backgroundJob
117 menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
118 menu.append((_("DVD media toolbox"), self.toolbox))
119 if self.project.settings.output.getValue() == "dvd":
120 if len(self["titles"].list):
121 menu.append((_("Burn DVD"), self.burnProject))
122 elif self.project.settings.output.getValue() == "iso":
123 menu.append((_("Create DVD-ISO"), self.burnProject))
124 menu.append((_("Burn existing image to DVD"), self.selectImage))
125 if len(self["titles"].list):
126 menu.append((_("Preview menu"), self.previewMenu))
127 menu.append((_("Edit chapters of current title"), self.editTitle))
128 menu.append((_("Reset and renumerate title names"), self.resetTitles))
129 menu.append((_("Exit"), self.leave))
130 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
132 def menuCallback(self, choice):
136 def showBackgroundJob(self):
137 job_manager.in_background = False
138 self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob)
139 self.backgroundJob = None
141 def titleProperties(self):
142 if self.getCurrentTitle():
143 self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex())
145 def selectImage(self):
146 self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings)
148 def newProject(self):
149 self.project = DVDProject.DVDProject()
150 if self.loadTemplate():
151 self.project.session = self.session
155 from Screens.MovieSelection import MovieSelection
156 from Components.ActionMap import HelpableActionMap
157 class DVDMovieSelection(MovieSelection):
158 skin = """<screen name="DVDMovieSelection" position="center,center" size="560,445" title="Select a movie">
159 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
160 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
161 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
162 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
163 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
164 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;19" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
165 <widget name="waitingtext" position="0,45" size="560,395" zPosition="4" font="Regular;22" halign="center" valign="center" />
166 <widget name="list" position="5,40" size="550,375" zPosition="2" scrollbarMode="showOnDemand" />
167 <widget name="DescriptionBorder" pixmap="skin_default/border_eventinfo.png" position="0,316" zPosition="1" size="560,103" transparent="1" alphatest="on" />
168 <widget source="Service" render="Label" position="5,318" zPosition="1" size="480,35" font="Regular;17" foregroundColor="#cccccc">
169 <convert type="MovieInfo">ShortDescription</convert>
171 <widget source="Service" render="Label" position="495,318" zPosition="1" size="60,22" font="Regular;17" halign="right">
172 <convert type="ServiceTime">Duration</convert>
173 <convert type="ClockToText">AsLength</convert>
175 <widget source="Service" render="Label" position="380,337" zPosition="2" size="175,22" font="Regular;17" halign="right">
176 <convert type="MovieInfo">RecordServiceName</convert>
178 <widget source="Service" render="Label" position="5,357" zPosition="1" size="550,58" font="Regular;19">
179 <convert type="EventName">ExtendedDescription</convert>
181 <widget name="freeDiskSpace" position="10,425" size="540,20" font="Regular;19" valign="center" halign="right" />
183 def __init__(self, session):
184 MovieSelection.__init__(self, session)
185 self["key_red"] = StaticText(_("Close"))
186 self["key_green"] = StaticText(_("Add"))
187 self["key_yellow"] = StaticText(_("Edit title"))
188 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
190 "red": (self.close, _("Close title selection")),
191 "green": (self.insertWithoutEdit, ("insert without cutlist editor")),
192 "yellow": (self.movieSelected, _("Add a new title"))
194 def updateTags(self):
197 print "context menu forbidden inside DVDBurn to prevent calling multiple instances"
198 def insertWithoutEdit(self):
199 current = self.getCurrent()
200 if current is not None:
203 def movieSelected(self):
204 current = self.getCurrent()
205 if current is not None:
208 self.session.openWithCallback(self.selectedSource, DVDMovieSelection)
210 def selectedSource(self, source = None):
213 if not source.getPath().endswith(".ts"):
214 self.session.open(MessageBox,text = _("You can only burn Dreambox recordings!"), type = MessageBox.TYPE_ERROR)
216 t = self.project.addService(source)
219 except AttributeError:
221 self.editTitle(t, editor)
223 def removeCurrentTitle(self):
224 title = self.getCurrentTitle()
225 self.removeTitle(title)
227 def removeTitle(self, title):
228 if title is not None:
229 self.project.titles.remove(title)
230 self.updateTitleList()
233 self.session.open(DVDToolbox.DVDToolbox)
236 self.session.openWithCallback(self.settingsCB, ProjectSettings.ProjectSettings, self.project)
238 def settingsCB(self, update=True):
241 self.updateTitleList()
243 def loadTemplate(self):
244 filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
245 if self.project.load(filename):
246 self["error_label"].setText("")
249 self["error_label"].setText(self.project.error)
252 def askBurnProject(self):
253 if len(self["titles"].list):
254 self.session.openWithCallback(self.burnProject,MessageBox,text = _("Do you want to burn this collection to DVD medium?"), type = MessageBox.TYPE_YESNO)
256 def burnProject(self, answer=True):
259 if self.project.settings.authormode.getValue() == "data_ts":
260 job = Process.DVDdataJob(self.project)
261 job_manager.AddJob(job)
262 job_manager.in_background = False
263 self.session.openWithCallback(self.JobViewCB, JobView, job)
265 job = Process.DVDJob(self.project)
266 job_manager.AddJob(job)
267 job_manager.in_background = False
268 self.session.openWithCallback(self.JobViewCB, JobView, job)
270 def burnISO(self, path, scope, configRef):
272 job = Process.DVDisoJob(self.project, path)
273 job_manager.AddJob(job)
274 job_manager.in_background = False
275 self.session.openWithCallback(self.JobViewCB, JobView, job)
277 def JobViewCB(self, in_background):
278 job_manager.in_background = in_background
280 def previewMenu(self):
281 job = Process.DVDJob(self.project, menupreview=True)
282 job_manager.in_background = False
283 job_manager.AddJob(job)
285 def updateTitleList(self):
287 for title in self.project.titles:
288 list.append((title, title.properties.menutitle.getValue(), title.properties.menusubtitle.getValue(), title.DVBchannel, title.formatDVDmenuText("$D.$M.$Y, $T", 0), title.formatDVDmenuText("$l", 0)))
289 self["titles"].list = list
292 self["key_red"].text = _("Remove title")
293 self["key_yellow"].text = _("Title properties")
294 self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
296 self["key_red"].text = ""
297 self["key_yellow"].text = ""
298 self["title_label"].text = _("Please add titles to the compilation")
300 def updateSize(self):
301 size = self.project.size/(1024*1024)
302 MAX_DL = self.project.MAX_DL-100
303 MAX_SL = self.project.MAX_SL-100
304 print "updateSize:", size, "MAX_DL:", MAX_DL, "MAX_SL:", MAX_SL
306 percent = 100 * size / float(MAX_DL)
307 self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
308 self["space_bar_dual"].value = int(percent)
309 self["space_bar_single"].value = 100
310 self["space_label_single"].text = ""
311 self["medium"].text = _("exceeds dual layer medium!")
312 if self.previous_size < MAX_DL:
313 self.session.open(MessageBox,text = _("exceeds dual layer medium!"), type = MessageBox.TYPE_ERROR)
315 percent = 100 * size / float(MAX_DL)
316 self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
317 self["space_bar_dual"].value = int(percent)
318 self["space_bar_single"].value = 100
319 self["space_label_single"].text = ""
320 self["medium"].text = _("required medium type:") + " " + _("DUAL LAYER DVD") + ", %d MB " % (MAX_DL - size) + _("free")
321 if self.previous_size < MAX_SL:
322 self.session.open(MessageBox, text = _("Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!"), timeout = 10, type = MessageBox.TYPE_INFO)
324 percent = 100 * size / float(MAX_SL)
325 self["space_label_single"].text = "%d MB (%.2f%%)" % (size, percent)
326 self["space_bar_single"].value = int(percent)
327 self["space_bar_dual"].value = 0
328 self["space_label_dual"].text = ""
329 self["medium"].text = _("required medium type:") + " " + _("SINGLE LAYER DVD") + ", %d MB " % (MAX_SL - size) + _("free")
330 self.previous_size = size
332 def getCurrentTitle(self):
333 t = self["titles"].getCurrent()
336 def editTitle(self, title = None, editor = True):
337 t = title or self.getCurrentTitle()
339 self.current_edit_title = t
341 self.session.openWithCallback(self.titleEditDone, TitleCutter.TitleCutter, t)
343 self.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, t)
345 def titleEditDone(self, cutlist):
346 t = self.current_edit_title
347 t.titleEditDone(cutlist)
349 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)
351 self.updateTitleList()
353 def resetTitles(self):
355 for title in self.project.titles:
357 title.initDVDmenuText(count)
358 self.updateTitleList()
360 def DVDformatCB(self, answer):
361 t = self.current_edit_title
363 self.project.settings.authormode.setValue("data_ts")
364 self.updateTitleList()
368 def leave(self, close = False):
369 if not len(self["titles"].list) or close:
372 self.session.openWithCallback(self.exitCB, MessageBox,text = _("Your current collection will get lost!") + "\n" + _("Do you really want to exit?"), type = MessageBox.TYPE_YESNO)
374 def exitCB(self, answer):
375 print "exitCB", answer
376 if answer is not None and answer: