Merge branch 'master' of /home/tmbinc/enigma2-git into tmbinc/FixTimingBugs
[vuplus_dvbapp] / lib / python / Plugins / Extensions / DVDBurn / TitleList.py
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
16
17 class TitleList(Screen, HelpableScreen):
18         skin = """
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" />
32                     </widget>
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" />
35                 </screen>"""
36
37         def __init__(self, session, project = None):
38                 Screen.__init__(self, session)
39                 HelpableScreen.__init__(self)
40                 
41                 self["titleactions"] = HelpableActionMap(self, "DVDTitleList",
42                         {
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.burnProject, _("Burn DVD"), _("Burn DVD")),
48                         })
49
50                 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
51                         {
52                                 "contextMenu": (self.showMenu, _("menu")),
53                         })
54
55                 self["actions"] = ActionMap(["OkCancelActions"],
56                         {
57                                 "cancel": self.leave
58                         })
59
60                 self["key_red"] = StaticText(_("Remove title"))
61                 self["key_green"] = StaticText(_("Add title"))
62                 self["key_yellow"] = StaticText(_("Title properties"))
63                 self["key_blue"] = StaticText(_("Settings"))
64
65                 self["title_label"] = StaticText()
66                 self["error_label"] = Label("")
67                 self["space_label"] = StaticText()
68                 self["space_bar"] = Progress()
69
70                 if project is not None:
71                         self.project = project
72                 else:
73                         self.newProject()
74
75                 self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)])
76                 self.updateTitleList()
77
78         def checkBackgroundJobs(self):
79                 for job in job_manager.getPendingJobs():
80                         print "type(job):", type(job)
81                         print "Process.DVDJob:", Process.DVDJob
82                         if type(job) == Process.DVDJob:
83                                 self.backgroundJob = job
84                                 return
85                 self.backgroundJob = None
86
87         def showMenu(self):
88                 menu = []
89                 self.checkBackgroundJobs()
90                 if self.backgroundJob:
91                         j = self.backgroundJob
92                         menu.append(("%s: %s (%d%%)" % (j.getStatustext(), j.name, int(100*j.progress/float(j.end))), self.showBackgroundJob))
93                 if self.project.settings.output.getValue() == "dvd":
94                         menu.append((_("Burn DVD"), self.burnProject))
95                 elif self.project.settings.output.getValue() == "iso":
96                         menu.append((_("Create DVD-ISO"), self.burnProject))
97                 menu.append((_("Burn existing image to DVD"), self.selectImage))
98                 menu.append((_("DVD media toolbox"), self.toolbox))
99                 menu.append((_("Preview menu"), self.previewMenu))
100                 menu.append((_("Collection settings"), self.settings))
101                 menu.append((_("Reset and renumerate title names"), self.resetTitles))
102                 menu.append((_("Edit chapters of current title"), self.editTitle))
103                 menu.append((_("Properties of current title"), self.titleProperties))
104                 menu.append((_("Add a new title"), self.addTitle))
105                 menu.append((_("Remove title"), self.removeCurrentTitle))
106                 menu.append((_("Exit"), self.leave))
107                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
108
109         def menuCallback(self, choice):
110                 if choice:
111                         choice[1]()
112
113         def showBackgroundJob(self):
114                 job_manager.in_background = False
115                 self.session.openWithCallback(self.JobViewCB, JobView, self.backgroundJob)
116                 self.backgroundJob = None
117         
118         def titleProperties(self):
119                 if self.getCurrentTitle():
120                         self.session.openWithCallback(self.updateTitleList, TitleProperties.TitleProperties, self, self.project, self["titles"].getIndex())
121
122         def selectImage(self):
123                 self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings)
124
125         def newProject(self):
126                 self.project = DVDProject.DVDProject()
127                 if self.loadTemplate():
128                         self.project.session = self.session
129                         self.settingsCB()
130
131         def addTitle(self):
132                 from Screens.MovieSelection import MovieSelection
133                 from Components.Button import Button
134                 from Components.ActionMap import HelpableActionMap
135                 class MovieSelectionNoMenu(MovieSelection):
136                         def __init__(self, session):
137                                 MovieSelection.__init__(self, session)
138                                 self.skinName = "MovieSelection"
139                                 self["key_red"] = Button(_("Edit title"))
140                                 self["key_green"] = Button(_("Add"))
141                                 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
142                                 {
143                                         "red": (self.movieSelected, _("Add a new title")),
144                                         "green": (self.insertWithoutEdit, ("insert without cutlist editor"))
145                                 })
146                         def updateTags(self):
147                                 pass
148                         def doContext(self):
149                                 print "context menu forbidden inside DVDBurn to prevent calling multiple instances"
150                         def insertWithoutEdit(self):
151                                 current = self.getCurrent()
152                                 if current is not None:
153                                         current.edit = False
154                                         self.close(current)
155                         def movieSelected(self):
156                                 current = self.getCurrent()
157                                 if current is not None:
158                                         current.edit = True
159                                         self.close(current)
160                 self.session.openWithCallback(self.selectedSource, MovieSelectionNoMenu)
161
162         def selectedSource(self, source):
163                 if source is None:
164                         return None
165                 t = self.project.addService(source)
166                 try:
167                         editor = source.edit
168                 except AttributeError:
169                         editor = True
170                 self.editTitle(t, editor)
171
172         def removeCurrentTitle(self):
173                 title = self.getCurrentTitle()
174                 self.removeTitle(title)
175         
176         def removeTitle(self, title):
177                 if title is not None:
178                         self.project.titles.remove(title)
179                         self.updateTitleList()
180
181         def toolbox(self):
182                 self.session.open(DVDToolbox.DVDToolbox)
183
184         def settings(self):
185                 self.session.openWithCallback(self.settingsCB, ProjectSettings.ProjectSettings, self.project)
186
187         def settingsCB(self, update=True):
188                 if not update:
189                         return
190                 self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
191
192         def loadTemplate(self):
193                 filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVD.ddvdp.xml"
194                 if self.project.load(filename):
195                         self["error_label"].hide()
196                         return True
197                 else:
198                         self["error_label"].text = self.project.error
199                         self["error_label"].show()
200                         return False
201
202         def burnProject(self):
203                 if self.project.settings.authormode.getValue() == "data_ts":
204                         job = Process.DVDdataJob(self.project)
205                         job_manager.AddJob(job)
206                         job_manager.in_background = False
207                         self.session.openWithCallback(self.JobViewCB, JobView, job)
208                 else:
209                         job = Process.DVDJob(self.project)
210                         job_manager.AddJob(job)
211                         job_manager.in_background = False
212                         self.session.openWithCallback(self.JobViewCB, JobView, job)
213
214         def burnISO(self, path, scope):
215                 if path:
216                         job = Process.DVDisoJob(self.project, path)
217                         job_manager.AddJob(job)
218                         job_manager.in_background = False
219                         self.session.openWithCallback(self.JobViewCB, JobView, job)
220
221         def JobViewCB(self, in_background):
222                 job_manager.in_background = in_background
223
224         def previewMenu(self):
225                 job = Process.DVDJob(self.project, menupreview=True)
226                 job_manager.in_background = False
227                 job_manager.AddJob(job)
228                 
229         def updateTitleList(self):
230                 res = [ ]
231                 totalsize = 0
232                 for title in self.project.titles:
233                         a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 5, 500, 25, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue())  ]
234                         res.append(a)
235                         totalsize += title.estimatedDiskspace
236                 self["titles"].list = res
237                 self.updateSize(totalsize)
238
239         def updateSize(self, totalsize):
240                 size = int((totalsize/1024)/1024)
241                 max_SL = 4370
242                 max_DL = 7950
243                 if size > max_DL:
244                         percent = 100 * size / float(max_DL)
245                         self["space_label"].text = "%d MB - " % size + _("exceeds dual layer medium!") + " (%.2f%% " % (100-percent) + _("free") + ")"
246                         self["space_bar"].value = int(percent)
247                 elif size > max_SL:
248                         percent = 100 * size / float(max_DL)
249                         self["space_label"].text = "%d MB  " % size + _("of a DUAL layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
250                         self["space_bar"].value = int(percent)
251                 elif size < max_SL:
252                         percent = 100 * size / float(max_SL)
253                         self["space_label"].text = "%d MB " % size + _("of a SINGLE layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
254                         self["space_bar"].value = int(percent)
255
256         def getCurrentTitle(self):
257                 t = self["titles"].getCurrent()
258                 return t and t[0]
259
260         def editTitle(self, title = None, editor = True):
261                 t = title or self.getCurrentTitle()
262                 if t is not None:
263                         self.current_edit_title = t
264                         if editor:
265                                 self.session.openWithCallback(self.titleEditDone, TitleCutter.TitleCutter, t)
266                         else:
267                                 self.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, t)
268
269         def titleEditDone(self, cutlist):
270                 t = self.current_edit_title
271                 t.initDVDmenuText(self.project,len(self.project.titles))
272                 t.cuesheet = cutlist
273                 t.produceFinalCuesheet()
274                 if t.VideoType != 0:
275                         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)
276                 else:
277                         self.updateTitleList()
278
279         def resetTitles(self):
280                 count = 0
281                 for title in self.project.titles:
282                         count += 1
283                         title.initDVDmenuText(self.project,count)
284                 self.updateTitleList()
285
286         def DVDformatCB(self, answer):
287                 t = self.current_edit_title
288                 if answer == True:
289                         self.project.settings.authormode.setValue("data_ts")
290                         self.updateTitleList()
291                 else:
292                         self.removeTitle(t)
293
294         def leave(self):
295                 self.close()