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 Components.Label import MultiColorLabel
15 from enigma import gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT
16 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
18 class TitleList(Screen, HelpableScreen):
20 <screen name="TitleList" position="center,center" size="560,470" title="DVD Tool" >
21 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
22 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
23 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
24 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
25 <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" />
26 <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" />
27 <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" />
28 <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" />
29 <widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" transparent="1" />
30 <widget source="error_label" render="Label" position="10,48" size="540,296" zPosition="3" font="Regular;20" transparent="1" />
31 <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="546,296" zPosition="3" transparent="1" >
32 <convert type="TemplatedMultiContent">
34 MultiContentEntryText(pos = (0, 0), size = (360, 20), font = 0, flags = RT_HALIGN_LEFT, text = 1), # index 1 Title,
35 MultiContentEntryText(pos = (0, 20), size = (360, 17), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 description,
36 MultiContentEntryText(pos = (366, 6), size = (152, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 3), # index 3 channel,
37 MultiContentEntryText(pos = (366, 20), size = (102, 17), font = 1, flags = RT_HALIGN_RIGHT, text = 4), # index 4 begin time,
38 MultiContentEntryText(pos = (470, 20), size = (48, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 5), # index 5 duration,
40 "fonts": [gFont("Regular", 20), gFont("Regular", 14)],
45 <ePixmap pixmap="skin_default/div-h.png" position="0,390" zPosition="10" size="560,2" />
46 <ePixmap pixmap="skin_default/buttons/key_menu.png" position="10,394" size="35,25" alphatest="on" />
47 <widget source="hint" render="Label" position="50,396" size="540,22" font="Regular;18" halign="left" />
48 <widget name="medium_label" position="10,420" size="540,22" font="Regular;18" halign="left" foregroundColors="#FFFFFF,#FFFF00,#FF0000" />
49 <widget source="space_bar_single" render="Progress" position="10,446" size="270,24" borderWidth="1" zPosition="2" backgroundColor="#254f7497" />
50 <widget source="space_label_single" render="Label" position="10,449" size="270,22" zPosition="3" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
51 <widget source="space_bar_dual" render="Progress" position="10,446" size="540,24" borderWidth="1" backgroundColor="#254f7497" />
52 <widget source="space_label_dual" render="Label" position="10,449" size="540,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
56 def __init__(self, session, project = None):
57 Screen.__init__(self, session)
58 HelpableScreen.__init__(self)
60 self["titleactions"] = HelpableActionMap(self, "DVDTitleList",
62 "addTitle": (self.addTitle, _("Add a new title"), _("Add title")),
63 "titleProperties": (self.titleProperties, _("Properties of current title"), _("Title properties")),
64 "removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")),
65 "settings": (self.settings, _("Collection settings"), _("Settings")),
66 "burnProject": (self.askBurnProject, _("Burn DVD"), _("Burn DVD")),
69 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
71 "contextMenu": (self.showMenu, _("menu")),
74 self["actions"] = ActionMap(["OkCancelActions"],
79 self["key_red"] = StaticText()
80 self["key_green"] = StaticText(_("Add title"))
81 self["key_yellow"] = StaticText()
82 self["key_blue"] = StaticText(_("Settings"))
84 self["title_label"] = StaticText()
85 self["error_label"] = StaticText()
86 self["space_label_single"] = StaticText()
87 self["space_label_dual"] = StaticText()
88 self["hint"] = StaticText(_("Advanced Options"))
89 self["medium_label"] = MultiColorLabel()
90 self["space_bar_single"] = Progress()
91 self["space_bar_dual"] = Progress()
93 self["titles"] = List([])
94 self.previous_size = 0
95 if project is not None:
96 self.project = project
99 self.onLayoutFinish.append(self.layoutFinished)
101 def layoutFinished(self):
102 self.setTitle(_("DVD Titlelist"))
104 def checkBackgroundJobs(self):
105 for job in job_manager.getPendingJobs():
106 print "type(job):", type(job)
107 print "Process.DVDJob:", Process.DVDJob
108 if type(job) == Process.DVDJob:
109 self.backgroundJob = job
111 self.backgroundJob = None
115 self.checkBackgroundJobs()
116 if self.backgroundJob:
117 j = self.backgroundJob
118 menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
119 menu.append((_("DVD media toolbox"), self.toolbox))
120 if self.project.settings.output.getValue() == "dvd":
121 if len(self["titles"].list):
122 menu.append((_("Burn DVD"), self.burnProject))
123 elif self.project.settings.output.getValue() == "iso":
124 menu.append((_("Create DVD-ISO"), self.burnProject))
125 menu.append((_("Burn existing image to DVD"), self.selectImage))
126 if len(self["titles"].list):
127 menu.append((_("Preview menu"), self.previewMenu))
128 menu.append((_("Edit chapters of current title"), self.editTitle))
129 menu.append((_("Reset and renumerate title names"), self.resetTitles))
130 menu.append((_("Exit"), self.leave))
131 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
133 def menuCallback(self, choice):
137 def showBackgroundJob(self):
138 job_manager.in_background = False
139 self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob)
140 self.backgroundJob = None
142 def titleProperties(self):
143 if self.getCurrentTitle():
144 self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex())
146 def selectImage(self):
147 self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings)
149 def newProject(self):
150 self.project = DVDProject.DVDProject()
151 if self.loadTemplate():
152 self.project.session = self.session
156 from Screens.MovieSelection import MovieSelection
157 from Components.ActionMap import HelpableActionMap
158 class DVDMovieSelection(MovieSelection):
159 skin = """<screen name="DVDMovieSelection" position="center,center" size="560,445" title="Select a movie">
160 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
161 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
162 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
163 <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" />
164 <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" />
165 <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" />
166 <widget name="waitingtext" position="0,45" size="560,395" zPosition="4" font="Regular;22" halign="center" valign="center" />
167 <widget name="list" position="5,40" size="550,375" zPosition="2" scrollbarMode="showOnDemand" />
168 <widget name="DescriptionBorder" pixmap="skin_default/border_eventinfo.png" position="0,316" zPosition="1" size="560,103" transparent="1" alphatest="on" />
169 <widget source="Service" render="Label" position="5,318" zPosition="1" size="480,35" font="Regular;17" foregroundColor="#cccccc">
170 <convert type="MovieInfo">ShortDescription</convert>
172 <widget source="Service" render="Label" position="495,318" zPosition="1" size="60,22" font="Regular;17" halign="right">
173 <convert type="ServiceTime">Duration</convert>
174 <convert type="ClockToText">AsLength</convert>
176 <widget source="Service" render="Label" position="380,337" zPosition="2" size="175,22" font="Regular;17" halign="right">
177 <convert type="MovieInfo">RecordServiceName</convert>
179 <widget source="Service" render="Label" position="5,357" zPosition="1" size="550,58" font="Regular;19">
180 <convert type="EventName">ExtendedDescription</convert>
182 <widget name="freeDiskSpace" position="10,425" size="540,20" font="Regular;19" valign="center" halign="right" />
184 def __init__(self, session):
185 MovieSelection.__init__(self, session)
186 self["key_red"] = StaticText(_("Close"))
187 self["key_green"] = StaticText(_("Add"))
188 self["key_yellow"] = StaticText(_("Edit title"))
189 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
191 "red": (self.close, _("Close title selection")),
192 "green": (self.insertWithoutEdit, ("insert without cutlist editor")),
193 "yellow": (self.movieSelected, _("Add a new title"))
195 def updateTags(self):
198 print "context menu forbidden inside DVDBurn to prevent calling multiple instances"
199 def insertWithoutEdit(self):
200 current = self.getCurrent()
201 if current is not None:
204 def movieSelected(self):
205 current = self.getCurrent()
206 if current is not None:
209 self.session.openWithCallback(self.selectedSource, DVDMovieSelection)
211 def selectedSource(self, source = None):
214 if not source.getPath().endswith(".ts"):
215 self.session.open(MessageBox,text = _("You can only burn Dreambox recordings!"), type = MessageBox.TYPE_ERROR)
217 t = self.project.addService(source)
220 except AttributeError:
222 self.editTitle(t, editor)
224 def removeCurrentTitle(self):
225 title = self.getCurrentTitle()
226 self.removeTitle(title)
228 def removeTitle(self, title):
229 if title is not None:
230 self.project.titles.remove(title)
231 self.updateTitleList()
234 self.session.open(DVDToolbox.DVDToolbox)
237 self.session.openWithCallback(self.settingsCB, ProjectSettings.ProjectSettings, self.project)
239 def settingsCB(self, update=True):
242 self.updateTitleList()
244 def loadTemplate(self):
245 filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
246 if self.project.load(filename):
247 self["error_label"].setText("")
250 self["error_label"].setText(self.project.error)
253 def askBurnProject(self):
254 if len(self["titles"].list):
255 self.session.openWithCallback(self.burnProject,MessageBox,text = _("Do you want to burn this collection to DVD medium?"), type = MessageBox.TYPE_YESNO)
257 def burnProject(self, answer=True):
260 if self.project.settings.authormode.getValue() == "data_ts":
261 job = Process.DVDdataJob(self.project)
262 job_manager.AddJob(job)
263 job_manager.in_background = False
264 self.session.openWithCallback(self.JobViewCB, JobView, job)
266 job = Process.DVDJob(self.project)
267 job_manager.AddJob(job)
268 job_manager.in_background = False
269 self.session.openWithCallback(self.JobViewCB, JobView, job)
271 def burnISO(self, path, scope, configRef):
273 job = Process.DVDisoJob(self.project, path)
274 job_manager.AddJob(job)
275 job_manager.in_background = False
276 self.session.openWithCallback(self.JobViewCB, JobView, job)
278 def JobViewCB(self, in_background):
279 job_manager.in_background = in_background
281 def previewMenu(self):
282 job = Process.DVDJob(self.project, menupreview=True)
283 job_manager.in_background = False
284 job_manager.AddJob(job)
286 def updateTitleList(self):
288 for title in self.project.titles:
289 list.append((title, title.properties.menutitle.getValue(), title.properties.menusubtitle.getValue(), title.DVBchannel, title.formatDVDmenuText("$D.$M.$Y, $T", 0), title.formatDVDmenuText("$l", 0)))
290 self["titles"].list = list
293 self["key_red"].text = _("Remove title")
294 self["key_yellow"].text = _("Title properties")
295 self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
297 self["key_red"].text = ""
298 self["key_yellow"].text = ""
299 self["title_label"].text = _("Please add titles to the compilation.")
301 def updateSize(self):
302 size = self.project.size/(1024*1024)
303 MAX_DL = self.project.MAX_DL-100
304 MAX_SL = self.project.MAX_SL-100
305 print "updateSize:", size, "MAX_DL:", MAX_DL, "MAX_SL:", MAX_SL
307 percent = 100 * size / float(MAX_DL)
308 self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
309 self["space_bar_dual"].value = int(percent)
310 self["space_bar_single"].value = 100
311 self["space_label_single"].text = ""
312 self["medium_label"].setText(_("Exceeds dual layer medium!"))
313 self["medium_label"].setForegroundColorNum(2)
314 if self.previous_size < MAX_DL:
315 self.session.open(MessageBox,text = _("Exceeds dual layer medium!"), type = MessageBox.TYPE_ERROR)
317 percent = 100 * size / float(MAX_DL)
318 self["space_label_dual"].text = "%d MB (%.2f%%)" % (size, percent)
319 self["space_bar_dual"].value = int(percent)
320 self["space_bar_single"].value = 100
321 self["space_label_single"].text = ""
322 self["medium_label"].setText(_("Required medium type:") + " " + _("DUAL LAYER DVD") + ", %d MB " % (MAX_DL - size) + _("free"))
323 self["medium_label"].setForegroundColorNum(1)
324 if self.previous_size < MAX_SL:
325 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)
327 percent = 100 * size / float(MAX_SL)
328 self["space_label_single"].text = "%d MB (%.2f%%)" % (size, percent)
329 self["space_bar_single"].value = int(percent)
330 self["space_bar_dual"].value = 0
331 self["space_label_dual"].text = ""
332 self["medium_label"].setText(_("Required medium type:") + " " + _("SINGLE LAYER DVD") + ", %d MB " % (MAX_SL - size) + _("free"))
333 self["medium_label"].setForegroundColorNum(0)
334 self.previous_size = size
336 def getCurrentTitle(self):
337 t = self["titles"].getCurrent()
340 def editTitle(self, title = None, editor = True):
341 t = title or self.getCurrentTitle()
343 self.current_edit_title = t
345 self.session.openWithCallback(self.titleEditDone, TitleCutter.TitleCutter, t)
347 self.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, t)
349 def titleEditDone(self, cutlist):
350 t = self.current_edit_title
351 t.titleEditDone(cutlist)
353 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)
355 self.updateTitleList()
357 def resetTitles(self):
359 for title in self.project.titles:
361 title.initDVDmenuText(count)
362 self.updateTitleList()
364 def DVDformatCB(self, answer):
365 t = self.current_edit_title
367 self.project.settings.authormode.setValue("data_ts")
368 self.updateTitleList()
372 def leave(self, close = False):
373 if not len(self["titles"].list) or close:
376 self.session.openWithCallback(self.exitCB, MessageBox,text = _("Your current collection will get lost!") + "\n" + _("Do you really want to exit?"), type = MessageBox.TYPE_YESNO)
378 def exitCB(self, answer):
379 print "exitCB", answer
380 if answer is not None and answer: